Salome HOME
PR: first version from Antony GEAY, with directory restructuration
authorprascle <prascle>
Tue, 12 Sep 2006 18:57:02 +0000 (18:57 +0000)
committerprascle <prascle>
Tue, 12 Sep 2006 18:57:02 +0000 (18:57 +0000)
99 files changed:
AUTHORS [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
adm/unix/config_files/ac_pkg_swig.m4 [new file with mode: 0755]
adm/unix/config_files/ac_prog_esope.m4 [new file with mode: 0755]
adm/unix/config_files/ac_python_devel.m4 [new file with mode: 0755]
adm/unix/config_files/check_cppunit.m4 [new file with mode: 0755]
adm/unix/config_files/check_qt.m4 [new file with mode: 0755]
adm/unix/config_files/production.m4 [new file with mode: 0755]
adm/unix/config_files/thread.m4 [new file with mode: 0755]
adm/unix/make_begin.am [new file with mode: 0755]
adm/unix/make_end.am [new file with mode: 0755]
build_configure [new file with mode: 0755]
configure.in.base [new file with mode: 0644]
doc/opml.dtd [new file with mode: 0644]
doc/opml.xslt [new file with mode: 0644]
doc/programingRules.sxw [new file with mode: 0644]
mkinstalldirs [new file with mode: 0755]
py-compile [new file with mode: 0755]
rfind [new file with mode: 0755]
root_clean [new file with mode: 0755]
src/Makefile.am [new file with mode: 0644]
src/bases/Exception.cxx [new file with mode: 0644]
src/bases/Exception.hxx [new file with mode: 0644]
src/bases/Makefile.am [new file with mode: 0644]
src/bases/Mutex.cxx [new file with mode: 0644]
src/bases/Mutex.hxx [new file with mode: 0644]
src/bases/MutexPT.cxx [new file with mode: 0644]
src/bases/MutexPT.hxx [new file with mode: 0644]
src/bases/Semaphore.cxx [new file with mode: 0644]
src/bases/Semaphore.hxx [new file with mode: 0644]
src/bases/SemaphorePT.cxx [new file with mode: 0644]
src/bases/SemaphorePT.hxx [new file with mode: 0644]
src/bases/Test/Makefile.am [new file with mode: 0644]
src/bases/Test/test1.cxx [new file with mode: 0644]
src/bases/Thread.cxx [new file with mode: 0644]
src/bases/Thread.hxx [new file with mode: 0644]
src/bases/ThreadPT.cxx [new file with mode: 0644]
src/bases/ThreadPT.hxx [new file with mode: 0644]
src/bases/define.hxx [new file with mode: 0644]
src/basicData/ContentOfDataFlow.cxx [new file with mode: 0644]
src/basicData/ContentOfDataFlow.hxx [new file with mode: 0644]
src/basicData/ConversionException.cxx [new file with mode: 0644]
src/basicData/ConversionException.hxx [new file with mode: 0644]
src/basicData/Data.cxx [new file with mode: 0644]
src/basicData/Data.hxx [new file with mode: 0644]
src/basicData/Makefile.am [new file with mode: 0644]
src/basicData/Test/Makefile.am [new file with mode: 0644]
src/basicData/Test/testData.cxx [new file with mode: 0644]
src/basicData/TypeCheckerDataFlow.cxx [new file with mode: 0644]
src/basicData/TypeCheckerDataFlow.hxx [new file with mode: 0644]
src/basicData/TypeCheckerDataStream.cxx [new file with mode: 0644]
src/basicData/TypeCheckerDataStream.hxx [new file with mode: 0644]
src/engine/Bloc.cxx [new file with mode: 0644]
src/engine/Bloc.hxx [new file with mode: 0644]
src/engine/ComposedNode.cxx [new file with mode: 0644]
src/engine/ComposedNode.hxx [new file with mode: 0644]
src/engine/DataFlowPort.cxx [new file with mode: 0644]
src/engine/DataFlowPort.hxx [new file with mode: 0644]
src/engine/DataStreamPort.cxx [new file with mode: 0644]
src/engine/DataStreamPort.hxx [new file with mode: 0644]
src/engine/ElementaryNode.cxx [new file with mode: 0644]
src/engine/ElementaryNode.hxx [new file with mode: 0644]
src/engine/Executor.cxx [new file with mode: 0644]
src/engine/Executor.hxx [new file with mode: 0644]
src/engine/InGate.cxx [new file with mode: 0644]
src/engine/InGate.hxx [new file with mode: 0644]
src/engine/InPort.cxx [new file with mode: 0644]
src/engine/InPort.hxx [new file with mode: 0644]
src/engine/InputDataStreamPort.cxx [new file with mode: 0644]
src/engine/InputDataStreamPort.hxx [new file with mode: 0644]
src/engine/InputPort.cxx [new file with mode: 0644]
src/engine/InputPort.hxx [new file with mode: 0644]
src/engine/Loop.cxx [new file with mode: 0644]
src/engine/Loop.hxx [new file with mode: 0644]
src/engine/Makefile.am [new file with mode: 0644]
src/engine/Node.cxx [new file with mode: 0644]
src/engine/Node.hxx [new file with mode: 0644]
src/engine/OutGate.cxx [new file with mode: 0644]
src/engine/OutGate.hxx [new file with mode: 0644]
src/engine/OutPort.cxx [new file with mode: 0644]
src/engine/OutPort.hxx [new file with mode: 0644]
src/engine/OutputDataStreamPort.cxx [new file with mode: 0644]
src/engine/OutputDataStreamPort.hxx [new file with mode: 0644]
src/engine/OutputPort.cxx [new file with mode: 0644]
src/engine/OutputPort.hxx [new file with mode: 0644]
src/engine/Port.cxx [new file with mode: 0644]
src/engine/Port.hxx [new file with mode: 0644]
src/engine/Scheduler.hxx [new file with mode: 0644]
src/engine/Switch.cxx [new file with mode: 0644]
src/engine/Switch.hxx [new file with mode: 0644]
src/engine/Task.hxx [new file with mode: 0644]
src/engine/Test/Makefile.am [new file with mode: 0644]
src/engine/Test/ToyNode.cxx [new file with mode: 0644]
src/engine/Test/ToyNode.hxx [new file with mode: 0644]
src/engine/Test/testBloc.cxx [new file with mode: 0644]
src/engine/Test/testPorts.cxx [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..2cad62a
--- /dev/null
@@ -0,0 +1,2 @@
+
+SUBDIRS = src
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..d981c48
--- /dev/null
+++ b/README
@@ -0,0 +1,4 @@
+IMPROVEMENTS :
+
+- OutGate::isAlreadyInList : use std::find
+- Bloc::checkNoCyclePassingThrough : first loop iter1=currentNodesToTest.erase(iter1) as last argument
diff --git a/adm/unix/config_files/ac_pkg_swig.m4 b/adm/unix/config_files/ac_pkg_swig.m4
new file mode 100755 (executable)
index 0000000..6810ca2
--- /dev/null
@@ -0,0 +1,150 @@
+dnl @synopsis AC_PROG_SWIG([major.minor.micro])
+dnl
+dnl This macro searches for a SWIG installation on your system. If found you
+dnl should) SWIG via $(SWIG).  You can use the optional first argument to check
+dnl if the version of the available SWIG is greater than or equal to the
+dnl value of the argument.  It should have the format: N[.N[.N]] (N is a
+dnl number between 0 and 999.  Only the first N is mandatory.)
+dnl
+dnl If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks that the
+dnl swig package is this version number or higher.
+dnl
+dnl In configure.in, use as:
+dnl
+dnl            AC_PROG_SWIG(1.3.17)
+dnl            SWIG_ENABLE_CXX
+dnl            SWIG_MULTI_MODULE_SUPPORT
+dnl            SWIG_PYTHON
+dnl
+dnl @authors Sebastian Huber <address@hidden>, Alan W. Irwin
+dnl <address@hidden>, Rafael Laboissiere <address@hidden> and
+dnl Andrew Collier <address@hidden>.
+dnl
+dnl
+AC_DEFUN([AC_PROG_SWIG],[
+       AC_PATH_PROG([SWIG],[swig])
+       if test -z "$SWIG" ; then
+               AC_MSG_WARN([cannot find 'swig' program. You should look at http://www.swig.org])
+               SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false'
+       elif test -n "$1" ; then
+               AC_MSG_CHECKING([for SWIG version])
+               [swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`]
+               AC_MSG_RESULT([$swig_version])
+               if test -n "$swig_version" ; then
+                       # Calculate the required version number components
+                       [required=$1]
+                       [required_major=`echo $required | sed 's/[^0-9].*//'`]
+                       if test -z "$required_major" ; then
+                               [required_major=0]
+                       fi
+                       [required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
+                       [required_minor=`echo $required | sed 's/[^0-9].*//'`]
+                       if test -z "$required_minor" ; then
+                               [required_minor=0]
+                       fi
+                       [required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
+                       [required_patch=`echo $required | sed 's/[^0-9].*//'`]
+                       if test -z "$required_patch" ; then
+                               [required_patch=0]
+                       fi
+                       # Calculate the available version number components
+                       [available=$swig_version]
+                       [available_major=`echo $available | sed 's/[^0-9].*//'`]
+                       if test -z "$available_major" ; then
+                               [available_major=0]
+                       fi
+                       [available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
+                       [available_minor=`echo $available | sed 's/[^0-9].*//'`]
+                       if test -z "$available_minor" ; then
+                               [available_minor=0]
+                       fi
+                       [available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
+                       [available_patch=`echo $available | sed 's/[^0-9].*//'`]
+                       if test -z "$available_patch" ; then
+                               [available_patch=0]
+                       fi
+                       if test $available_major -ne $required_major \
+                               -o $available_minor -ne $required_minor \
+                               -o $available_patch -lt $required_patch ; then
+                               AC_MSG_WARN([SWIG version >= $1 is required.  You have $swig_version.  You should look at http://www.swig.org])
+                               SWIG='echo "Error: SWIG version >= $1 is required.  You have '"$swig_version"'.  You should look at http://www.swig.org" ; false'
+                       else
+                               AC_MSG_NOTICE([SWIG executable is '$SWIG'])
+                               SWIG_LIB=`$SWIG -swiglib`
+                               AC_MSG_NOTICE([SWIG runtime library directory is '$SWIG_LIB'])
+                       fi
+               else
+                       AC_MSG_WARN([cannot determine SWIG version])
+                       SWIG='echo "Error: Cannot determine SWIG version.  You should look at http://www.swig.org" ; false'
+               fi
+       fi
+       AC_SUBST([SWIG_LIB])
+])
+
+# SWIG_ENABLE_CXX()
+#
+# Enable SWIG C++ support.  This affects all invocations of $(SWIG).
+AC_DEFUN([SWIG_ENABLE_CXX],[
+       AC_REQUIRE([AC_PROG_SWIG])
+       AC_REQUIRE([AC_PROG_CXX])
+       SWIG="$SWIG -c++"
+])
+
+# SWIG_MULTI_MODULE_SUPPORT()
+#
+# Enable support for multiple modules.  This effects all invocations
+# of $(SWIG).  You have to link all generated modules against the
+# appropriate SWIG runtime library.  If you want to build Python
+# modules for example, use the SWIG_PYTHON() macro and link the
+# modules against $(SWIG_PYTHON_LIBS).
+AC_DEFUN([SWIG_MULTI_MODULE_SUPPORT],[
+       AC_REQUIRE([AC_PROG_SWIG])
+       SWIG="$SWIG -c"
+])
+
+# SWIG_PYTHON([use-shadow-classes = {no, yes}])
+#
+# Checks for Python and provides the $(SWIG_PYTHON_CPPFLAGS),
+# $(SWIG_PYTHON_LIBS) and $(SWIG_PYTHON_OPT) output variables.
+# $(SWIG_PYTHON_OPT) contains all necessary SWIG options to generate
+# code for Python.  Shadow classes are enabled unless the value of the
+# optional first argument is exactly 'no'.  If you need multi module
+# support (provided by the SWIG_MULTI_MODULE_SUPPORT() macro) use
+# $(SWIG_PYTHON_LIBS) to link against the appropriate library.  It
+# contains the SWIG Python runtime library that is needed by the type
+# check system for example.
+AC_DEFUN([SWIG_PYTHON],[
+       AC_REQUIRE([AC_PROG_SWIG])
+       AC_REQUIRE([AC_PYTHON_DEVEL])
+       test "x$1" != "xno" || swig_shadow=" -noproxy"
+       AC_SUBST([SWIG_PYTHON_OPT],[-python$swig_shadow])
+       AC_SUBST([SWIG_PYTHON_CPPFLAGS],[$PYTHON_CPPFLAGS])
+       AC_SUBST([SWIG_PYTHON_LIBS],["-L$SWIG_LIB -lswigpy"])
+])
+
+
+dnl @synopsis AC_LIB_WAD
+dnl
+dnl This macro searches for installed WAD library.
+dnl
+AC_DEFUN([AC_LIB_WAD],
+[
+       AC_REQUIRE([AC_PYTHON_DEVEL])
+       AC_ARG_ENABLE(wad,
+       AC_HELP_STRING([--enable-wad], [enable wad module]),
+       [
+               case "${enableval}" in
+                       no)     ;;
+                       *)      if test "x${enableval}" = xyes;
+                               then
+                                       check_wad="yes"
+                               fi ;;
+               esac
+       ], [])
+
+       if test -n "$check_wad";
+       then
+               AC_CHECK_LIB(wadpy, _init, [WADPY=-lwadpy], [], $PYTHON_LDFLAGS $PYTHON_EXTRA_LIBS)
+               AC_SUBST(WADPY)
+       fi
+])
diff --git a/adm/unix/config_files/ac_prog_esope.m4 b/adm/unix/config_files/ac_prog_esope.m4
new file mode 100755 (executable)
index 0000000..4b9e42c
--- /dev/null
@@ -0,0 +1,50 @@
+# Check availability of Med binary distribution
+#
+# Author : Anthony GEAY (CEA, 2005)
+#
+
+AC_DEFUN([AC_PROG_ESOPE],[
+CHECK_MED
+
+AC_CHECKING(for Esope)
+
+srcdirea=`( cd $srcdir && pwd )`
+
+esope_ok=yes
+
+AC_ARG_WITH(esope,
+    [  --with-esope=EXEC esope executable ],
+    [ESOPE="$withval"
+      AC_MSG_RESULT("select $withval as esope executable")
+    ], [
+      AC_PATH_PROG(ESOPE, esopv10_0)
+    ])
+if test "x$ESOPE" = "x" ;
+then
+     ESOPE=$srcdirea/bin/esopv10_0
+     AC_MSG_RESULT(use esope furnished in sources at location : $ESOPE)
+fi
+AC_SUBST(ESOPE)
+
+dnl --- To improve UNIX 32
+EFLAGS="ESOPE=2000000,NORME=TRADUCTEUR,FORT=UNIX32"
+AC_SUBST(EFLAGS)
+
+AC_PATH_PROG(CPPFORESOPE, cpp)
+if test "x$CPPFORESOPE" = "x" ;
+then
+    esope_ok=no
+    AC_MSG_RESULT(cpp not found in PATH !!! - used by esope to generate Fortran files)
+fi
+AC_SUBST(CPPFORESOPE)
+
+CPPFORESOPEFLAGS="-Dunix32 -Dlinux ${MED_INCLUDES}"
+AC_SUBST(CPPFORESOPEFLAGS)
+dnl --- Segment directory
+SEGMENTS_DIR="-I"$srcdirea/bin/SEGMENTS
+AC_SUBST(SEGMENTS_DIR)
+
+AC_MSG_RESULT(for Esope: $esope_ok)
+])dnl
diff --git a/adm/unix/config_files/ac_python_devel.m4 b/adm/unix/config_files/ac_python_devel.m4
new file mode 100755 (executable)
index 0000000..e0ac20c
--- /dev/null
@@ -0,0 +1,60 @@
+dnl @synopsis AC_PYTHON_DEVEL()
+dnl
+dnl Checks for Python and tries to get the include path to 'Python.h'.
+dnl It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) output variable.
+dnl
+dnl @authors Sebastian Huber <address@hidden>, Alan W. Irwin
+dnl <address@hidden>, Rafael Laboissiere <address@hidden> and
+dnl Andrew Collier <address@hidden>.
+dnl
+dnl
+AC_DEFUN([AC_PYTHON_DEVEL],[
+       #
+       # should allow for checking of python version here...
+       #
+       AC_REQUIRE([AM_PATH_PYTHON])
+
+       # Check for Python include path
+       AC_MSG_CHECKING([for Python include path])
+       python_path=`echo $PYTHON | sed "s,/bin.*$,,"`
+       for i in "$python_path/include/python$PYTHON_VERSION/" "$python_path/include/python/" "$python_path/" ; do
+               python_path=`find $i -type f -name Python.h -print | sed "1q"`
+               if test -n "$python_path" ; then
+                       break
+               fi
+       done
+       python_path=`echo $python_path | sed "s,/Python.h$,,"`
+       AC_MSG_RESULT([$python_path])
+       if test -z "$python_path" ; then
+               AC_MSG_ERROR([cannot find Python include path])
+       fi
+       AC_SUBST([PYTHON_CPPFLAGS],[-I$python_path])
+
+       # Check for Python library path
+       AC_MSG_CHECKING([for Python library path])
+       python_path=`echo $PYTHON | sed "s,/bin.*$,,"`
+       for i in "$python_path/lib/python$PYTHON_VERSION/config/" "$python_path/lib/python$PYTHON_VERSION/" "$python_path/lib/python/config/" "$python_path/lib/python/" "$python_path/" ; do
+               python_path=`find $i -type f -name libpython$PYTHON_VERSION.* -print | sed "1q"`
+               if test -n "$python_path" ; then
+                       break
+               fi
+       done
+       python_path=`echo $python_path | sed "s,/libpython.*$,,"`
+       AC_MSG_RESULT([$python_path])
+       if test -z "$python_path" ; then
+               AC_MSG_ERROR([cannot find Python library path])
+       fi
+       AC_SUBST([PYTHON_LDFLAGS],["-L$python_path -lpython$PYTHON_VERSION"])
+       #
+       python_site=`echo $python_path | sed "s/config/site-packages/"`
+       AC_SUBST([PYTHON_SITE_PKG],[$python_site])
+       #
+       # libraries which must be linked in when embedding
+       #
+       AC_MSG_CHECKING(python extra libraries)
+       PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
+                conf = distutils.sysconfig.get_config_var; \
+                print conf('LOCALMODLIBS')+' '+conf('LIBS')"
+       AC_MSG_RESULT($PYTHON_EXTRA_LIBS)`
+       AC_SUBST(PYTHON_EXTRA_LIBS)
+])
diff --git a/adm/unix/config_files/check_cppunit.m4 b/adm/unix/config_files/check_cppunit.m4
new file mode 100755 (executable)
index 0000000..78ec1b8
--- /dev/null
@@ -0,0 +1,64 @@
+# Check presence of "CPPUNIT" product presence
+#
+# Author : Anthony GEAY (CEA, 2006)
+#
+
+AC_DEFUN([CHECK_CPPUNIT],[
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_CPP])dnl
+
+AC_CHECKING(for CPPUNIT)
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+cppunit_ok=no
+AC_ARG_WITH(cppunit,
+    [AC_HELP_STRING([--with-cppunit=DIR],[cppunit directory path where cppunit is installed])],
+    [CPPUNITINSTDIR="$withval"
+      AC_MSG_RESULT("select $withval as path to cppunit")
+    ])
+
+AC_SUBST(CPPUNIT_INCLUDES)
+AC_SUBST(CPPUNIT_LIBS)
+AC_SUBST(CPPUNIT_LIBS_DIR)
+AC_SUBST(CPPUNITINSTDIR)
+
+CPPUNIT_INCLUDES=""
+CPPUNIT_LIBS=""
+
+LOCAL_INCLUDES=""
+LOCAL_LIBS=""
+
+if test "x$CPPUNITINSTDIR" = "x"  
+then
+   LOCAL_INCLUDES=""
+   LOCAL_LIBS_DIR=""
+else
+   LOCAL_INCLUDES="-I$CPPUNITINSTDIR/include"
+   LOCAL_LIBS_DIR="$CPPUNITINSTDIR/lib"
+fi
+
+dnl cppunit headers
+
+CPPFLAGS_old="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $LOCAL_INCLUDES"
+AC_LANG_CPLUSPLUS
+AC_CHECK_HEADER(cppunit/ui/text/TestRunner.h,cppunit_ok=yes ,cppunit_ok=no)
+CPPFLAGS="$CPPFLAGS_old"
+
+if test "x$cppunit_ok" = "xyes"
+then
+  if test "x$LOCAL_INCLUDES" = "x"
+  then
+     CPPUNIT_INCLUDES=""
+     CPPUNIT_LIBS="-lcppunit"
+     CPPUNIT_LIBS_DIR=""
+  else
+     CPPUNIT_INCLUDES="$LOCAL_INCLUDES"
+     CPPUNIT_LIBS="-L$LOCAL_LIBS_DIR -lcppunit"
+     CPPUNIT_LIBS_DIR="$LOCAL_LIBS_DIR"
+  fi
+fi
+AC_LANG_RESTORE
+AC_MSG_RESULT(for cppunit: $cppunit_ok)
+
+])dnl
diff --git a/adm/unix/config_files/check_qt.m4 b/adm/unix/config_files/check_qt.m4
new file mode 100755 (executable)
index 0000000..e8df7ee
--- /dev/null
@@ -0,0 +1,154 @@
+dnl  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+dnl 
+dnl  This library is free software; you can redistribute it and/or 
+dnl  modify it under the terms of the GNU Lesser General Public 
+dnl  License as published by the Free Software Foundation; either 
+dnl  version 2.1 of the License. 
+dnl 
+dnl  This library is distributed in the hope that it will be useful, 
+dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+dnl  Lesser General Public License for more details. 
+dnl 
+dnl  You should have received a copy of the GNU Lesser General Public 
+dnl  License along with this library; if not, write to the Free Software 
+dnl  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+dnl 
+dnl  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+dnl
+dnl
+dnl
+
+AC_DEFUN([CHECK_QT],[
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_CXX])dnl
+AC_REQUIRE([AC_PROG_CPP])dnl
+AC_REQUIRE([AC_PROG_CXXCPP])dnl
+
+AC_CHECKING(for QT)
+qt_ok=yes
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+
+if test "x$QTDIR" = "x"
+then
+   AC_MSG_RESULT(please define QTDIR variable)
+   qt_ok=no
+fi
+
+if  test "x$qt_ok" = "xyes"
+then
+  if test -f ${QTDIR}/bin/moc
+  then
+    MOC=${QTDIR}/bin/moc
+  else
+    AC_PATH_PROG(MOC, moc)
+  fi
+  if test "x$MOC" = "x"
+  then
+    qt_ok=no
+    AC_MSG_RESULT(moc qt-compiler not in PATH variable)
+  else
+    qt_ok=yes
+    AC_MSG_RESULT(moc found)
+  fi
+fi
+
+if  test "x$qt_ok" = "xyes"
+then
+  if test -f ${QTDIR}/bin/uic
+  then
+    UIC=${QTDIR}/bin/uic
+  else
+    AC_PATH_PROG(UIC, uic)
+  fi
+  if test "x$UIC" = "x"
+  then
+    qt_ok=no
+    AC_MSG_RESULT(uic qt-interface compiler not in PATH variable)
+  else
+    qt_ok=yes
+    AC_MSG_RESULT(uic found)
+  fi
+fi
+
+AC_SUBST(QTDIR)
+QT_ROOT=$QTDIR
+
+if  test "x$qt_ok" = "xyes"
+then
+  AC_MSG_CHECKING(include of qt headers)
+
+  CPPFLAGS_old=$CPPFLAGS
+  CPPFLAGS="$CPPFLAGS -I$QTDIR/include"
+
+  AC_LANG_CPLUSPLUS
+  AC_CHECK_HEADER(qaction.h,qt_ok=yes ,qt_ok=no)
+
+  CPPFLAGS=$CPPFLAGS_old
+
+  if  test "x$qt_ok" = "xno"
+  then
+    AC_MSG_RESULT(qt headers not found, or too old qt version, in $QTDIR/include)
+    AC_MSG_RESULT(QTDIR environment variable may be wrong)
+  else
+    AC_MSG_RESULT(yes)
+       QT_INCLUDES="-I${QT_ROOT}/include -DQT_THREAD_SUPPORT"
+    QT_MT_INCLUDES="-I${QT_ROOT}/include -DQT_THREAD_SUPPORT"
+  fi
+fi
+
+if  test "x$qt_ok" = "xyes"
+then
+  AC_MSG_CHECKING(linking qt library)
+  LIBS_old=$LIBS
+  LIBS="$LIBS -L$QTDIR/lib -lqt-mt $OGL_LIBS"
+
+  CXXFLAGS_old=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS -I$QTDIR/include"
+
+  AC_CACHE_VAL(salome_cv_lib_qt,[
+    AC_TRY_LINK(
+#include <qapplication.h>
+,   int n;
+    char **s;
+    QApplication a(n, s);
+    a.exec();,
+    eval "salome_cv_lib_qt=yes",eval "salome_cv_lib_qt=no")
+  ])
+  qt_ok="$salome_cv_lib_qt"
+
+  if  test "x$qt_ok" = "xno"
+  then
+    AC_MSG_RESULT(unable to link with qt library)
+    AC_MSG_RESULT(QTDIR environment variable may be wrong)
+  else
+    AC_MSG_RESULT(yes)
+       QT_LIBS="-L$QTDIR/lib -lqt-mt"
+    QT_MT_LIBS="-L$QTDIR/lib -lqt-mt"
+  fi
+
+  LIBS=$LIBS_old
+  CXXFLAGS=$CXXFLAGS_old
+
+fi
+
+AC_SUBST(MOC)
+AC_SUBST(UIC)
+
+AC_SUBST(QT_ROOT)
+AC_SUBST(QT_INCLUDES)
+AC_SUBST(QT_LIBS)
+AC_SUBST(QT_MT_LIBS)
+
+AC_LANG_RESTORE
+
+AC_MSG_RESULT(for qt: $qt_ok)
+
+# Save cache
+AC_CACHE_SAVE
+
+])dnl
+dnl
diff --git a/adm/unix/config_files/production.m4 b/adm/unix/config_files/production.m4
new file mode 100755 (executable)
index 0000000..d5fa2a3
--- /dev/null
@@ -0,0 +1,107 @@
+dnl  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+dnl 
+dnl  This library is free software; you can redistribute it and/or 
+dnl  modify it under the terms of the GNU Lesser General Public 
+dnl  License as published by the Free Software Foundation; either 
+dnl  version 2.1 of the License. 
+dnl 
+dnl  This library is distributed in the hope that it will be useful, 
+dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+dnl  Lesser General Public License for more details. 
+dnl 
+dnl  You should have received a copy of the GNU Lesser General Public 
+dnl  License along with this library; if not, write to the Free Software 
+dnl  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+dnl 
+dnl  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+dnl
+dnl
+dnl
+dnl define macros :
+dnl AC_ENABLE_PRODUCTION AC_DISABLE_PRODUCTION
+dnl and 
+dnl AC_ENABLE_DEBUG AC_DISABLE_DEBUG
+dnl
+dnl version $Id$
+dnl author Patrick GOLDBRONN
+dnl
+# AC_ENABLE_PRODUCTION
+AC_DEFUN(AC_ENABLE_PRODUCTION, [dnl
+define([AC_ENABLE_PRODUCTION_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(production,
+changequote(<<, >>)dnl
+<<  --enable-production[=PKGS]  build without debug information [default=>>AC_ENABLE_PRODUCTION_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_production=yes ;;
+no) enable_production=no ;;
+*)
+  enable_production=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_production=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_production=AC_ENABLE_PRODUCTION_DEFAULT)dnl
+if test "X$enable_production" = "Xyes"; then
+  FFLAGS="$FFLAGS -O3 "
+  CFLAGS="$CFLAGS -O3 "
+  CXXFLAGS="$CXXFLAGS -O3 "
+else
+  FFLAGS="$FFLAGS"
+  CFLAGS="$CFLAGS"
+  CXXFLAGS="$CXXFLAGS"
+fi
+])
+
+# AC_DISABLE_PRODUCTION - set the default flag to --disable-production
+AC_DEFUN(AC_DISABLE_PRODUCTION, [AC_ENABLE_PRODUCTION(no)])
+
+# AC_ENABLE_DEBUG
+AC_DEFUN(AC_ENABLE_DEBUG, [dnl
+define([AC_ENABLE_DEBUG_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(debug,
+changequote(<<, >>)dnl
+<<  --enable-debug[=PKGS]  build without debug information [default=>>AC_ENABLE_DEBUG_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_debug=yes ;;
+no) enable_debug=no ;;
+*)
+  enable_debug=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_debug=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_debug=AC_ENABLE_DEBUG_DEFAULT)dnl
+
+if test "X$enable_debug" = "Xyes"; then
+  FFLAGS="$FFLAGS -g "
+  CFLAGS="$CFLAGS -g "
+  CXXFLAGS="$CXXFLAGS -g "
+else
+  FFLAGS="$FFLAGS"
+  CFLAGS="$CFLAGS"
+  CXXFLAGS="$CXXFLAGS"
+fi
+])
+
+# AC_DISABLE_DEBUG - set the default flag to --disable-debug
+AC_DEFUN(AC_DISABLE_DEBUG, [AC_ENABLE_DEBUG(no)])
+
diff --git a/adm/unix/config_files/thread.m4 b/adm/unix/config_files/thread.m4
new file mode 100755 (executable)
index 0000000..4724dbc
--- /dev/null
@@ -0,0 +1,24 @@
+# Check presence of "CPPUNIT" product presence
+#
+# Author : Anthony GEAY (CEA, 2006)
+#
+
+AC_DEFUN([CHECK_THREAD],[
+
+AC_CHECKING(for THREADs)
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+thread_ok=no
+
+AC_SUBST(THREAD_DEF)
+if test `uname` = "Linux"
+then
+   THREAD_DEF="-DYACS_PTHREAD"
+   AC_CHECK_HEADER(pthread.h,thread_ok=yes ,thread_ok=no)
+   thread_ok="yes"
+fi
+
+AC_LANG_RESTORE
+AC_MSG_RESULT(for THREADs: $thread_ok)
+
+])dnl
diff --git a/adm/unix/make_begin.am b/adm/unix/make_begin.am
new file mode 100755 (executable)
index 0000000..eeec911
--- /dev/null
@@ -0,0 +1,2 @@
+
+EXTRA_DIST = $(wildcard $(srcdir)/*.hxx) $(wildcard $(srcdir)/*.h)
diff --git a/adm/unix/make_end.am b/adm/unix/make_end.am
new file mode 100755 (executable)
index 0000000..9d769bc
--- /dev/null
@@ -0,0 +1,11 @@
+
+SUFFIXES =
+
+# --------------------------------------------
+# *.i --> *wrap.cxx
+# --------------------------------------------
+
+SUFFIXES += .i WRAP.cxx
+
+.iWRAP.cxx :
+       $(SWIG) $(SWIG_PYTHON_OPT) $(SWIG_PYTHON_INCLUDES) -o $@ $<
diff --git a/build_configure b/build_configure
new file mode 100755 (executable)
index 0000000..a1aed8b
--- /dev/null
@@ -0,0 +1,62 @@
+#! /bin/sh
+
+# --
+#
+PROJECT="YACS"
+
+# --
+# set VERSION from CVS_TAG_NAME
+
+CVS_TAG_NAME='$Name$'
+VERSION=${CVS_TAG_NAME}
+VERSION=`echo ${VERSION/'$Name:'/}`
+VERSION=`echo ${VERSION/'$'/}`
+if test X$VERSION = X ; then
+    VERSION=`date +"%F"`   # -%H-%M
+else
+    VERSION=`echo $VERSION | sed -e "s/V_//g"`
+    VERSION=`echo $VERSION | sed -e "s/_/./g"`
+fi
+
+# --
+ORIG_DIR=`pwd`
+run() {
+    local logfile=$ORIG_DIR/build_configure.log
+    printf "%-50s" "$1 ... "
+    eval $1 > $logfile 2>&1
+    if test $? != 0 ; then
+        echo "[FAILED]"
+        echo "see file build_configure.log ..."
+        exit 1
+    fi
+    echo "[  OK  ]"
+}
+
+# --
+# -- goto build_configure dir
+CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"`
+cd ${CONF_DIR}
+
+# --
+# -- list all Makefile.am in Makefile.am.list
+./rfind . Makefile.am > Makefile.am.list
+
+# --
+# -- configure.in construction
+rm -f configure.in
+touch configure.in
+echo "AC_INIT(src)" >> configure.in
+echo "RELEASE=$VERSION" >> configure.in
+echo "PROJECT=$PROJECT" >> configure.in
+cat configure.in.base >> configure.in
+echo "AC_OUTPUT([ \\" >> configure.in
+# echo "  src/XDATA/xversion.py \\" >> configure.in
+# echo "  doc/xversion.tex \\" >> configure.in
+sed -e 's,\.am, \\,' -e 's,\.\/,,' Makefile.am.list >> configure.in
+echo  "])" >> configure.in
+
+# --
+run "libtoolize"
+run "aclocal -I adm/unix/config_files"
+run "autoconf"
+run "automake --add-missing --copy"
diff --git a/configure.in.base b/configure.in.base
new file mode 100644 (file)
index 0000000..41e7232
--- /dev/null
@@ -0,0 +1,16 @@
+# --
+# Copyright (C) CEA, EDF
+# Author : Anthony Geay (CEA)
+# --
+
+AC_ENABLE_DEBUG(no)
+AC_DISABLE_PRODUCTION
+AC_SUBST(RELEASE)
+AM_INIT_AUTOMAKE($PROJECT, $RELEASE)
+AC_PROG_CXX
+AM_PROG_LIBTOOL
+CHECK_CPPUNIT
+AC_PROG_SWIG(1.3.17)
+SWIG_ENABLE_CXX
+SWIG_PYTHON
+CHECK_THREAD
diff --git a/doc/opml.dtd b/doc/opml.dtd
new file mode 100644 (file)
index 0000000..3f64c45
--- /dev/null
@@ -0,0 +1,63 @@
+<!ENTITY % date-time "(#PCDATA)*" > <!-- conforming to the Date and Time Specification of RFC 822.-->\r
+<!ENTITY % number "(#PCDATA)*" >\r
+<!ENTITY % string "(#PCDATA)*" >\r
+\r
+\r
+\r
+<!ELEMENT opml (head, body) >\r
+<!ATTLIST opml\r
+version CDATA #IMPLIED> <!-- a version string, of the form, x.y, where x and y are both numeric strings.-->\r
+\r
+<!ELEMENT head ( title?, dateCreated?, dateModified?,\r
+ownerName?, ownerEmail?, expansionState?, vertScrollState?,\r
+windowTop?, windowLeft?, windowBottom?, windowRight?   ) >\r
+\r
+<!ELEMENT title (#PCDATA)* > <!--the title of the document.-->\r
+<!ELEMENT dateCreated %date-time; > <!--a date-time, indicating when the document was created.-->\r
+<!ELEMENT dateModified %date-time;> <!--a date-time, indicating when the document was last modified.-->\r
+<!ELEMENT ownerName %string; > <!--a string, the owner of the document. -->\r
+<!ELEMENT ownerEmail %string; > <!--a string, the email address of the owner of the document.-->\r
+\r
+<!ELEMENT expansionState (#PCDATA)* >\r
+<!--\r
+a comma-separated list of line numbers that are expanded.\r
+The line numbers in the list tell you which headlines to expand.\r
+The order is important.\r
+For each element in the list, X, starting at the first summit, navigate \r
+flatdown X times and expand.\r
+Repeat for each element in the list.\r
+-->\r
+\r
+<!ELEMENT vertScrollState %number; >\r
+<!--\r
+a number, saying which line of the outline is displayed on the top line of \r
+the window.\r
+This number is calculated with the expansion state already applied.\r
+-->\r
+\r
+<!ELEMENT windowTop  %number; > <!-- a number, the pixel location of the top edge of the window.-->\r
+<!ELEMENT windowLeft  %number; > <!-- a number, the pixel location of the left edge of the window.-->\r
+<!ELEMENT windowBottom  %number; > <!-- a number, the pixel location of the bottom edge of the window.-->\r
+<!ELEMENT windowRight  %number; > <!-- a number, the pixel location of the right edge of the window.-->\r
+\r
+\r
+<!ELEMENT body (outline)+ >\r
+<!ELEMENT outline (outline)* >\r
+\r
+<!ENTITY % OtherAttributes  " "       >\r
+<!ATTLIST outline text CDATA #IMPLIED\r
+                  type CDATA #IMPLIED\r
+                  isComment ( true | false ) false\r
+isBreakpoint (true|false) false >\r
+<!--\r
+text is the string of characters that's displayed when the outline is being browsed or edited. \r
+type is a string, it says how the other attributes of the <outline> are interpreted.\r
+isComment indicates whether the outline is commented or not.\r
+By convention if an outline is commented, all subordinate outlines are considered to be commented as well.\r
+isBreakpoint indicates whether a breakpoint is set on this outline.This attribute is mainly necessary for outlines used to edit scripts that execute.\r
+\r
+You can add whatever other attributes on the outline element you want.\r
+-->\r
+\r
+\r
+\r
diff --git a/doc/opml.xslt b/doc/opml.xslt
new file mode 100644 (file)
index 0000000..4a56aac
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>\r
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">\r
+<xsl:output method = "html" version = "4.0" encoding="ISO-8859-1" indent = "no" />\r
+<xsl:strip-space elements = "*" />\r
+\r
+<xsl:variable name="markerNormal">&#9658;</xsl:variable>\r
+<xsl:variable name="markerComment">&#8810;</xsl:variable>\r
+<xsl:variable name="markerLink">&#9788;</xsl:variable>\r
+\r
+<xsl:template match = "/opml" >\r
+<html>\r
+  <script language="JavaScript" src="http://www.netcrucible.com/xslt/opml.js" />\r
+  <link rel="stylesheet" href="http://www.netcrucible.com/xslt/opml.css" />\r
+  <head><title><xsl:value-of select="head/title" /></title></head>\r
+  <body>\r
+    <div id="outlineRoot" class="outlineRoot">\r
+        <xsl:for-each select="head/*" >\r
+        <span class="outlineAttribute" title="{name()}"><xsl:value-of select="." /></span>\r
+        </xsl:for-each>\r
+       <xsl:apply-templates select="body"/>\r
+    </div>\r
+    <span id="markerNormal" style="display:none"><xsl:value-of select="$markerNormal" /></span>\r
+    <span id="markerComment" style="display:none"><xsl:value-of select="$markerComment" /></span>\r
+    <span id="markerLink" style="display:none"><xsl:value-of select="$markerLink" /></span>\r
+  </body>\r
+</html>\r
+</xsl:template>\r
+\r
+<xsl:template match = "outline" >\r
+  <div class="outline">\r
+       <xsl:attribute name="style">\r
+         <xsl:if test="parent::outline">display:none</xsl:if>       \r
+       </xsl:attribute>\r
+       <xsl:for-each select="@*[name() !='text']" >\r
+       <span class="outlineAttribute" title="{name()}"><xsl:value-of select="." /></span>\r
+       </xsl:for-each>\r
+       <span>\r
+            <xsl:attribute name="class">\r
+              <xsl:choose>\r
+                <xsl:when test="./*">markerClosed</xsl:when>\r
+                <xsl:when test="contains(@url,'.opml') or contains(@url,'.OPML')">markerClosed</xsl:when>\r
+                <xsl:otherwise>markerOpen</xsl:otherwise>\r
+              </xsl:choose>\r
+            </xsl:attribute>\r
+            <xsl:choose>\r
+               <xsl:when test="@isComment = 'true'"><xsl:value-of select="$markerComment" /></xsl:when>\r
+               <xsl:when test="@type = 'link' and not(contains(@url,'.opml') or contains(@url,'.OPML'))"><xsl:value-of select="$markerLink" /></xsl:when>\r
+               <xsl:otherwise><xsl:value-of select="$markerNormal" /></xsl:otherwise>\r
+            </xsl:choose>\r
+       </span>\r
+       <span class="outlineText">\r
+       <xsl:value-of select = "@text" disable-output-escaping = "yes" /></span>\r
+       <xsl:apply-templates />\r
+  </div>\r
+</xsl:template>\r
+\r
+</xsl:stylesheet>\r
diff --git a/doc/programingRules.sxw b/doc/programingRules.sxw
new file mode 100644 (file)
index 0000000..a744bd5
Binary files /dev/null and b/doc/programingRules.sxw differ
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755 (executable)
index 0000000..8ab885e
--- /dev/null
@@ -0,0 +1,99 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+   case "${1}" in
+     -h | --help | --h* )                      # -h for help
+       echo "${usage}" 1>&2; exit 0 ;;
+     -m )                                      # -m PERM arg
+       shift
+       test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
+       dirmode="${1}"
+       shift ;;
+     -- ) shift; break ;;                      # stop option processing
+     -* ) echo "${usage}" 1>&2; exit 1 ;;      # unknown option
+     * )  break ;;                             # first non-opt arg
+   esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+0) exit 0 ;;
+esac
+
+case $dirmode in
+'')
+  if mkdir -p -- . 2>/dev/null; then
+    echo "mkdir -p -- $*"
+    exec mkdir -p -- "$@"
+  fi ;;
+*)
+  if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
+    echo "mkdir -m $dirmode -p -- $*"
+    exec mkdir -m "$dirmode" -p -- "$@"
+  fi ;;
+esac
+
+for file
+do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d
+   do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+       echo "mkdir $pathcomp"
+
+       mkdir "$pathcomp" || lasterr=$?
+
+       if test ! -d "$pathcomp"; then
+         errstatus=$lasterr
+       else
+         if test ! -z "$dirmode"; then
+            echo "chmod $dirmode $pathcomp"
+
+            lasterr=""
+            chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+            if test ! -z "$lasterr"; then
+              errstatus=$lasterr
+            fi
+         fi
+       fi
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 3
+# End:
+# mkinstalldirs ends here
diff --git a/py-compile b/py-compile
new file mode 100755 (executable)
index 0000000..a055fae
--- /dev/null
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+# py-compile - Compile a Python program
+# Copyright 2000, 2001 Free Software Foundation, Inc.
+
+# 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, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# called as "py-compile [--basedir DIR] PY_FILES ...
+
+if [ -z "$PYTHON" ]; then
+  PYTHON=python
+fi
+
+basedir=
+
+case "$1" in
+    --basedir)
+       basedir=$2
+       shift 2
+       ;;
+    --help)
+       echo "Usage: py-compile [--basedir DIR] PY_FILES ..."
+       echo "Byte compile some python scripts.  This should be performed"
+       echo "after they have been moved to the final installation location"
+       exit 0
+       ;;
+    --version)
+       echo "py-compile version 0.0"
+       exit 0
+       ;;
+esac
+
+if [ $# = 0 ]; then
+    echo "No files given to $0" 1>&2
+    exit 1
+fi
+
+# if basedir was given, then it should be prepended to filenames before
+# byte compilation.
+if [ -z "$basedir" ]; then
+    trans="path = file"
+else
+    trans="path = os.path.join('$basedir', file)"
+fi
+
+$PYTHON -c "
+import sys, os, string, py_compile
+
+files = '''$*'''
+print 'Byte-compiling python modules...'
+for file in string.split(files):
+    $trans
+    if not os.path.exists(path) or not (len(path) >= 3 and path[-3:] == '.py'):
+       continue
+    print file,
+    sys.stdout.flush()
+    py_compile.compile(path)
+print" || exit $?
+
+# this will fail for python < 1.5, but that doesn't matter ...
+$PYTHON -O -c "
+import sys, os, string, py_compile
+
+files = '''$*'''
+print 'Byte-compiling python modules (optimised versions) ...'
+for file in string.split(files):
+    $trans
+    if not os.path.exists(path) or not (len(path) >= 3 and path[-3:] == '.py'):
+       continue
+    print file,
+    sys.stdout.flush()
+    py_compile.compile(path)
+print" 2>/dev/null || :
+
diff --git a/rfind b/rfind
new file mode 100755 (executable)
index 0000000..e35b27b
--- /dev/null
+++ b/rfind
@@ -0,0 +1,52 @@
+#! /bin/sh
+# --
+# Copyright (C) CEA, EDF
+# Author : Erwan ADAM (CEA)
+# --
+
+#
+# Usage : rfind dir suffix ...
+# 
+# find all files *suffix in dir in a recursive way
+# different of the usual command find ...
+#
+
+if test $# != 2 ; then
+    echo "Usage : $0 dir suffix"
+    exit
+fi
+
+local_find() {
+    # if the first argument is not a directory, returns
+    if test ! -d $1 ; then 
+       # echo "$1 is not a directory"
+       return 
+    fi
+    # dont look in the CVS directories
+    # dont look in the autom4te* directories
+    case "$1" in
+       */CVS) return ;;
+       */autom4te*) return ;;
+       */*_ROOT) return ;;
+       */*_SRC) return ;;
+       *) ;;
+    esac
+    # for each regular file contained in the directory
+    # test if it's a *"$2" file
+    for i in $1/*
+    do
+       if test -f $i ; then
+           case `basename $i` in 
+               *$2) echo "     "$i ;;
+               *) ;;
+           esac
+       fi
+    done
+    # for each subdirectory of the first argument, proceeds recursively
+    for i in $1/*
+    do
+       local_find $i $2
+    done
+}
+
+local_find $1 $2
diff --git a/root_clean b/root_clean
new file mode 100755 (executable)
index 0000000..2116b3b
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"`
+cd ${CONF_DIR}
+
+TO_CLEAN=
+TO_CLEAN=${TO_CLEAN}' build_configure.log'
+TO_CLEAN=${TO_CLEAN}' Makefile.am.list'
+TO_CLEAN=${TO_CLEAN}' aclocal.m4'
+TO_CLEAN=${TO_CLEAN}' autom4te*'
+TO_CLEAN=${TO_CLEAN}' configure'
+TO_CLEAN=${TO_CLEAN}' configure.in'
+TO_CLEAN=${TO_CLEAN}' COPYING INSTALL'
+TO_CLEAN=${TO_CLEAN}' missing'
+TO_CLEAN=${TO_CLEAN}' install-sh'
+TO_CLEAN=${TO_CLEAN}' config.guess'
+TO_CLEAN=${TO_CLEAN}' config.sub'
+TO_CLEAN=${TO_CLEAN}' depcomp'
+
+rm -rf $TO_CLEAN > /dev/null
+
+l=`find . -name "Makefile.in" -or -name "*~"`
+
+if test X"$l" != X ; then
+    rm -f $l
+fi
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..c234fb0
--- /dev/null
@@ -0,0 +1,2 @@
+
+SUBDIRS = bases basicData engine
diff --git a/src/bases/Exception.cxx b/src/bases/Exception.cxx
new file mode 100644 (file)
index 0000000..a566eab
--- /dev/null
@@ -0,0 +1,16 @@
+#include "Exception.hxx"
+
+using namespace YACS;
+
+Exception::Exception(const std::string& what):_what(what)
+{
+}
+
+const char *Exception::what( void ) const throw ()
+{
+  return _what.c_str();
+}
+
+Exception::~Exception() throw ()
+{
+}
diff --git a/src/bases/Exception.hxx b/src/bases/Exception.hxx
new file mode 100644 (file)
index 0000000..d4cde40
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __EXCEPTION_HXX__
+#define __EXCEPTION_HXX__
+
+#include <string>
+#include <exception>
+
+namespace YACS
+{
+  class Exception : public std::exception
+  {
+  protected:
+    std::string _what;
+  public:
+    Exception(const std::string& what);
+    const char *what( void ) const throw ();
+    ~Exception() throw ();
+  };
+}
+
+#endif
diff --git a/src/bases/Makefile.am b/src/bases/Makefile.am
new file mode 100644 (file)
index 0000000..5231ecf
--- /dev/null
@@ -0,0 +1,20 @@
+
+include $(top_srcdir)/adm/unix/make_begin.am
+
+SUBDIRS = Test
+
+noinst_LTLIBRARIES = libYACSBases.la
+
+libYACSBases_la_SOURCES = Exception.cxx Thread.cxx Mutex.cxx Semaphore.cxx \
+       $(__dummy__)
+
+EXTRA_libYACSBases_la_SOURCES = 
+       Thread.hxx ThreadPT.hxx ThreadPT.cxx          \
+       Mutex.hxx MutexPT.cxx MutexPT.hxx             \
+       Semaphore.hxx SemaphorePT.cxx SemaphorePT.hxx \
+       Exception.hxx                                 \
+       $(__dummy__)
+
+AM_CXXFLAGS = $(THREAD_DEF)
+
+include $(top_srcdir)/adm/unix/make_end.am
diff --git a/src/bases/Mutex.cxx b/src/bases/Mutex.cxx
new file mode 100644 (file)
index 0000000..cd94bfa
--- /dev/null
@@ -0,0 +1,7 @@
+#include "Mutex.hxx"
+
+#if defined(YACS_PTHREAD)
+#include "MutexPT.cxx"
+#else
+#error
+#endif
diff --git a/src/bases/Mutex.hxx b/src/bases/Mutex.hxx
new file mode 100644 (file)
index 0000000..cfc2500
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __MUTEX_HXX__
+#define __MUTEX_HXX__
+
+/* Interface is :
+   class Mutex
+    {
+    public:
+      Mutex();
+      void lock();
+      void unlock();
+    };
+ */
+
+#if defined(YACS_PTHREAD)
+#include "MutexPT.hxx"
+
+namespace YACS
+{
+  namespace BASES
+  {
+    typedef MutexPT Mutex;
+  }
+}
+#else
+#error
+#endif
+
+#endif
diff --git a/src/bases/MutexPT.cxx b/src/bases/MutexPT.cxx
new file mode 100644 (file)
index 0000000..8233a39
--- /dev/null
@@ -0,0 +1,24 @@
+#include "MutexPT.hxx"
+
+using namespace YACS::BASES;
+
+MutexPT::MutexPT()
+{
+  pthread_mutexattr_settype(&_options, PTHREAD_MUTEX_FAST_NP);
+  pthread_mutex_init(&_mutexDesc, &_options);
+}
+
+MutexPT::~MutexPT()
+{
+  pthread_mutex_destroy(&_mutexDesc);
+}
+
+void MutexPT::lock()
+{
+  pthread_mutex_lock(&_mutexDesc);
+}
+
+void MutexPT::unlock()
+{
+  pthread_mutex_unlock(&_mutexDesc);
+}
diff --git a/src/bases/MutexPT.hxx b/src/bases/MutexPT.hxx
new file mode 100644 (file)
index 0000000..ef7c940
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __MUTEXPT_HXX__
+#define __MUTEXPT_HXX__
+
+#include <pthread.h>
+
+namespace YACS
+{
+  namespace BASES
+  {
+    class MutexPT
+    {
+    public:
+      MutexPT();
+      ~MutexPT();
+      void lock();
+      void unlock();
+    private:
+      pthread_mutex_t _mutexDesc;
+      pthread_mutexattr_t _options;
+
+    };
+  }
+}
+
+#endif
diff --git a/src/bases/Semaphore.cxx b/src/bases/Semaphore.cxx
new file mode 100644 (file)
index 0000000..5de98c0
--- /dev/null
@@ -0,0 +1,7 @@
+#include "Semaphore.hxx"
+
+#if defined(YACS_PTHREAD)
+#include "SemaphorePT.cxx"
+#else
+#error
+#endif
diff --git a/src/bases/Semaphore.hxx b/src/bases/Semaphore.hxx
new file mode 100644 (file)
index 0000000..68dc9b6
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef __SEMAPHORE_HXX__
+#define __SEMAPHORE_HXX__
+
+/* Interface is :
+   class Semaphore
+    {
+    public:
+      Semaphore(int initValue=0);
+      ~Semaphore();
+      void post();
+      void wait();
+      int getvalue();
+    };
+ */
+
+#if defined(YACS_PTHREAD)
+#include "SemaphorePT.hxx"
+
+namespace YACS
+{
+  namespace BASES
+  {
+    typedef SemaphorePT Semaphore;
+  }
+}
+#else
+#error
+#endif
+
+#endif
diff --git a/src/bases/SemaphorePT.cxx b/src/bases/SemaphorePT.cxx
new file mode 100644 (file)
index 0000000..73955fa
--- /dev/null
@@ -0,0 +1,30 @@
+#include "SemaphorePT.hxx"
+
+using namespace YACS::BASES;
+
+SemaphorePT::SemaphorePT(int initValue)
+{
+  sem_init(&_semDesc, 0, initValue);
+}
+
+SemaphorePT::~SemaphorePT()
+{
+  sem_destroy(&_semDesc);
+}
+
+void SemaphorePT::post()
+{
+  sem_post(&_semDesc);
+}
+
+void SemaphorePT::wait()
+{
+  sem_wait(&_semDesc);
+}
+
+int SemaphorePT::getValue()
+{
+  int val;
+  sem_getvalue(&_semDesc,&val);
+  return val;
+}
diff --git a/src/bases/SemaphorePT.hxx b/src/bases/SemaphorePT.hxx
new file mode 100644 (file)
index 0000000..64f3055
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef __SEMAPHOREPT_HXX__
+#define __SEMAPHOREPT_HXX__
+
+#include <semaphore.h>
+
+namespace YACS
+{
+  namespace BASES
+  {
+    class SemaphorePT
+    {
+    public:
+      SemaphorePT(int initValue=0);
+      ~SemaphorePT();
+      void post();
+      void wait();
+      int getValue();
+    private:
+      sem_t _semDesc;
+    };
+  }
+}
+
+#endif
diff --git a/src/bases/Test/Makefile.am b/src/bases/Test/Makefile.am
new file mode 100644 (file)
index 0000000..1e256d6
--- /dev/null
@@ -0,0 +1,18 @@
+
+include $(top_srcdir)/adm/unix/make_begin.am
+
+AM_CXXFLAGS = $(THREAD_DEF) -I$(srcdir)/..
+
+check_PROGRAMS = test1
+
+test1_SOURCES = test1.cxx
+
+test1_LDADD = ../libYACSBases.la
+
+test1_LDFLAGS = $(CPPUNIT_LIBS) -pthread -ldl
+
+test1_CXXFLAGS = $(THREAD_DEF) $(CPPUNIT_INCLUDES) -I$(srcdir)/..
+
+TESTS = test1
+
+include $(top_srcdir)/adm/unix/make_end.am
diff --git a/src/bases/Test/test1.cxx b/src/bases/Test/test1.cxx
new file mode 100644 (file)
index 0000000..6bf7662
--- /dev/null
@@ -0,0 +1,139 @@
+#include "Mutex.hxx"
+#include "Thread.hxx"
+#include "Semaphore.hxx"
+//
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <sstream>
+//
+
+using namespace YACS::BASES;
+
+class ThreadMechanismTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( ThreadMechanismTest );
+  CPPUNIT_TEST( test1 );
+  CPPUNIT_TEST( test2 );
+  CPPUNIT_TEST_SUITE_END();
+public: 
+  void setUp();
+  void tearDown();
+  void test1();
+  void test2();
+private:
+  static void *th1_1(void *);
+  static void *th1_2(void *);
+  static void *th1_3(void *);
+  static void *th2_1(void *);
+private:
+  static int _var;
+  static std::ostringstream _glob;
+  static Mutex _m;
+  static Semaphore _s1;
+  static Semaphore _s2;
+  //
+  static const int THREAD_NUM;
+  static const int LOOPS;
+  static int _value;
+};
+
+Mutex ThreadMechanismTest::_m;
+
+Semaphore ThreadMechanismTest::_s1;
+
+Semaphore ThreadMechanismTest::_s2;
+
+std::ostringstream ThreadMechanismTest::_glob;
+
+int ThreadMechanismTest::_var=7;
+
+const int ThreadMechanismTest::THREAD_NUM=5;
+
+const int ThreadMechanismTest::LOOPS=4;
+
+int ThreadMechanismTest::_value=0;
+
+void ThreadMechanismTest::setUp()
+{
+}
+
+void ThreadMechanismTest::tearDown()
+{
+}
+
+void ThreadMechanismTest::test1()
+{
+  char t1Name='A'; char t2Name='B'; char t3Name='C';
+  Thread t1(th1_1,&t1Name);
+  Thread t2(th1_2,&t2Name);
+  Thread t3(th1_3,&t3Name);
+  t1.join();
+  t2.join();
+  t3.join();
+  CPPUNIT_ASSERT( _glob.str() == "C7A8B10" );
+}
+
+void ThreadMechanismTest::test2()
+{
+  int i;
+  Thread **ths=new Thread *[THREAD_NUM];
+  for (i=0; i<THREAD_NUM; ++i)
+    ths[i]=new Thread(th2_1,0);
+
+  for (i=0; i<THREAD_NUM; ++i)
+    {
+      ths[i]->join();
+      delete ths[i];
+    }
+  delete [] ths;
+  CPPUNIT_ASSERT( _value == THREAD_NUM*LOOPS );
+}
+
+void *ThreadMechanismTest::th1_1(void *st)
+{
+  char myName=*((char *) st);
+  _s1.wait();
+  _glob<< myName << _var;
+  _var+=2;
+  _s1.post();
+  _s2.post();
+}
+
+void *ThreadMechanismTest::th1_2(void *st)
+{
+  char myName=*((char *) st);
+  _s2.wait();
+  _glob<< myName << _var;
+  _s2.post();
+}
+
+void *ThreadMechanismTest::th1_3(void *st)
+{
+  char myName=*((char *) st);
+  _glob<< myName << _var++;
+  _s1.post();
+}
+
+void *ThreadMechanismTest::th2_1(void *)
+{
+  int i, tmp;
+  int rc = 0;     
+  for (i=0; i<LOOPS; ++i)
+    {
+      _m.lock();
+      tmp = _value;
+      tmp = tmp+1;
+      Thread::sleep(1000);
+      _value = tmp;
+      _m.unlock();
+      Thread::sleep(100000);
+    }
+}
+
+int main()
+{
+  CppUnit::TextUi::TestRunner runner;
+  runner.addTest( ThreadMechanismTest::suite() );
+  runner.run();
+  return 0;
+}
diff --git a/src/bases/Thread.cxx b/src/bases/Thread.cxx
new file mode 100644 (file)
index 0000000..dbc9e5b
--- /dev/null
@@ -0,0 +1,9 @@
+#include "Thread.hxx"
+
+#if defined(YACS_PTHREAD)
+
+#include "ThreadPT.cxx"
+
+#else
+#error
+#endif
diff --git a/src/bases/Thread.hxx b/src/bases/Thread.hxx
new file mode 100644 (file)
index 0000000..041c34f
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef __THREAD_HXX__
+#define __THREAD_HXX__
+
+/* Interface is :
+   class Thread
+    {
+    public:
+      typedef void *(*ThreadJob)(void*);
+    public:
+      Thread(ThreadJob funcPtr, void *stack);
+      bool operator==(const Thread& other);
+      void join();
+      static void sleep(unsigned long usec);
+    };
+ */
+
+#if defined(YACS_PTHREAD)
+#include "ThreadPT.hxx"
+
+namespace YACS
+{
+  namespace BASES
+  {
+    typedef ThreadPT Thread;
+  }
+}
+#else
+#error
+#endif
+
+#endif
diff --git a/src/bases/ThreadPT.cxx b/src/bases/ThreadPT.cxx
new file mode 100644 (file)
index 0000000..c32b30d
--- /dev/null
@@ -0,0 +1,26 @@
+#include "ThreadPT.hxx"
+#include <unistd.h>
+
+using namespace YACS::BASES;
+
+ThreadPT::ThreadPT(ThreadJob funcPtr, void *stack)
+{
+  void **stackT=(void **) stack;
+  pthread_create(&_threadId,0,funcPtr,stackT);
+}
+
+bool ThreadPT::operator==(const ThreadPT& other)
+{
+  return pthread_equal(_threadId, other._threadId) != 0;
+}
+
+void ThreadPT::join()
+{
+  void *ret;
+  pthread_join(_threadId, &ret);
+}
+
+void ThreadPT::sleep(unsigned long usec)
+{
+  usleep(usec);
+}
diff --git a/src/bases/ThreadPT.hxx b/src/bases/ThreadPT.hxx
new file mode 100644 (file)
index 0000000..05ddc95
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __THREADPT_HXX__
+#define __THREADPT_HXX__
+
+#include <pthread.h>
+
+namespace YACS
+{
+  namespace BASES
+  {
+    class ThreadPT
+    {
+    public:
+      typedef void *(*ThreadJob)(void*);
+    public:
+      ThreadPT(ThreadJob funcPtr, void *stack);
+      bool operator==(const ThreadPT& other);
+      void join();
+      static void sleep(unsigned long usec);
+    private:
+      pthread_t _threadId;
+    };
+  }
+}
+
+#endif
diff --git a/src/bases/define.hxx b/src/bases/define.hxx
new file mode 100644 (file)
index 0000000..34d8dd9
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef __DEFINE_HXX__
+#define __DEFINE_HXX__
+
+namespace YACS
+{
+  //for algs of graphs and trees
+  typedef enum
+    {
+      White = 10,
+      Grey  = 11,
+      Black = 12
+    } Colour;
+
+  typedef enum
+    {
+      Double = 41,
+      Int = 42,
+      String = 44,
+      Bool = 45,
+      //CorbaRef = 46,
+      None = 49
+    } DynType;
+
+  typedef enum
+    {
+      SDouble = 71
+    } StreamType;
+
+  typedef enum
+    {
+      INITED       = 100,
+      TOLOAD       = 101,
+      LOADED       = 102,
+      TOACTIVATE   = 103,
+      ACTIVATED    = 104,
+      DESACTIVATED = 105,
+      DONE         = 106,
+      SUSPENDED    = 107,
+      LOADFAILED   = 108,
+      EXECFAILED   = 109,
+      PAUSE        = 110
+    } StatesForNode;
+
+  typedef enum
+    {
+      NOEVENT      = 200,
+      START        = 201,
+      FINISH       = 202,
+      ABORT        = 203
+    } Event;
+}
+
+#endif
diff --git a/src/basicData/ContentOfDataFlow.cxx b/src/basicData/ContentOfDataFlow.cxx
new file mode 100644 (file)
index 0000000..66639f5
--- /dev/null
@@ -0,0 +1,104 @@
+#include "ContentOfDataFlow.hxx"
+
+using namespace YACS::ENGINE;
+
+const char ContentOfDataFlow::STRFORNULLREPR[]="NULL";
+
+template< YACS::DynType type >
+class TreatmentForNewContentDataFlow
+{
+public:
+  static void perform(const std::string& input, ContentOfDataFlow::Type& ret)
+  {
+    ret=ContentOfDataFlow::createNewContent<type>(input);
+  }
+};
+
+template< YACS::DynType fromType, YACS::DynType toType >
+class TreatmentForConvertContentDataFlow
+{
+  public:
+  static void perform(ContentOfDataFlow::Type input, ContentOfDataFlow::Type& ret)
+  {
+    ret=StaticAndDynamicTypeConverter<ContentOfDataFlow,fromType,toType>::convert(input);
+  }
+};
+
+template< YACS::DynType fromType, YACS::DynType toType >
+class TreatmentToCheckStaticallyTypes
+{
+  public:
+  static void perform(ContentOfDataFlow::Type input, bool& ret)
+  {
+    ret=StaticTypeConverter<fromType,toType>::_staticallyCompatible;
+  }
+};
+
+void ContentOfDataFlow::duplicate(ContentOfDataFlow::Type content)
+{
+  if(content!=neuter())
+    {
+      int *contentC=(int *)content;
+      (*contentC)=(*contentC)+1;
+    }
+}
+
+void ContentOfDataFlow::release(ContentOfDataFlow::Type& content)
+{
+  if(content!=neuter())
+    {
+      int *contentC=(int *)content;
+      (*contentC)=(*contentC)-1;
+      if((*contentC)==0)
+       {
+         free(content);
+         content=neuter();
+       }
+    }
+}
+
+ContentOfDataFlow::Type ContentOfDataFlow::createNewContent(const std::string& content, DynType typeOfContent) throw(Exception)
+{
+  ContentOfDataFlow::Type ret;
+  DynToStaticTypeDispatcher1<TreatmentForNewContentDataFlow>::perform(typeOfContent, content, ret);
+  return ret;
+}
+
+ContentOfDataFlow::Type ContentOfDataFlow::convertContent(ContentOfDataFlow::Type content, DynType fromType, DynType toType) throw(ConversionException)
+{
+  if(fromType==toType)
+    return content;
+  else
+    {
+      ContentOfDataFlow::Type ret;
+      DynToStaticTypeDispatcher2<TreatmentForConvertContentDataFlow>::perform(fromType, toType, content, ret);
+      return ret;
+    }
+}
+
+bool ContentOfDataFlow::isStaticallyCompatibleWith(DynType fromType, DynType toType) throw(Exception)
+{
+  bool ret;
+  DynToStaticTypeDispatcher2<TreatmentToCheckStaticallyTypes>::perform(fromType, toType, ContentOfDataFlow::neuter(), ret);
+  return ret;
+}
+
+std::string ContentOfDataFlow::getRepresentation(ContentOfDataFlow::Type content)
+{
+  if(content!=ContentOfDataFlow::neuter())
+    {
+      char *contentC=(char *)content;
+      contentC+=sizeof(int);
+      return std::string(contentC);
+    }
+  else
+    return ContentOfDataFlow::STRFORNULLREPR;
+}
+
+ContentOfDataFlow::Type ContentOfDataFlow::allocate(int lgth)
+{
+  ContentOfDataFlow::Type ret=malloc(lgth+1+sizeof(int));
+  int *ret2=(int *)ret;
+  *ret2=1;
+  return ret;
+}
diff --git a/src/basicData/ContentOfDataFlow.hxx b/src/basicData/ContentOfDataFlow.hxx
new file mode 100644 (file)
index 0000000..bb4e665
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef __CONTENTOFDATAFLOW_HXX__
+#define __CONTENTOFDATAFLOW_HXX__
+
+#include "define.hxx"
+#include "TypeCheckerDataFlow.hxx"
+#include "ConversionException.hxx"
+
+#include <string>
+#include <cstring>
+#include <sstream>
+#include <stdlib.h>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class ContentOfDataFlow
+    {
+    public:
+      typedef void * Type;
+
+      static void duplicate(Type content);
+      static void release(Type& content);
+      static Type createNewContent(const std::string& content, DynType typeOfContent) throw(Exception);
+      static Type convertContent(Type content, DynType fromType, DynType toType) throw(ConversionException);
+      static bool isStaticallyCompatibleWith(DynType fromType, DynType toType) throw(Exception);
+      template<class T>
+      static Type createNewContent(T value);
+      template<YACS::DynType typ>
+      static Type createNewContent(const std::string& content) throw(Exception);
+      template<class T>
+      static void readContent(Type content, T& value) throw(Exception);
+      static Type neuter() { return 0; }
+      static std::string getRepresentation(Type content);
+    private:
+      static Type allocate(int lgth);
+    private:
+      static const char STRFORNULLREPR[];
+    };
+
+    template<class T>
+    ContentOfDataFlow::Type ContentOfDataFlow::createNewContent(T value)
+    {
+      std::ostringstream stream;
+      stream << value;
+      int length=stream.str().length();
+      ContentOfDataFlow::Type ret=allocate(length);
+      int *retC=(int *)ret;
+      memcpy(retC+1,stream.str().c_str(),length+1);
+      return ret;
+    }
+
+    template<class T>
+    void ContentOfDataFlow::readContent(ContentOfDataFlow::Type content, T& value) throw(Exception)
+    {
+      if(content==ContentOfDataFlow::neuter())
+       throw Exception("no content to read");
+      char *contentC=(char *)content;
+      contentC+=sizeof(int);
+      const DynType typ=TypeDescriptorTraitsInv<T>::_typeEnum;
+      std::istringstream stream(contentC);
+      stream >> value;
+      if(stream.fail() || !stream.eof())
+       {
+         std::string what="Content not recognized as "; what+=TypeDescriptorTraits<TypeDescriptorTraitsInv<T>::_typeEnum>::_name;
+         throw Exception(what);
+       }
+    }
+
+    template<YACS::DynType typ>
+    ContentOfDataFlow::Type ContentOfDataFlow::createNewContent(const std::string& content) throw(Exception)
+    {
+      std::istringstream stream(content);
+      typename TypeDescriptorTraits<typ>::ConcreteType value;
+      stream >> value;
+      if(!stream.fail() && stream.eof())
+       return createNewContent(value);
+      else
+       {
+         std::string what(content);
+         what+=" is not recognized as "; what+=TypeDescriptorTraits<typ>::_name;
+         throw Exception(what);
+       }
+    }
+  }
+}
+
+#endif
diff --git a/src/basicData/ConversionException.cxx b/src/basicData/ConversionException.cxx
new file mode 100644 (file)
index 0000000..d9b1da0
--- /dev/null
@@ -0,0 +1,14 @@
+#include "ConversionException.hxx"
+
+using namespace YACS::ENGINE;
+
+const char ConversionException::TYPEOFEXCEPTION[]="Conversion between types failed : ";
+
+
+ConversionException::ConversionException(const std::string& content, const std::string& expectedType):Exception(TYPEOFEXCEPTION)
+{
+  _what=TYPEOFEXCEPTION;
+  _what+=content;
+  _what+=" -> Expecting type ";
+  _what+=expectedType;
+}
diff --git a/src/basicData/ConversionException.hxx b/src/basicData/ConversionException.hxx
new file mode 100644 (file)
index 0000000..f32f609
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef __CONVERSIONEXCEPTION_HXX__
+#define __CONVERSIONEXCEPTION_HXX__
+
+#include "Exception.hxx"
+
+#include <string>
+
+namespace YACS
+{
+  namespace ENGINE
+  {    
+    class ConversionException : public Exception
+    {
+    public:
+      ConversionException(const std::string& content, const std::string& expectedType);
+    private:
+      static const char TYPEOFEXCEPTION[];
+    };
+  }
+}
+
+#endif
diff --git a/src/basicData/Data.cxx b/src/basicData/Data.cxx
new file mode 100644 (file)
index 0000000..e0bd62c
--- /dev/null
@@ -0,0 +1,127 @@
+#include "Data.hxx"
+
+using namespace YACS::ENGINE;
+
+const char Data::UNRECOGNIZEDTYPENAME[]="Unrecognized type";
+
+Data::Data(DynType typeOfContent):_edType(typeOfContent),_exContent(ContentOfDataFlow::neuter())
+{
+}
+
+Data::Data(const std::string& content, DynType typeOfContent) throw(Exception):_edType(typeOfContent)
+{
+  _exContent=ContentOfDataFlow::createNewContent(content,typeOfContent);
+}
+
+Data::Data(const Data& other):_edType(other._edType)
+{
+  ContentOfDataFlow::duplicate(other._exContent);
+  _exContent=other._exContent;
+}
+
+Data::~Data()
+{
+  ContentOfDataFlow::release(_exContent);
+}
+
+Data &Data::operator =(const Data& other) throw(ConversionException)
+{
+  if(&other!=this)
+    {
+      if(other._exContent==ContentOfDataFlow::neuter())
+       {
+         ContentOfDataFlow::release(_exContent);
+         _exContent=ContentOfDataFlow::neuter();
+         return *this;
+       }
+      if(other._edType==_edType)
+       {
+         ContentOfDataFlow::duplicate(other._exContent);
+         ContentOfDataFlow::release(_exContent);
+         _exContent=other._exContent;
+       }
+      else
+       {
+         ContentOfDataFlow::release(_exContent);
+         _exContent=ContentOfDataFlow::convertContent(other._exContent,other._edType,_edType);
+       }
+    }
+  return *this;
+}
+
+std::string Data::edGetRepresentation() const
+{
+  std::ostringstream stream;
+  stream << _edType << "_" << ContentOfDataFlow::getRepresentation(_exContent);
+  return stream.str();
+}
+
+void Data::edSetNewType(DynType newTypeOfContent) throw(ConversionException)
+{
+  if(_edType==newTypeOfContent)
+    return;
+  ContentOfDataFlow::Type newContent=ContentOfDataFlow::convertContent(_exContent,_edType,newTypeOfContent);
+  ContentOfDataFlow::release(_exContent);
+  _exContent=newContent;
+  _edType=newTypeOfContent;
+}
+
+void Data::exSetContent(const std::string& content) throw(ConversionException)
+{
+  ContentOfDataFlow::release(_exContent);
+  _exContent=ContentOfDataFlow::createNewContent(content,_edType);
+}
+
+void Data::edInitToType(DynType typeOfContent)
+{
+  ContentOfDataFlow::release(_exContent);
+  _exContent=ContentOfDataFlow::neuter();
+  _edType=typeOfContent;
+}
+
+void Data::exInit()
+{
+  ContentOfDataFlow::release(_exContent);
+  _exContent=ContentOfDataFlow::neuter();
+}
+
+// Part of Data::edGetType implementation
+template< YACS::DynType type >
+class TreatmentForNameOfType
+{
+public:
+  static void perform(int input, std::string& ret)
+  {
+    ret=TypeDescriptorTraits<type>::_name;
+  }
+};
+
+std::string Data::edGetTypeInPrintableForm(DynType type)
+{
+  try
+    {
+      int fake1;
+      std::string ret;
+      DynToStaticTypeDispatcher1<TreatmentForNameOfType>::perform(type, fake1, ret);
+      return ret;
+    }
+  catch(Exception& e)
+    {
+      return UNRECOGNIZEDTYPENAME;
+    }
+}
+
+bool Data::isStaticallyCompatibleWith(const Data& other) const throw(Exception)
+{
+  return areStaticallyCompatible(_edType, other._edType);
+}
+
+bool Data::areStaticallyCompatible(DynType type1, DynType type2) throw(Exception)
+{
+  return ContentOfDataFlow::isStaticallyCompatibleWith(type1, type2);
+}
+
+bool Data::empty() const
+{
+  return _exContent==ContentOfDataFlow::neuter();
+}
diff --git a/src/basicData/Data.hxx b/src/basicData/Data.hxx
new file mode 100644 (file)
index 0000000..6c2e0e5
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef __DATA_HXX__
+#define __DATA_HXX__
+
+#include "define.hxx"
+#include "ContentOfDataFlow.hxx"
+#include "ConversionException.hxx"
+#include <string>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    /**
+     *
+     * Manage Data exchanged through dataflow pipe between 2 nodes. This class minimizes duplications of data.
+     * WARNING : Data has a type defined on constructor or after having called edSetNewType method.
+     *          All the methods that change the content of data check the validity regarding _edType attribute.
+     *
+     */
+    class Data
+    {
+    private:
+      DynType _edType;
+      ContentOfDataFlow::Type _exContent;
+      static const char Data::UNRECOGNIZEDTYPENAME[];
+    public:
+      Data(DynType typeOfContent);
+      Data(const std::string& content, DynType typeOfContent) throw(Exception);
+      template<class T>
+      Data(T val);
+      Data(const Data& other);
+      ~Data();
+      Data &operator =(const Data& other) throw(ConversionException);
+      template<class T>
+      Data &operator =(T val) throw(ConversionException);
+      std::string edGetRepresentation() const;
+      void edSetNewType(DynType newTypeOfContent) throw(ConversionException);
+      void exSetContent(const std::string& content) throw(ConversionException);
+      template<class T>
+      T exGet() const throw(ConversionException);
+      void edInitToType(DynType typeOfContent);
+      void exInit();
+      DynType edGetType() const { return _edType; }
+      static std::string edGetTypeInPrintableForm(DynType type);
+      bool isStaticallyCompatibleWith(const Data& other) const throw(Exception);
+      static bool areStaticallyCompatible(DynType type1, DynType type2) throw(Exception);
+      bool empty() const;
+    };
+
+    template<class T>
+    Data::Data(T val)
+    {
+      _edType=TypeDescriptorTraitsInv<T>::_typeEnum;
+      _exContent=ContentOfDataFlow::createNewContent(val);
+    }
+
+    template<class T>
+    Data &Data::operator =(T val) throw(ConversionException)
+    {
+      ContentOfDataFlow::release(_exContent);
+      typename ContentOfDataFlow::Type content=ContentOfDataFlow::createNewContent(val);
+      if(_edType==TypeDescriptorTraitsInv<T>::_typeEnum)
+       {
+         _exContent=content;
+       }
+      else
+       {
+         _exContent=ContentOfDataFlow::convertContent(content,TypeDescriptorTraitsInv<T>::_typeEnum,_edType);
+         ContentOfDataFlow::release(content);
+       }
+      return *this;
+    }
+    
+    template<class T>
+    T Data::exGet() const throw(ConversionException)
+    {
+      T ret;
+      ContentOfDataFlow::readContent(_exContent,ret);
+      return ret;
+    }
+  }
+}
+
+#endif
diff --git a/src/basicData/Makefile.am b/src/basicData/Makefile.am
new file mode 100644 (file)
index 0000000..723ae28
--- /dev/null
@@ -0,0 +1,26 @@
+
+include $(top_srcdir)/adm/unix/make_begin.am
+
+SUBDIRS = Test
+
+lib_LTLIBRARIES = libYACSBasicData.la
+
+libYACSBasicData_la_SOURCES =      \
+       Data.cxx                   \
+       ContentOfDataFlow.cxx      \
+       ConversionException.cxx    \
+       TypeCheckerDataFlow.cxx    \
+       TypeCheckerDataStream.cxx  \
+       $(__dummy__)
+
+EXTRA_libYACSBasicData_la_SOURCES =  \
+       Data.hxx                     \
+       $(__dummy__)
+
+libYACSBasicData_la_LIBADD = ../bases/libYACSBases.la
+
+AM_CXXFLAGS = $(THREAD_DEF) \
+              -I$(srcdir)/../bases \
+              -D__OLD_GCC__
+
+include $(top_srcdir)/adm/unix/make_end.am
diff --git a/src/basicData/Test/Makefile.am b/src/basicData/Test/Makefile.am
new file mode 100644 (file)
index 0000000..484d063
--- /dev/null
@@ -0,0 +1,21 @@
+
+include $(top_srcdir)/adm/unix/make_begin.am
+
+       $(__dummy__)
+
+check_PROGRAMS = testData
+
+testData_SOURCES = testData.cxx
+
+testData_LDADD = ../libYACSBasicData.la \
+                 ../../bases/libYACSBases.la
+
+testData_LDFLAGS = $(CPPUNIT_LIBS) -pthread -ldl
+
+testData_CXXFLAGS = $(CPPUNIT_INCLUDES)       \
+                    -I$(srcdir)/..            \
+                    -I$(srcdir)/../../bases
+
+TESTS = testData
+
+include $(top_srcdir)/adm/unix/make_end.am
diff --git a/src/basicData/Test/testData.cxx b/src/basicData/Test/testData.cxx
new file mode 100644 (file)
index 0000000..b8dee37
--- /dev/null
@@ -0,0 +1,118 @@
+#include "Data.hxx"
+//
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <sstream>
+//
+
+using namespace YACS::ENGINE;
+
+class DataTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( DataTest );
+  CPPUNIT_TEST( test1 );
+  CPPUNIT_TEST( test2 );
+  CPPUNIT_TEST( test3 );
+  CPPUNIT_TEST( test4 );
+  CPPUNIT_TEST_EXCEPTION( test5, YACS::ENGINE::ConversionException);
+  CPPUNIT_TEST( test6 );
+  CPPUNIT_TEST( testStaticCheckType );
+  CPPUNIT_TEST_SUITE_END();
+public: 
+  void tearDown();
+  void test1();
+  void test2();
+  void test3();
+  void test4();
+  void test5();
+  void test6();
+  void testStaticCheckType();
+};
+
+void DataTest::tearDown()
+{
+}
+
+void DataTest::test1()
+{
+  Data d1(YACS::Double),d2(YACS::Int),d3(YACS::Bool);
+  d1=3.14; d3=d2=d1;
+  CPPUNIT_ASSERT( d1.edGetRepresentation() == "41_3.14" );
+  CPPUNIT_ASSERT( d2.edGetRepresentation() == "42_3" );
+  CPPUNIT_ASSERT( d3.edGetRepresentation() == "45_1" );
+}
+
+void DataTest::test2()
+{
+  Data d1("2.78",YACS::Double);
+  d1.edSetNewType(YACS::Int);
+  CPPUNIT_ASSERT( d1.edGetRepresentation() == "42_2" );
+  d1.edSetNewType(YACS::Bool);
+  CPPUNIT_ASSERT( d1.edGetRepresentation() == "45_1" );
+  d1.edInitToType(YACS::String);
+  CPPUNIT_ASSERT( d1.edGetRepresentation() == "44_NULL" );
+}
+
+void DataTest::test3()
+{
+  Data d1("2.78",YACS::Double);
+  CPPUNIT_ASSERT( d1.edGetRepresentation() == "41_2.78" );
+  d1.exSetContent("4.14e3");
+  CPPUNIT_ASSERT( d1.edGetRepresentation() == "41_4140" );
+  d1.exSetContent("-4.9995");
+  CPPUNIT_ASSERT( d1.edGetRepresentation() == "41_-4.9995" );
+}
+
+void DataTest::test4()
+{
+  Data d1(6.279),d2(67), d3(false), d4(std::string("coucou"));
+  CPPUNIT_ASSERT( d1.edGetRepresentation() == "41_6.279" );
+  CPPUNIT_ASSERT( d2.edGetRepresentation() == "42_67" );
+  CPPUNIT_ASSERT( Data::edGetTypeInPrintableForm(d1.edGetType()) == "Double" );
+  CPPUNIT_ASSERT( d3.edGetRepresentation() == "45_0" );
+  CPPUNIT_ASSERT( Data::edGetTypeInPrintableForm(d3.edGetType()) == "Bool" );
+  CPPUNIT_ASSERT( d4.edGetRepresentation() == "44_coucou" );
+  CPPUNIT_ASSERT( Data::edGetTypeInPrintableForm(d4.edGetType()) == "String" );
+}
+
+void DataTest::test5()
+{
+  Data d1("2.78",YACS::Double);
+  d1=std::string("coucou");
+}
+
+void DataTest::test6()
+{
+  Data d1("2.78",YACS::Double);
+  Data d2("3.14",YACS::Double);
+  CPPUNIT_ASSERT( d1.edGetRepresentation() == "41_2.78" );
+  CPPUNIT_ASSERT( d2.edGetRepresentation() == "41_3.14" );
+  d1=d2;
+  Data d3(d1);
+  Data d4=d1;
+  CPPUNIT_ASSERT( d1.edGetRepresentation() == "41_3.14" );
+  CPPUNIT_ASSERT( d3.edGetRepresentation() == "41_3.14" );
+  CPPUNIT_ASSERT( d4.edGetRepresentation() == "41_3.14" );
+  d3.edInitToType(YACS::Int);
+  CPPUNIT_ASSERT( d3.empty() );
+  CPPUNIT_ASSERT( Data::edGetTypeInPrintableForm(d3.edGetType()) == "Int" );
+}
+
+void DataTest::testStaticCheckType()
+{
+  Data d1("2.78",YACS::Double);
+  Data d2("3.14",YACS::Double);
+  CPPUNIT_ASSERT( d1.isStaticallyCompatibleWith(d2) );
+  d1.edInitToType(YACS::Int);
+  CPPUNIT_ASSERT( d1.isStaticallyCompatibleWith(d2) );
+  d1.edInitToType(YACS::Bool);
+  CPPUNIT_ASSERT( !d1.isStaticallyCompatibleWith(d2) );
+}
+
+int main()
+{
+  CppUnit::TextUi::TestRunner runner;
+  runner.addTest( DataTest::suite() );
+  runner.run();
+  return 0;
+}
diff --git a/src/basicData/TypeCheckerDataFlow.cxx b/src/basicData/TypeCheckerDataFlow.cxx
new file mode 100644 (file)
index 0000000..a54f960
--- /dev/null
@@ -0,0 +1,11 @@
+#include "TypeCheckerDataFlow.hxx"
+
+using namespace YACS::ENGINE;
+
+const char TypeDescriptorTraits<YACS::Double>::_name[]="Double";
+   
+const char TypeDescriptorTraits<YACS::Int>::_name[]="Int";
+    
+const char TypeDescriptorTraits<YACS::Bool>::_name[]="Bool";
+    
+const char TypeDescriptorTraits<YACS::String>::_name[]="String";
diff --git a/src/basicData/TypeCheckerDataFlow.hxx b/src/basicData/TypeCheckerDataFlow.hxx
new file mode 100644 (file)
index 0000000..b260946
--- /dev/null
@@ -0,0 +1,332 @@
+#ifndef __TYPECHECKERDATAFLOW_HXX__
+#define __TYPECHECKERDATAFLOW_HXX__
+
+#include "define.hxx"
+#include "ConversionException.hxx"
+
+#include <string>
+#include <sstream>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    /**
+     *
+     * @ note : container in all this file is a concept that stores any data of any data into container::Type type.
+     *          container concept must at least implement
+     *                 - createNewContent method
+     *                 - readContent method
+     *          and container must define Type class that stores data independently of type.
+     *          ContentOfDataFlow is one class fulfilling this concept !
+     *
+     */
+    template< template< DynType type> class TREATMENTPERTYPE >
+    class DynToStaticTypeDispatcher1
+    {
+    public:
+      template<class  T, class U>
+      static void perform(YACS::DynType myTypeDyn, T input, U& output) throw(Exception)
+      {
+       switch(myTypeDyn)
+         {
+         case Double:
+           TREATMENTPERTYPE<Double>::perform(input, output);
+           break;
+         case Int:
+           TREATMENTPERTYPE<Int>::perform(input, output);
+           break;
+         case String:
+           TREATMENTPERTYPE<String>::perform(input, output);
+           break;
+         case Bool:
+           TREATMENTPERTYPE<Bool>::perform(input, output);
+           break;
+         default:
+           throw Exception("Unknow type enum");
+         }
+      }
+    };
+
+    template< template< DynType fromType, DynType toType> class TREATMENTPERTYPE >
+    class DynToStaticTypeDispatcher2
+    {
+      template<DynType toType> class TREATMENTPERTYPEDOUBLE : public TREATMENTPERTYPE<Double,toType> { };
+      template<DynType toType> class TREATMENTPERTYPEINT : public TREATMENTPERTYPE<Int,toType> { };
+      template<DynType toType> class TREATMENTPERTYPEBOOL : public TREATMENTPERTYPE<Bool,toType> { };
+      template<DynType toType> class TREATMENTPERTYPESTRING : public TREATMENTPERTYPE<String,toType> { };
+    public:
+      template<class  T, class U>
+      static void perform(YACS::DynType myTypeDynFrom, YACS::DynType myTypeDynTo, T input, U& output) throw(Exception)
+      {
+       switch(myTypeDynFrom)
+         {
+         case Double:
+#ifndef __OLD_GCC__
+           DynToStaticTypeDispatcher1<TREATMENTPERTYPEDOUBLE>::perform(myTypeDynTo, input, output);
+#else
+           switch(myTypeDynTo)
+             {
+             case Double:
+               TREATMENTPERTYPE<Double,Double>::perform(input, output);
+               break;
+             case Int:
+               TREATMENTPERTYPE<Double,Int>::perform(input, output);
+               break;
+             case String:
+               TREATMENTPERTYPE<Double,String>::perform(input, output);
+               break;
+             case Bool:
+               TREATMENTPERTYPE<Double,Bool>::perform(input, output);
+               break;
+             default:
+               throw Exception("Unknow type enum");
+             }
+#endif
+           break;
+         case Int:
+#ifndef __OLD_GCC__
+           DynToStaticTypeDispatcher1<TREATMENTPERTYPEINT>::perform(myTypeDynTo, input, output);
+#else
+           switch(myTypeDynTo)
+             {
+             case Double:
+               TREATMENTPERTYPE<Int,Double>::perform(input, output);
+               break;
+             case Int:
+               TREATMENTPERTYPE<Int,Int>::perform(input, output);
+               break;
+             case String:
+               TREATMENTPERTYPE<Int,String>::perform(input, output);
+               break;
+             case Bool:
+               TREATMENTPERTYPE<Int,Bool>::perform(input, output);
+               break;
+             default:
+               throw Exception("Unknow type enum");
+             }
+#endif
+           break;
+         case String:
+#ifndef __OLD_GCC__
+           DynToStaticTypeDispatcher1<TREATMENTPERTYPESTRING>::perform(myTypeDynTo, input, output);
+#else
+           switch(myTypeDynTo)
+             {
+             case Double:
+               TREATMENTPERTYPE<String,Double>::perform(input, output);
+               break;
+             case Int:
+               TREATMENTPERTYPE<String,Int>::perform(input, output);
+               break;
+             case String:
+               TREATMENTPERTYPE<String,String>::perform(input, output);
+               break;
+             case Bool:
+               TREATMENTPERTYPE<String,Bool>::perform(input, output);
+               break;
+             default:
+               throw Exception("Unknow type enum");
+             }
+#endif
+           break;
+         case Bool:
+#ifndef __OLD_GCC__
+           DynToStaticTypeDispatcher1<TREATMENTPERTYPESTRING>::perform(myTypeDynTo, input, output);
+#else
+           switch(myTypeDynTo)
+             {
+             case Double:
+               TREATMENTPERTYPE<Bool,Double>::perform(input, output);
+               break;
+             case Int:
+               TREATMENTPERTYPE<Bool,Int>::perform(input, output);
+               break;
+             case String:
+               TREATMENTPERTYPE<Bool,String>::perform(input, output);
+               break;
+             case Bool:
+               TREATMENTPERTYPE<Bool,Bool>::perform(input, output);
+               break;
+             default:
+               throw Exception("Unknow type enum");
+             }
+#endif
+           break;
+         default:
+           throw Exception("Unknow type enum");
+         }
+      }
+    };
+
+    template<YACS::DynType baseTyp>
+    class TypeDescriptorTraits
+    {
+    };
+
+    template<class T>
+    class TypeDescriptorTraitsInv
+    {
+    };
+
+    template<>
+    class TypeDescriptorTraits<YACS::Double>
+    {
+    public:
+      typedef double ConcreteType;
+      static const char _name[];
+    };
+
+    template<>
+    class TypeDescriptorTraitsInv<double>
+    {
+    public:
+      static const YACS::DynType _typeEnum=Double;
+    };
+
+    template<>
+    class TypeDescriptorTraits<YACS::Int>
+    {
+    public:
+      typedef int ConcreteType;
+      static const char _name[];
+    };
+
+    template<>
+    class TypeDescriptorTraitsInv<int>
+    {
+    public:
+      static const YACS::DynType _typeEnum=Int;
+    };
+
+    template<>
+    class TypeDescriptorTraits<YACS::Bool>
+    {
+    public:
+      typedef bool ConcreteType;
+      static const char _name[];
+    };
+
+    template<>
+    class TypeDescriptorTraitsInv<bool>
+    {
+    public:
+      static const YACS::DynType _typeEnum=Bool;
+    };
+
+    template<>
+    class TypeDescriptorTraits<YACS::String>
+    {
+    public:
+      typedef std::string ConcreteType;
+      static const char _name[];
+    };
+
+    template<>
+    class TypeDescriptorTraitsInv<std::string>
+    {
+    public:
+      static const YACS::DynType _typeEnum=String;
+    };
+
+    /**
+     *
+     * This class has the responsability of the validity of the content of data regarding only statically its types from and to.
+     *
+     */
+    template<DynType fromType, DynType toType >
+    class StaticTypeConverter
+    {
+    public:
+      enum { _staticallyCompatible=0 };
+      static typename TypeDescriptorTraits<toType>::ConcreteType traduce(typename TypeDescriptorTraits<fromType>::ConcreteType input) throw(ConversionException)
+      {
+       throw ConversionException(TypeDescriptorTraits<fromType>::_name, TypeDescriptorTraits<toType>::_name);
+      }
+    };
+
+    //Specialisation of the previously declared StaticTypeConverter class when 'fromType' and 'toType' are equal.
+    template<DynType aType>
+    class StaticTypeConverter<aType, aType>
+    {
+    public:
+      enum { _staticallyCompatible=1 };
+      static typename TypeDescriptorTraits<aType>::ConcreteType traduce(typename TypeDescriptorTraits<aType>::ConcreteType input) throw(ConversionException)
+      {
+       return input;
+      }
+    };
+
+    template<>
+    class StaticTypeConverter<YACS::Double, YACS::Int>
+    {
+    public:
+      enum { _staticallyCompatible=1 };
+      static TypeDescriptorTraits<YACS::Int>::ConcreteType traduce(TypeDescriptorTraits<YACS::Double>::ConcreteType input) throw(ConversionException)
+      {
+       return (TypeDescriptorTraits<YACS::Int>::ConcreteType) input;
+      }
+    };
+
+    template<>
+    class StaticTypeConverter<YACS::Int, YACS::Double>
+    {
+    public:
+      enum { _staticallyCompatible=1 };
+      static TypeDescriptorTraits<YACS::Double>::ConcreteType traduce(TypeDescriptorTraits<YACS::Int>::ConcreteType input) throw(ConversionException)
+      {
+       return (TypeDescriptorTraits<YACS::Double>::ConcreteType) input;
+      }
+    };
+
+    template<>
+    class StaticTypeConverter<YACS::Int, YACS::Bool>
+    {
+    public:
+      enum { _staticallyCompatible=1 };
+      static TypeDescriptorTraits<YACS::Bool>::ConcreteType traduce(TypeDescriptorTraits<YACS::Int>::ConcreteType input) throw(ConversionException)
+      {
+       if(input!=0)
+         return true;
+       else
+         return false;
+      }
+    };
+
+    template<>
+    class StaticTypeConverter<YACS::Bool, YACS::Int>
+    {
+    public:
+      enum { _staticallyCompatible=1 };
+      static TypeDescriptorTraits<YACS::Int>::ConcreteType traduce(TypeDescriptorTraits<YACS::Bool>::ConcreteType input) throw(ConversionException)
+      {
+       if(input)
+         return 1;
+       else
+         return 0;
+      }
+    };
+
+    /**
+     *
+     * This class has the responsability of the validity of the content of data regarding statically and dynamically its types from and to.
+     *
+     */
+    template<class container, DynType fromType, DynType toType >
+    class StaticAndDynamicTypeConverter
+    {
+    public:
+      static typename container::Type convert(typename container::Type source) throw(ConversionException)
+      {
+       if(!StaticTypeConverter<fromType, toType>::_staticallyCompatible)
+         throw ConversionException(TypeDescriptorTraits<fromType>::_name, TypeDescriptorTraits<toType>::_name);
+       typename TypeDescriptorTraits<fromType>::ConcreteType sourceValue;
+       container::readContent(source,sourceValue);
+       typename TypeDescriptorTraits<toType>::ConcreteType targetValue=StaticTypeConverter<fromType, toType>::traduce(sourceValue);
+       return container::createNewContent(targetValue);
+      }
+    };
+  }
+}
+
+#endif
diff --git a/src/basicData/TypeCheckerDataStream.cxx b/src/basicData/TypeCheckerDataStream.cxx
new file mode 100644 (file)
index 0000000..977c9f8
--- /dev/null
@@ -0,0 +1,127 @@
+#include "TypeCheckerDataStream.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    template< template< StreamType type> class TREATMENTPERTYPE >
+    class DynToStaticStreamTypeDispatcher1
+    {
+    public:
+      template<class  T, class U>
+      static void perform(YACS::StreamType myTypeDyn, T input, U& output) throw(Exception)
+      {
+       switch(myTypeDyn)
+         {
+         case SDouble:
+           TREATMENTPERTYPE<SDouble>::perform(input, output);
+           break;
+         default:
+           throw Exception("Unknow stream type enum");
+         }
+      }
+    };
+
+    template< template< StreamType fromType, StreamType toType> class TREATMENTPERTYPE >
+    class DynToStaticStreamTypeDispatcher2
+    {
+      template<StreamType toType> class TREATMENTPERTYPESDOUBLE : public TREATMENTPERTYPE<SDouble,toType> { };
+    public:
+      template<class  T, class U>
+      static void perform(YACS::StreamType myTypeDynFrom, YACS::StreamType myTypeDynTo, T input, U& output) throw(Exception)
+      {
+       switch(myTypeDynFrom)
+         {
+         case SDouble:
+           DynToStaticStreamTypeDispatcher1<TREATMENTPERTYPESDOUBLE>::perform(myTypeDynTo, input, output);
+           break;
+         default:
+           throw Exception("Unknow stream type enum");
+         }
+      }
+    };
+
+    template<YACS::StreamType baseTyp>
+    class StreamTypeDescriptorTraits
+    {
+    };
+
+    template<>
+    class StreamTypeDescriptorTraits<YACS::SDouble>
+    {
+    public:
+      static const char _name[];
+    };
+
+    /**
+     *
+     * This class has the responsability of the validity of the content of stream data regarding only statically its types from and to.
+     *
+     */
+    template< StreamType fromType, StreamType toType >
+    class StaticStreamTypeConverter
+    {
+    public:
+      enum { _staticallyCompatible=0 };
+    };
+
+    template<StreamType type>
+    class StaticStreamTypeConverter<type,type>
+    {
+    public:
+      enum { _staticallyCompatible=1 };
+    };
+  }
+}
+
+using namespace YACS::ENGINE;
+
+const char StreamTypeDescriptorTraits<YACS::SDouble>::_name[]="SDouble";
+
+const char TypeCheckerDataStream::UNRECOGNIZEDTYPENAME[]="Unrecognized type";
+
+//Part of TypeCheckerDataStream::areStaticallyCompatible implementation
+template< YACS::StreamType fromType, YACS::StreamType toType >
+class TreatmentToCheckStaticallyTypes
+{
+public:
+  static void perform(int input, bool& ret)
+  {
+    ret=StaticStreamTypeConverter<fromType,toType>::_staticallyCompatible;
+  }
+};
+
+bool TypeCheckerDataStream::areStaticallyCompatible(YACS::StreamType type1, YACS::StreamType type2) throw(Exception)
+{
+  bool ret;
+  int fake;
+  //DynToStaticStreamTypeDispatcher2<TreatmentToCheckStaticallyTypes>::perform(type1, type2, fake, ret);
+  return ret;
+}
+
+// Part of TypeCheckerDataStream::edGetTypeInPrintableForm implementation
+
+template< YACS::StreamType type >
+class TreatmentForNameOfStreamType
+{
+public:
+  static void perform(int input, std::string& ret)
+  {
+    ret=StreamTypeDescriptorTraits<type>::_name;
+  }
+};
+
+std::string TypeCheckerDataStream::edGetTypeInPrintableForm(YACS::StreamType type)
+{
+  try
+    {
+      int fake1;
+      std::string ret;
+      DynToStaticStreamTypeDispatcher1< TreatmentForNameOfStreamType >::perform(type, fake1, ret);
+      return ret;
+    }
+  catch(Exception& e)
+    {
+      return UNRECOGNIZEDTYPENAME;
+    }
+}
diff --git a/src/basicData/TypeCheckerDataStream.hxx b/src/basicData/TypeCheckerDataStream.hxx
new file mode 100644 (file)
index 0000000..8954922
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef __TYPECHECKERDATASTREAM_HXX__
+#define __TYPECHECKERDATASTREAM_HXX__
+
+#include "define.hxx"
+#include "Exception.hxx"
+
+#include <string>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class TypeCheckerDataStream
+    {
+    public:
+      static bool areStaticallyCompatible(YACS::StreamType type1, YACS::StreamType type2) throw(Exception);
+      static std::string edGetTypeInPrintableForm(YACS::StreamType type);
+    private:
+      static const char UNRECOGNIZEDTYPENAME[];
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/Bloc.cxx b/src/engine/Bloc.cxx
new file mode 100644 (file)
index 0000000..e02d459
--- /dev/null
@@ -0,0 +1,220 @@
+#include "Bloc.hxx"
+#include "ElementaryNode.hxx"
+
+using namespace YACS::ENGINE;
+
+Bloc::Bloc(const std::string& name):ComposedNode(name)
+{
+}
+
+Bloc::~Bloc()
+{
+  for(std::list<Node *>::iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++)
+    delete *iter;
+}
+
+void Bloc::init()
+{
+  for(std::list<Node *>::iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++)
+    (*iter)->init();
+  if(_inGate.exIsReady())
+    _state=YACS::TOACTIVATE;
+  else
+    _state=YACS::INITED;
+}
+
+bool Bloc::isFinished()
+{
+  return _state==YACS::DONE;
+}
+
+int Bloc::getNumberOfCFLinks() const
+{
+  int ret=0;
+  for(std::list<Node *>::const_iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++)
+    {
+      ret+=(*iter)->getOutGate()->getNbOfInGatesConnected();
+    }
+  return ret;
+}
+
+std::vector<Task *> Bloc::getNextTasks(bool& isMore)
+{
+  std::vector<Task *> ret;
+  isMore=false;
+  if(_state==YACS::DONE || _state==YACS::INITED)
+    return ret;
+  for(std::list<Node *>::iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++)
+    (*iter)->getReadyTasks(ret);
+  isMore=!ret.empty();
+  return ret;
+}
+
+void Bloc::getReadyTasks(std::vector<Task *>& tasks)
+{
+  if(_state==YACS::TOACTIVATE || _state==YACS::ACTIVATED)
+    for(std::list<Node *>::iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++)
+      (*iter)->getReadyTasks(tasks);
+}
+
+std::list<ElementaryNode *> Bloc::getRecursiveConstituents()
+{
+  std::list<ElementaryNode *> ret;
+  for(std::list<Node *>::iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++)
+    {
+      std::list<ElementaryNode *> myCurrentList=(*iter)->getRecursiveConstituents();
+      ret.insert(ret.begin(),myCurrentList.begin(),myCurrentList.end());
+    }
+  return ret;
+}
+
+/**
+ * @ note : Update the '_state' attribute.
+ *          Typically called by 'this->_inGate' when 'this->_inGate' is ready. Contrary to Node::exUpdateState no check done on inputs
+ *          because internal linked DF inputports are not valid yet.
+ */
+void Bloc::exUpdateState()
+{
+  if(_inGate.exIsReady())
+    _state=YACS::TOACTIVATE;
+}
+
+bool Bloc::edAddChild(Node *node) throw(Exception)
+{
+  if(isNodeAlreadyAggregated(node))
+    {
+      if(node->_father==this)
+       return false;
+      else
+       throw Exception("Bloc::edAddChild : Internal error occured");
+    }
+  if(node->_father)
+    throw Exception("Bloc::edAddChild : node is not orphan");
+  if(isNameAlreadyUsed(node->getName()))
+    {
+      std::string what("Bloc::edAddChild : name "); what+=node->getName(); what+=" already exists in the scope of "; what+=_name;
+      throw Exception(what);
+    }
+  node->_father=this;
+  _listOfNode.push_back(node);
+  return true;
+}
+
+/**
+ * @ note : Remove 'node' from the list of direct children.
+ *          WARNING 1 : node is destroyed after invocation of this method because Bloc class has ownership of its child nodes.
+ *          WARNING 2 : all links to 'node' are automatically desactivated. As consequence this method is quite heavy for big graphs due to
+ *                      unilateral storing policy of links. 
+ * @ exception : If 'node' is NOT the direct son of 'this'.
+ *
+ */
+void Bloc::edRemoveChild(Node *node) throw(Exception)
+{
+  if(node->_father!=this)
+    throw Exception("Bloc::edRemoveChild : node is NOT managed by this");
+  if(!isNodeAlreadyAggregated(node))
+    throw Exception("Bloc::edRemoveChild : Internal error occured");
+  ComposedNode *myRootNode=getRootNode();
+  myRootNode->disconnectAllLinksConnectedTo(node);
+  _listOfNode.remove(node);
+  delete node;
+}
+
+void Bloc::selectRunnableTasks(std::vector<Task *>& tasks)
+{
+}
+
+bool Bloc::areAllSubNodesFinished() const
+{
+  bool ret=true;
+  for(std::list<Node *>::const_iterator iter=_listOfNode.begin();iter!=_listOfNode.end() && ret;iter++)
+    if((*iter)->_state!=YACS::DONE)
+      ret=false;
+  return ret;
+}
+
+bool Bloc::isNodeAlreadyAggregated(Node *node) const
+{
+  for(std::list<Node *>::const_iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++)
+    {
+      if((*iter)==node)
+       return true;
+    }
+  return false;
+}
+
+bool Bloc::isNameAlreadyUsed(const std::string& name) const
+{
+  for(std::list<Node *>::const_iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++)
+      if((*iter)->getName()==name)
+       return true;
+  return false;
+}
+
+/**
+ * @ note : Checks that in the forest from 'node' there are NO back-edges.
+ *          WARNING : When using this method 'node' has to be checked in order to be part of direct children of 'this'. 
+ *
+ */
+void Bloc::checkNoCyclePassingThrough(Node *node) throw(Exception)
+{
+  initChildrenForDFS();
+  node->_colour=YACS::Grey;
+  bool verdict=true;
+  std::list<Node *> currentNodesToTest;
+  currentNodesToTest.push_back(node);
+  for(std::list<Node *>::iterator iter1=currentNodesToTest.begin();iter1!=currentNodesToTest.end() && verdict;)
+    {
+      std::list<Node *> outNodes=(*iter1)->getOutNodes();
+      for(std::list<Node *>::iterator iter2=outNodes.begin();iter2!=outNodes.end() && verdict;iter2++)
+       if((*iter2)->_colour==YACS::White)
+         {
+           currentNodesToTest.push_back(*iter2);
+           (*iter2)->_colour=YACS::Grey;
+         }
+       else
+         verdict=false;
+      iter1=currentNodesToTest.erase(iter1);
+    }
+  if(!verdict)
+    throw Exception("Cycle has been detected");
+}
+
+void Bloc::initChildrenForDFS() const
+{
+  for(std::list<Node *>::const_iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++)
+    (*iter)->initForDFS();
+}
+
+/**
+ *
+ * @ note : Runtime called method. Indirectly called by ComposedNode::updateStateFrom which has dispatch to this method
+ *          'when event == START'.
+ *          WARNING Precondition : '_state == Running' and 'node->_father==this'(garanteed by ComposedNode::notifyFrom)
+ *
+ */
+YACS::Event Bloc::updateStateOnStartEventFrom(Node *node)
+{
+  _state=YACS::ACTIVATED;
+  return YACS::START;
+}
+
+/**
+ *
+ * @ note : Runtime called method. Indirectly called by ComposedNode::updateStateFrom which has dispatch to this method
+ *          'when event == FINISH'.
+ *          WARNING Precondition : '_state == Running' and 'node->_father==this'(garanteed by ComposedNode::notifyFrom)
+ *
+ */
+YACS::Event Bloc::updateStateOnFinishedEventFrom(Node *node)
+{
+  //ASSERT(node->_father==this)
+  if(areAllSubNodesFinished())
+    {
+      _state=YACS::DONE;
+      return YACS::FINISH;//notify to father node that 'this' has becomed finished.
+    }
+  //more job to do in 'this'
+  node->_outGate.exNotifyDone();
+  return YACS::NOEVENT;//no notification to father needed because from father point of view nothing happened.
+}
diff --git a/src/engine/Bloc.hxx b/src/engine/Bloc.hxx
new file mode 100644 (file)
index 0000000..1f0f15c
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef __BLOC_HXX__
+#define __BLOC_HXX__
+
+#include "ComposedNode.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Bloc : public ComposedNode
+    {
+    protected:
+      std::list<Node *> _listOfNode;//OWNERSHIP OF ALL NODES
+    public:
+      Bloc(const std::string& name);
+      ~Bloc();
+      void init();
+      bool isFinished();
+      int getNumberOfCFLinks() const;
+      std::vector<Task *> getNextTasks(bool& isMore);
+      void getReadyTasks(std::vector<Task *>& tasks);
+      std::list<ElementaryNode *> getRecursiveConstituents();
+      void exUpdateState();
+      bool edAddChild(Node *node) throw(Exception);
+      void edRemoveChild(Node *node) throw(Exception);
+      std::list<Node *> getChildren() { return _listOfNode; }
+      void selectRunnableTasks(std::vector<Task *>& tasks);
+    protected:
+      bool areAllSubNodesFinished() const;
+      bool isNodeAlreadyAggregated(Node *node) const;
+      bool isNameAlreadyUsed(const std::string& name) const;
+      void checkNoCyclePassingThrough(Node *node) throw(Exception);
+      YACS::Event updateStateOnStartEventFrom(Node *node);
+      YACS::Event updateStateOnFinishedEventFrom(Node *node);
+    private:
+      void initChildrenForDFS() const;
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/ComposedNode.cxx b/src/engine/ComposedNode.cxx
new file mode 100644 (file)
index 0000000..10359d1
--- /dev/null
@@ -0,0 +1,288 @@
+#include "ComposedNode.hxx"
+#include "InputPort.hxx"
+#include "OutputPort.hxx"
+#include "ElementaryNode.hxx"
+
+#include <set>
+
+using namespace YACS::ENGINE;
+
+ComposedNode::ComposedNode(const std::string& name):Node(name)
+{
+}
+
+/**
+ *
+ * @ note : Runtime called method. Overloads the Scheduler::notifyFrom abstract method. Typically Called in Executor (in a parallel thread or not) by the Task 'task'
+ *          to inform the scheduler that an event coded 'event' (in Executor static const var) happened. Contrary to updateStateFrom several level may exist between 'sender' and 'this'.
+ *
+ */
+void ComposedNode::notifyFrom(const Task *sender, //* I : task emitting event
+                             YACS::Event event   //* I : event emitted
+                             )
+{
+  ElementaryNode *taskTyped=dynamic_cast<ElementaryNode *>((Task *)sender);
+  //ASSERT(taskTyped != 0)
+  YACS::Event curEvent=event;
+  Node *lminus1LevelNode=taskTyped;
+  ComposedNode *curLevelNode=taskTyped->_father;
+  curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent);
+  while(curEvent!=YACS::NOEVENT && curLevelNode!=this)
+    {
+      lminus1LevelNode=curLevelNode;
+      curLevelNode=curLevelNode->_father;
+      curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent);
+    }
+}
+
+/**
+ * @ note : Add a dataflow link.
+ *          Precondition : 'start' AND 'end' are in/outputPort contained in a node in descendance of 'this'.
+ * @ exception : incompatibility between input and output (type), or 'start'/'end' is/are NOT in/outputPort
+ *               contained in a node in descendance of 'this', or a mutilple link to an input not supporting it.
+ * @ return : true if a new link has been created, false otherwise.
+ */
+bool ComposedNode::edAddLink(OutputPort *start, InputPort *end) throw(Exception)
+{
+  ComposedNode* lwstCmnAnctr=getLowestCommonAncestor(start->getNode(),end->getNode());
+  std::list<ComposedNode *> allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr);
+  std::list<ComposedNode *> allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr);
+  checkInMyDescendance(lwstCmnAnctr);
+  ComposedNode *iterS=start->getNode()->_father;
+  OutPort *currentPortO=start;
+  while(iterS!=lwstCmnAnctr)
+    {
+      currentPortO=iterS->buildDelegateOf(currentPortO, allAscendanceOfNodeEnd);
+      iterS=iterS->_father;
+    }
+  iterS=end->getNode()->_father;
+  InPort *currentPortI=end;
+  while(iterS!=lwstCmnAnctr)
+    {
+      currentPortI=iterS->buildDelegateOf(currentPortI, allAscendanceOfNodeEnd);
+      iterS=iterS->_father;
+    }
+  return currentPortO->addInPort(currentPortI);
+}
+
+/**
+ * @ note : Add a controlflow link.
+ *          Precondition : 'start' AND 'end' are in/outGate contained in a node in DIRECT descendance of 'this'.
+ * @ exception : If a cycle has been detected, or incompatibility between input and output, or 'start'/'end' is/are NOT in/outputPort
+ *               contained in a node in descendance of 'this', or a mutilple link to an input not supporting it.
+ * @ return : true if a new link has been created, false otherwise. 
+ */
+bool ComposedNode::edAddLink(OutGate *start, InGate *end) throw(Exception)
+{
+  ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode());
+  if(father!=this)
+    {
+      checkInMyDescendance(father);
+      return father->edAddLink(start,end);
+    }
+  bool ret=start->edAddInGate(end);
+  if(ret)
+    checkNoCyclePassingThrough(end->getNode());
+  return ret;
+}
+
+bool ComposedNode::edAddCFLink(Node *nodeS, Node *nodeE) throw(Exception)
+{
+  ComposedNode* father=checkHavingCommonFather(nodeS,nodeE);
+  if(father!=this)
+    {
+      checkInMyDescendance(father);
+      return father->edAddLink(nodeS->getOutGate(),nodeE->getInGate());
+    }
+  bool ret=nodeS->getOutGate()->edAddInGate(nodeE->getInGate());
+  if(ret)
+    checkNoCyclePassingThrough(nodeE);
+  return ret;
+}
+
+/**
+ * @ note : Remove a dataflow link.
+ *          Precondition : 'start' AND 'end' are in/outputPort contained in a node in descendance of 'this'.
+ * @ exception : The specified link does not exist. The content of Exception is different in accordance with the link from 'start' to 'end' implies DF/DS gateway.
+ */
+void ComposedNode::edRemoveLink(OutputPort *start, InputPort *end) throw(Exception)
+{
+  ComposedNode* lwstCmnAnctr=getLowestCommonAncestor(start->getNode(),end->getNode());
+  checkInMyDescendance(lwstCmnAnctr);
+  std::list<ComposedNode *> allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr);
+  std::list<ComposedNode *> allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr);
+  //Part of test if the link from 'start' to 'end' really exist particulary all eventually intermediate ports created
+  ComposedNode *iterS=start->getNode()->_father;
+  OutPort *currentPortO=start;
+  while(iterS!=lwstCmnAnctr)
+    {
+      currentPortO=iterS->getDelegateOf(currentPortO, allAscendanceOfNodeEnd);
+      iterS=iterS->_father;
+    }
+  iterS=end->getNode()->_father;
+  InPort *currentPortI=end;
+  while(iterS!=lwstCmnAnctr)
+    {
+      currentPortI=iterS->getDelegateOf(currentPortI, allAscendanceOfNodeStart);
+      iterS=iterS->_father;
+    }
+  //End of test for evt intermediate ports created
+  currentPortO->removeInPort(currentPortI);
+  //Performing deletion of intermediate ports
+  iterS=start->getNode()->_father;
+  currentPortO=start; currentPortI=end;
+  while(iterS!=lwstCmnAnctr)
+    {
+      currentPortO=iterS->releaseDelegateOf(currentPortO, allAscendanceOfNodeEnd);
+      iterS=iterS->_father;
+    }
+  iterS=end->getNode()->_father;
+  while(iterS!=lwstCmnAnctr)
+    {
+      currentPortI=iterS->releaseDelegateOf(currentPortI, allAscendanceOfNodeStart);
+      iterS=iterS->_father;
+    }
+}
+
+void ComposedNode::edRemoveLink(OutGate *start, InGate *end) throw(Exception)
+{
+  ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode());
+  if(father!=this)
+    throw Exception("edRemoveLink : nodes not in direct descendance of this");
+  start->edRemoveInGate(end);
+}
+
+void ComposedNode::publishOutputPort(OutputPort *port) throw(Exception)
+{
+  checkInMyDescendance(port->getNode());
+  _listOfOutputPort.push_back(port);
+}
+
+void ComposedNode::publishInputPort(InputPort *port)
+{
+  _listOfInputPort.push_back(port);
+}
+
+ComposedNode *ComposedNode::getRootNode() throw(Exception)
+{
+  if(!_father)
+    return this;
+  return Node::getRootNode();
+}
+
+/**
+ * @ note : perform the disconnection of all links under the scope of 'this' connected to an input (dataflow or datastream) of node 'node'.
+ *          This method is quite heavy because the links are stored in one direction.
+ */
+void ComposedNode::disconnectAllLinksConnectedTo(Node *node)
+{
+  std::list<ElementaryNode *> listOfAllNodes=getRecursiveConstituents();
+  for(std::list<ElementaryNode *>::iterator iter=listOfAllNodes.begin();iter!=listOfAllNodes.end();iter++)
+    (*iter)->disconnectAllLinksConnectedTo(node);
+}
+
+/**
+ * @ note : Check that 'nodeToTest' is in descendance of 'this' OR equal to 'this'
+ * @ exception : If 'nodeToTest' is NOT in descendance of 'this' AND not equal to 'this'
+ */
+void ComposedNode::checkInMyDescendance(Node *nodeToTest) const throw(Exception)
+{
+  const char what[]="check failed : node is not in the correct descendance";
+  if(nodeToTest==0)
+    throw Exception(what);
+  if((ComposedNode *)nodeToTest==this)
+    return;
+  ComposedNode *iter=nodeToTest->_father;
+  while(iter!=0 && iter!=this)
+    iter=iter->_father;
+  if(iter==0)
+    throw Exception(what);
+}
+
+/**
+ *
+ * @ note : Retrieves the lowest common ancestor of 'node1' AND 'node2'. If 'node1' AND 'node2' are equals and are instance of ComposedNode 
+ *          the father of 'node1' is returned.
+ * @ exception : 'node1' and 'node2' does not share the same genealogy.
+ * @ return : The lowest common ancestor if it exists.
+ *
+ */
+ComposedNode *ComposedNode::getLowestCommonAncestor(Node *node1, Node *node2) throw(Exception)
+{
+  const char what[]="2 nodes does not share the same genealogy";
+  if(node1==0 || node2==0)
+    throw Exception(what);
+  ComposedNode *temp=node1->_father;
+  std::set<ComposedNode *> s;
+  while(temp)
+    {
+      s.insert(temp);
+      temp=temp->_father;
+    }
+  //
+  temp=node2->_father;
+  std::set<ComposedNode *>::iterator iter=s.find(temp);
+  while(temp && iter==s.end())
+    {
+      iter=s.find(temp);
+      temp=temp->_father;
+    }
+  if(iter==s.end())
+    throw Exception(what);
+  return *iter;
+}
+
+/**
+ *
+ * @ note : Runtime called method. Perform, the state updating, from the son node 'node' emitting the event 'event' (among Executor static const var).
+ *          WARNING Precondition : this == node->_father
+ * @ return : The event (among Executor static const var) destinated to this->_father node to perform eventually up level update.
+ *
+ */
+YACS::Event ComposedNode::updateStateFrom(Node *node,        //* I : node emitting event
+                                         YACS::Event event  //* I : event emitted
+                                         )
+{
+  switch(event)
+    {
+    case YACS::START:
+      return updateStateOnStartEventFrom(node);
+      break;
+    case YACS::FINISH:
+      return updateStateOnFinishedEventFrom(node);
+      break;
+    default:
+      return YACS::NOEVENT;//TODO unexpected type of event
+      break;
+    }
+}
+
+InPort *ComposedNode::buildDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView)
+{
+  return port;
+}
+
+OutPort *ComposedNode::buildDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView)
+{
+  return port;
+}
+
+InPort *ComposedNode::getDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
+{
+  return port;
+}
+
+OutPort *ComposedNode::getDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
+{
+  return port;
+}
+
+InPort *ComposedNode::releaseDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
+{
+  return port;
+}
+
+OutPort *ComposedNode::releaseDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
+{
+  return port;
+}
diff --git a/src/engine/ComposedNode.hxx b/src/engine/ComposedNode.hxx
new file mode 100644 (file)
index 0000000..c24e601
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef __COMPOSEDNODE_HXX__
+#define __COMPOSEDNODE_HXX__
+
+#include "Node.hxx"
+#include "Scheduler.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Bloc;
+    class InPort;
+    class OutPort;
+    class ElementaryNode;
+    
+    class ComposedNode : public Node, public Scheduler
+    {
+      friend class Bloc;
+      friend class ElementaryNode;
+    protected:
+      ComposedNode(const std::string& name);
+    public:
+      void notifyFrom(const Task *sender, YACS::Event event);
+      bool edAddLink(OutputPort *start, InputPort *end) throw(Exception);
+      bool edAddLink(OutGate *start, InGate *end) throw(Exception);
+      bool edAddCFLink(Node *nodeS, Node *nodeE) throw(Exception);
+      void edRemoveLink(OutputPort *start, InputPort *end) throw(Exception);
+      void edRemoveLink(OutGate *start, InGate *end) throw(Exception);
+      virtual void publishOutputPort(OutputPort *port) throw(Exception);
+      virtual bool isRepeatedUnpredictablySeveralTimes() const { return false; }
+    protected:
+      ComposedNode *getRootNode() throw(Exception);
+      void disconnectAllLinksConnectedTo(Node *node);
+      virtual void publishInputPort(InputPort *port);
+      YACS::Event updateStateFrom(Node *node, YACS::Event event);//update the state of this. Precondition : node->_father == this
+      virtual YACS::Event updateStateOnStartEventFrom(Node *node) = 0;//transition 3 doc P.R
+      virtual YACS::Event updateStateOnFinishedEventFrom(Node *node) = 0;//transition 9 doc P.R.
+      virtual InPort *buildDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView);
+      virtual OutPort *buildDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView);
+      virtual InPort *getDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
+      virtual OutPort *getDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
+      virtual InPort *releaseDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
+      virtual OutPort *releaseDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
+      virtual void checkNoCyclePassingThrough(Node *node) throw(Exception) = 0;
+      void checkInMyDescendance(Node *nodeToTest) const throw(Exception);
+      static ComposedNode *getLowestCommonAncestor(Node *node1, Node *node2) throw(Exception);
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/DataFlowPort.cxx b/src/engine/DataFlowPort.cxx
new file mode 100644 (file)
index 0000000..0130338
--- /dev/null
@@ -0,0 +1,25 @@
+#include "DataFlowPort.hxx"
+
+using namespace YACS::ENGINE;
+using YACS::DynType;
+
+const char DataFlowPort::NAME[]="DataFlowPort";
+
+DataFlowPort::DataFlowPort(const std::string& name, Node *node, DynType type):Port(node),_name(name),_data(type)
+{
+}
+
+std::string DataFlowPort::getNameOfTypeOfCurrentInstance() const
+{
+  return NAME;
+}
+
+DynType DataFlowPort::edGetType() const
+{
+  return _data.edGetType();
+}
+
+void DataFlowPort::edSetType(DynType type)
+{
+  _data.edInitToType(type);
+}
diff --git a/src/engine/DataFlowPort.hxx b/src/engine/DataFlowPort.hxx
new file mode 100644 (file)
index 0000000..9c04f05
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef __DATAFLOWPORT_HXX__
+#define __DATAFLOWPORT_HXX__
+
+#include "Port.hxx"
+#include "Data.hxx"
+
+#include <string>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class DataFlowPort : public virtual Port
+    {
+    protected:
+      Data _data;
+      std::string _name;
+    public:
+      static const char NAME[];
+    protected:
+      DataFlowPort(const std::string& name, Node *node, DynType type);
+    public:
+      std::string getNameOfTypeOfCurrentInstance() const;
+      DynType edGetType() const;
+      virtual void edSetType(DynType type);
+      std::string getName() const { return _name; }
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/DataStreamPort.cxx b/src/engine/DataStreamPort.cxx
new file mode 100644 (file)
index 0000000..258e219
--- /dev/null
@@ -0,0 +1,14 @@
+#include "DataStreamPort.hxx"
+
+using namespace YACS::ENGINE;
+
+const char DataStreamPort::NAME[]="DataStreamPort";
+
+DataStreamPort::DataStreamPort(const std::string& name, Node *node, StreamType type):Port(node),_name(name),_edType(type)
+{
+}
+
+std::string DataStreamPort::getNameOfTypeOfCurrentInstance() const
+{
+  return NAME;
+}
diff --git a/src/engine/DataStreamPort.hxx b/src/engine/DataStreamPort.hxx
new file mode 100644 (file)
index 0000000..dc08038
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef __DATASTREAMPORT_HXX__
+#define __DATASTREAMPORT_HXX__
+
+#include "Port.hxx"
+#include "define.hxx"
+
+#include <string>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class DataStreamPort : public virtual Port
+    {
+    protected:
+      std::string _name;
+      StreamType _edType;
+    public:
+      static const char NAME[];
+    protected:
+      DataStreamPort(const std::string& name, Node *node, StreamType type);
+    public:
+      std::string getNameOfTypeOfCurrentInstance() const;
+      std::string getName() const { return _name; }
+      StreamType edGetType() const { return _edType; }
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/ElementaryNode.cxx b/src/engine/ElementaryNode.cxx
new file mode 100644 (file)
index 0000000..b1913d9
--- /dev/null
@@ -0,0 +1,110 @@
+#include "ElementaryNode.hxx"
+#include "InputPort.hxx"
+#include "OutputPort.hxx"
+#include "ComposedNode.hxx"
+#include "InputDataStreamPort.hxx"
+#include "OutputDataStreamPort.hxx"
+
+using namespace YACS::ENGINE;
+
+ElementaryNode::ElementaryNode(const std::string& name):Node(name)
+{
+}
+
+ElementaryNode::~ElementaryNode()
+{
+  for(std::list<InputPort *>::iterator iter1=_listOfInputPort.begin();iter1!=_listOfInputPort.end();iter1++)
+    delete *iter1;
+  for(std::list<OutputPort *>::iterator iter2=_listOfOutputPort.begin();iter2!=_listOfOutputPort.end();iter2++)
+    delete *iter2;
+  for(std::list<InputDataStreamPort *>::iterator iter3=_listOfInputDataStreamPort.begin();iter3!=_listOfInputDataStreamPort.end();iter3++)
+    delete *iter3;
+  for(std::list<OutputDataStreamPort *>::iterator iter4=_listOfOutputDataStreamPort.begin();iter4!=_listOfOutputDataStreamPort.end();iter4++)
+    delete *iter4;
+}
+
+void ElementaryNode::getReadyTasks(std::vector<Task *>& tasks)
+{
+  if(_state==YACS::TOACTIVATE)
+    tasks.push_back(this);
+}
+
+void ElementaryNode::edRemovePort(Port *port) throw(Exception)
+{
+  if(port->getNode()!=this)
+    throw Exception("ElementaryNode::edRemovePort : Port is not ownered by this");
+  std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
+  if(typeOfPortInstance==InputPort::NAME)
+    edRemovePortTypedFromList<InputPort>(dynamic_cast<InputPort *>(port),_listOfInputPort);
+  else if(typeOfPortInstance==OutputPort::NAME)
+    edRemovePortTypedFromList<OutputPort>(dynamic_cast<OutputPort *>(port),_listOfOutputPort);
+  else if(typeOfPortInstance==InputDataStreamPort::NAME)
+    edRemovePortTypedFromList<InputDataStreamPort>(dynamic_cast<InputDataStreamPort *>(port),_listOfInputDataStreamPort);
+  else if(typeOfPortInstance==OutputDataStreamPort::NAME)
+    edRemovePortTypedFromList<OutputDataStreamPort>(dynamic_cast<OutputDataStreamPort *>(port),_listOfOutputDataStreamPort);
+  else
+    throw Exception("ElementaryNode::edRemovePort : unknown port type");
+  delete port;
+}
+
+std::list<ElementaryNode *> ElementaryNode::getRecursiveConstituents()
+{
+  std::list<ElementaryNode *> ret;
+  ret.push_back(this);
+  return ret;
+}
+
+InputPort *ElementaryNode::edAddInputPort(const std::string& inputPortName, YACS::DynType type) throw(Exception)
+{
+  InputPort *ret=edAddPort<InputPort,YACS::DynType>(inputPortName,_listOfInputPort,type);
+  //By default all inputports are seen from upper level nodes NOT outputports
+  ComposedNode *iter=_father;
+  while(iter)
+    {
+      iter->publishInputPort(_listOfInputPort.back());
+      iter=iter->_father;
+    }
+  return ret;
+}
+
+OutputPort *ElementaryNode::edAddOutputPort(const std::string& outputPortName, YACS::DynType type) throw(Exception)
+{
+  return edAddPort<OutputPort,YACS::DynType>(outputPortName,_listOfOutputPort,type);
+}
+
+InputDataStreamPort *ElementaryNode::edAddInputDataStreamPort(const std::string& inputPortDSName, YACS::StreamType type) throw(Exception)
+{
+  return edAddPort<InputDataStreamPort,YACS::StreamType>(inputPortDSName,_listOfInputDataStreamPort,type);
+}
+
+OutputDataStreamPort *ElementaryNode::edAddOutputDataStreamPort(const std::string& outputPortDSName, YACS::StreamType type) throw(Exception)
+{
+  return edAddPort<OutputDataStreamPort,YACS::StreamType>(outputPortDSName,_listOfOutputDataStreamPort,type);
+}
+
+void ElementaryNode::disconnectAllLinksConnectedTo(Node *node)
+{
+  std::list<InputPort *> inputDF=node->getListOfInputPort();
+  for(std::list<OutputPort *>::iterator iter1=_listOfOutputPort.begin();iter1!=_listOfOutputPort.end();iter1++)
+    for(std::list<InputPort *>::iterator iter2=inputDF.begin();iter2!=inputDF.end();iter2++)
+      (*iter1)->edRemoveInputPort(*iter2);
+  std::list<InputDataStreamPort *> inputDS=node->getListOfInputDataStreamPort();
+  for(std::list<OutputDataStreamPort *>::iterator iter3=_listOfOutputDataStreamPort.begin();iter3!=_listOfOutputDataStreamPort.end();iter3++)
+    for(std::list<InputDataStreamPort *>::iterator iter4=inputDS.begin();iter4!=inputDS.end();iter4++)
+      (*iter3)->edRemoveInputDataStreamPort(*iter4);
+}
+
+void ElementaryNode::begin()
+{
+  _state=ACTIVATED;
+}
+
+bool ElementaryNode::isReady()
+{
+  return _state==TOACTIVATE;
+}
+
+void ElementaryNode::finished()
+{
+  _state=DONE;
+}
diff --git a/src/engine/ElementaryNode.hxx b/src/engine/ElementaryNode.hxx
new file mode 100644 (file)
index 0000000..3bafac5
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef __ELEMENTARYNODE_HXX__
+#define __ELEMENTARYNODE_HXX__
+
+#include "Node.hxx"
+#include "Task.hxx"
+#include "define.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Port;
+    class InputPort;
+    class OutputPort;
+    class ComposedNode;
+    class InputDataStreamPort;
+    class OutputDataStreamPort;
+
+    class ElementaryNode : public Node, public Task
+    {
+      friend class ComposedNode;
+    protected:
+      ElementaryNode(const std::string& name);
+      ~ElementaryNode();
+    public:
+      void getReadyTasks(std::vector<Task *>& tasks);
+      void edRemovePort(Port *port) throw(Exception);
+      std::list<ElementaryNode *> getRecursiveConstituents();
+      virtual InputPort *edAddInputPort(const std::string& inputPortName, YACS::DynType type) throw(Exception);
+      virtual OutputPort *edAddOutputPort(const std::string& outputPortName, YACS::DynType type) throw(Exception);
+      virtual InputDataStreamPort *edAddInputDataStreamPort(const std::string& inputPortDSName, YACS::StreamType type) throw(Exception);
+      virtual OutputDataStreamPort *edAddOutputDataStreamPort(const std::string& outputPortDSName, YACS::StreamType type) throw(Exception);
+      //run part
+      void begin();
+      bool isReady();
+      void finished();
+    protected:
+      void disconnectAllLinksConnectedTo(Node *node);
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/Executor.cxx b/src/engine/Executor.cxx
new file mode 100644 (file)
index 0000000..64938da
--- /dev/null
@@ -0,0 +1,123 @@
+#include "Executor.hxx"
+#include "Task.hxx"
+#include "Scheduler.hxx"
+#include <pthread.h>
+#include <iostream>
+
+using namespace YACS::ENGINE;
+
+using YACS::BASES::Mutex;
+using YACS::BASES::Thread;
+using YACS::BASES::Semaphore;
+
+Executor::Executor():_nbOfConcurrentThreads(0)//,_cond(PTHREAD_COND_INITIALIZER)
+{
+}
+
+Executor::~Executor()
+{
+  for(std::list<Thread *>::iterator iter=_groupOfAllThreadsCreated.begin();iter!=_groupOfAllThreadsCreated.end();iter++)
+    delete *iter;
+}
+
+void Executor::RunW(Scheduler *graph)
+{
+  _mainSched=graph;
+  bool isMore;
+  int i=0;
+  graph->init();
+  std::vector<Task *> tasks;
+  std::vector<Task *>::iterator iter;
+  bool toContinue=true;
+  wakeUp();
+  while(toContinue)
+    {
+      sleepWhileNoEventsFromAnyRunningTask();
+      {//Critical section
+       _mutexForSchedulerUpdate.lock();
+       tasks=graph->getNextTasks(isMore);
+       graph->selectRunnableTasks(tasks);
+       _mutexForSchedulerUpdate.unlock();
+      }//End of critical section
+      for(iter=tasks.begin();iter!=tasks.end();iter++)
+       launchTask(*iter);
+      {//Critical section
+       _mutexForSchedulerUpdate.lock();
+       toContinue=!graph->isFinished();
+       _mutexForSchedulerUpdate.unlock();
+      }//End of critical section
+      i++;
+    }
+}
+
+void Executor::launchTask(Task *task)
+{
+  void **args=new void *[3];
+  _mutexForNbOfConcurrentThreads.lock();
+  _groupOfAllThreadsCreated.push_back(0);
+  std::list<Thread *>::iterator iter=_groupOfAllThreadsCreated.end();
+  iter--;
+  _mutexForNbOfConcurrentThreads.unlock();
+  args[0]=(void *)task;
+  args[1]=(void *)_mainSched;
+  args[2]=(void *)this;
+  {//Critical section
+    _mutexForSchedulerUpdate.lock();
+    task->begin();
+    _mainSched->notifyFrom(task,YACS::START);
+    _mutexForSchedulerUpdate.unlock();
+  }//End of critical section
+  _mutexForNbOfConcurrentThreads.lock();
+  //functionForTaskExecution(args);//MultiThreaded=NO
+  //  *iter=
+  new Thread(functionForTaskExecution,args);//MultiThreaded=YES
+  _mutexForNbOfConcurrentThreads.unlock();
+}
+
+void Executor::sleepWhileNoEventsFromAnyRunningTask()
+{
+  _semForNewTasksToPerform.wait();
+}
+
+void Executor::notifyEndOfThread(YACS::BASES::Thread *thread)
+{
+  /*_mutexForNbOfConcurrentThreads.lock();
+  _groupOfAllThreadsCreated.remove(thread);
+  delete thread;
+  _mutexForNbOfConcurrentThreads.unlock();*/
+}
+
+void Executor::wakeUp()
+{
+  int val=_semForNewTasksToPerform.getValue();
+  if(!val)
+    _semForNewTasksToPerform.post();
+}
+
+int Executor::getNbOfThreads()
+{
+  int ret;
+  _mutexForNbOfConcurrentThreads.lock();
+  ret=_groupOfAllThreadsCreated.size();
+  _mutexForNbOfConcurrentThreads.unlock();
+  return ret;
+}
+
+void *Executor::functionForTaskExecution(void *arg)
+{
+  void **argT=(void **)arg;
+  Task *task=(Task *)argT[0];
+  Scheduler *sched=(Scheduler *)argT[1];
+  Executor *execInst=(Executor *)argT[2];
+  delete [] argT;
+  task->execute();
+  {//Critical section
+    execInst->_mutexForSchedulerUpdate.lock();
+    task->finished();
+    sched->notifyFrom(task,YACS::FINISH);
+    execInst->_mutexForSchedulerUpdate.unlock();
+  }//End of critical section
+  execInst->wakeUp();
+  execInst->notifyEndOfThread(0);
+  return 0;
+}
diff --git a/src/engine/Executor.hxx b/src/engine/Executor.hxx
new file mode 100644 (file)
index 0000000..9337cc0
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef __EXECUTOR_HXX__
+#define __EXECUTOR_HXX__
+
+#include "Mutex.hxx"
+#include "Thread.hxx"
+#include "Semaphore.hxx"
+
+#include <list>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Scheduler;
+    class Task;
+    
+    class Executor
+    {
+    protected:
+      Scheduler *_mainSched;
+      int _nbOfConcurrentThreads;
+      YACS::BASES::Mutex _mutexForNbOfConcurrentThreads;
+      YACS::BASES::Semaphore _semForNewTasksToPerform;
+      YACS::BASES::Mutex _mutexForSchedulerUpdate;
+      pthread_cond_t _cond;
+      std::list< YACS::BASES::Thread * > _groupOfAllThreadsCreated;
+    public:
+      Executor();
+      ~Executor();
+      void RunW(Scheduler *graph);
+      int getNbOfThreads();
+    protected:
+      void launchTask(Task *task);
+      void wakeUp();
+      void sleepWhileNoEventsFromAnyRunningTask();
+      void notifyEndOfThread(YACS::BASES::Thread *thread);
+    protected:
+      static void *functionForTaskExecution(void *);
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/InGate.cxx b/src/engine/InGate.cxx
new file mode 100644 (file)
index 0000000..57008d4
--- /dev/null
@@ -0,0 +1,47 @@
+#include "InGate.hxx"
+#include "Node.hxx"
+
+using namespace YACS::ENGINE;
+
+const char InGate::NAME[]="InGate";
+
+InGate::InGate(Node *node):Port(node),_nbPrecursor(0),_nbPrecursorDone(0),_colour(YACS::White)
+{
+}
+
+std::string InGate::getNameOfTypeOfCurrentInstance() const
+{
+  return NAME;
+}
+
+void InGate::exNotifyFromPrecursor()
+{
+  _nbPrecursorDone++;
+  if(exIsReady() && _node)
+    _node->exUpdateState();
+}
+
+void InGate::edAppendPrecursor()
+{
+  _nbPrecursor++;
+}
+
+void InGate::edRemovePrecursor()
+{
+  _nbPrecursor--;
+}
+
+void InGate::edSet(int nbOfPrecursors)
+{
+  _nbPrecursor=nbOfPrecursors;
+}
+
+void InGate::exReset()
+{
+  _nbPrecursorDone=0;
+}
+
+bool InGate::exIsReady() const
+{
+  return _nbPrecursor==_nbPrecursorDone;
+}
diff --git a/src/engine/InGate.hxx b/src/engine/InGate.hxx
new file mode 100644 (file)
index 0000000..75e888c
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef __INGATE_HXX__
+#define __INGATE_HXX__
+
+#include "Port.hxx"
+#include "define.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class InGate : public Port
+    {
+      friend class Bloc;
+      friend class Node;
+    protected:
+      int _nbPrecursor;
+      int _nbPrecursorDone;
+      static const char NAME[];
+    private:
+      //for graphs algs
+      mutable Colour _colour;
+    public:
+      InGate(Node *node);
+      std::string getNameOfTypeOfCurrentInstance() const;
+      void exNotifyFromPrecursor();
+      void edAppendPrecursor();
+      void edRemovePrecursor();
+      void edSet(int nbOfPrecursors);
+      void exReset();
+      bool exIsReady() const;
+    private:
+      void initForDFS() const { _colour=YACS::White; }
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/InPort.cxx b/src/engine/InPort.cxx
new file mode 100644 (file)
index 0000000..ea17280
--- /dev/null
@@ -0,0 +1,7 @@
+#include "InPort.hxx"
+
+using namespace YACS::ENGINE;
+
+InPort::InPort(Node *node):Port(node)
+{
+}
diff --git a/src/engine/InPort.hxx b/src/engine/InPort.hxx
new file mode 100644 (file)
index 0000000..0377fc1
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __INPORT_HXX__
+#define __INPORT_HXX__
+
+#include "Port.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class InPort : public virtual Port
+    {
+    protected:
+      InPort(Node *node);
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/InputDataStreamPort.cxx b/src/engine/InputDataStreamPort.cxx
new file mode 100644 (file)
index 0000000..8c54db5
--- /dev/null
@@ -0,0 +1,16 @@
+#include "InputDataStreamPort.hxx"
+
+using namespace YACS::ENGINE;
+
+const char InputDataStreamPort::NAME[]="InputDataStreamPort";
+
+InputDataStreamPort::InputDataStreamPort(const std::string& name, Node *node, StreamType type):DataStreamPort(name,node,type),
+                                                                                              InPort(node),
+                                                                                              Port(node)
+{
+}
+
+std::string InputDataStreamPort::getNameOfTypeOfCurrentInstance() const
+{
+  return NAME;
+}
diff --git a/src/engine/InputDataStreamPort.hxx b/src/engine/InputDataStreamPort.hxx
new file mode 100644 (file)
index 0000000..e62687e
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef __INPUTDATASTREAMPORT_HXX__
+#define __INPUTDATASTREAMPORT_HXX__
+
+#include "InPort.hxx"
+#include "DataStreamPort.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class InputDataStreamPort : public DataStreamPort, public InPort
+    {
+    public:
+      static const char NAME[];
+    public:
+      InputDataStreamPort(const std::string& name, Node *node, StreamType type);
+      std::string getNameOfTypeOfCurrentInstance() const;
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/InputPort.cxx b/src/engine/InputPort.cxx
new file mode 100644 (file)
index 0000000..c14347f
--- /dev/null
@@ -0,0 +1,45 @@
+#include "InputPort.hxx"
+
+using namespace YACS::ENGINE;
+
+const char InputPort::NAME[]="InputPort";
+
+InputPort::InputPort(const std::string& name, Node *node, DynType type):DataFlowPort(name,node,type),InPort(node),Port(node),_manuallySet(false)
+{
+}
+
+std::string InputPort::getNameOfTypeOfCurrentInstance() const
+{
+  return NAME;
+}
+
+void InputPort::edInit(Data data) throw(ConversionException)
+{
+  _data=data;
+  _manuallySet=true;
+}
+
+void InputPort::edNotifyReferenced()
+{
+  _manuallySet=false;
+}
+
+void InputPort::exInit()
+{
+  if(!_manuallySet)
+    _data.exInit();
+}
+
+Data InputPort::exGet() const
+{
+  return _data;
+}
+
+void InputPort::exAccept(Data data) throw(ConversionException)
+{
+  _data=data;
+}
+
+InputPort::~InputPort()
+{
+}
diff --git a/src/engine/InputPort.hxx b/src/engine/InputPort.hxx
new file mode 100644 (file)
index 0000000..815b497
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef __INPUTPORT_HXX__
+#define __INPUTPORT_HXX__
+
+#include "InPort.hxx"
+#include "DataFlowPort.hxx"
+#include "ConversionException.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class InputPort : public DataFlowPort, public InPort
+    {
+    protected:
+      bool _manuallySet;
+    public:
+      static const char NAME[];
+    public:
+      InputPort(const std::string& name, Node *node, DynType type);
+      std::string getNameOfTypeOfCurrentInstance() const;
+      void edInit(Data data) throw(ConversionException);
+      void edNotifyReferenced();
+      void exInit();
+      Data exGet() const;
+      void exAccept(Data data) throw(ConversionException);
+      ~InputPort();
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/Loop.cxx b/src/engine/Loop.cxx
new file mode 100644 (file)
index 0000000..94bf78e
--- /dev/null
@@ -0,0 +1,282 @@
+#include "Loop.hxx"
+#include "InputPort.hxx"
+#include "OutputPort.hxx"
+#include "InputDataStreamPort.hxx"
+#include "OutputDataStreamPort.hxx"
+#include "TypeCheckerDataStream.hxx"
+
+using namespace YACS::ENGINE;
+
+DFToDSForLoop::DFToDSForLoop(Loop *loop, const std::string& name, YACS::DynType type):ElementaryNode(""),_nbOfTimeUsed(1)
+{
+  _name="DF2DS For "; _name+=loop->getName(); _name+=" representing port "; _name+=name;
+  _father=loop;
+  _listOfInputPort.push_back(new InputPort("",this,type));
+  _listOfOutputDataStreamPort.push_back(new OutputDataStreamPort("",this,Loop::MappingDF2DS(type)));
+}
+
+DFToDSForLoop::~DFToDSForLoop()
+{
+}
+
+InputPort *DFToDSForLoop::getInputPort(const std::string& name) const throw(Exception)
+{
+  return (InputPort *) &_listOfInputPort.back();
+}
+
+OutputDataStreamPort *DFToDSForLoop::getOutputDataStreamPort(const std::string& name) const throw(Exception)
+{
+  return (OutputDataStreamPort *) &_listOfOutputDataStreamPort.back();
+}
+
+void DFToDSForLoop::execute()
+{
+  //TO IMPLEMENT
+}
+
+DSToDFForLoop::DSToDFForLoop(Loop *loop, const std::string& name, YACS::StreamType type):ElementaryNode(""),_nbOfTimeUsed(1)
+{
+  _name="DS2DF For "; _name+=loop->getName(); _name+=" representing port "; _name+=name;
+  _father=loop;
+  _listOfOutputPort.push_back(new OutputPort("",this,Loop::MappingDS2DF(type)));
+  _listOfInputDataStreamPort.push_back(new InputDataStreamPort("",this,type));
+}
+
+DSToDFForLoop::~DSToDFForLoop()
+{
+}
+
+OutputPort *DSToDFForLoop::getOutputPort(const std::string& name) const throw(Exception)
+{
+  return (OutputPort *) &_listOfOutputPort.back();
+}
+
+InputDataStreamPort *DSToDFForLoop::getInputDataStreamPort(const std::string& name) const throw(Exception)
+{
+  return (InputDataStreamPort *) &_listOfInputDataStreamPort.back();
+}
+
+void DSToDFForLoop::execute()
+{
+  //TO IMPLEMENT
+}
+
+Loop::Loop(const std::string& name):ComposedNode(name),_node(0)
+{
+}
+
+Loop::~Loop()
+{
+  delete _node;
+}
+
+void Loop::edSetNode(Node *node)
+{
+  delete _node;
+  _node=node;
+}
+
+void Loop::edAddExtraInputPort(const std::string& inputPortName, YACS::DynType type) throw(Exception)
+{
+  edAddPort<InputPort,YACS::DynType>(inputPortName,_listOfExtraInputPort,type);
+}
+
+void Loop::edRemoveExtraInputPort(InputPort *inputPort)
+{
+  edRemovePortTypedFromList<InputPort>(inputPort,_listOfExtraInputPort);
+}
+
+YACS::StreamType Loop::MappingDF2DS(YACS::DynType type) throw(Exception)
+{
+  switch(type)
+    {
+      case Double:
+       return SDouble;
+    }
+  std::string what("Loop::MappingDF2DS : unable to perform DataFlow to DataStream traduction for dataflow type ");
+  what+=Data::edGetTypeInPrintableForm(type);
+  throw Exception(what);
+}
+
+YACS::DynType Loop::MappingDS2DF(YACS::StreamType type) throw(Exception)
+{
+  switch(type)
+    {
+      case SDouble:
+       return Double;
+    }
+  std::string what("Loop::MappingDS2DF : unable to perform DataStream to DataFlow traduction for datastream type ");
+  what+=TypeCheckerDataStream::edGetTypeInPrintableForm(type);
+  throw Exception(what);
+}
+
+InPort *Loop::buildDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView)
+{
+  std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
+  if(typeOfPortInstance!=InputPort::NAME)
+    return port;
+  else
+    if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView))
+      return port;
+  InputPort *portCasted=(InputPort *)port;
+  std::list<DSToDFForLoop>::iterator iter;
+  //Determinig if a DSToDFForLoop node has already been created for delegation of 'port'
+  for(iter=_inputsTraducer.begin();iter!=_inputsTraducer.end();iter++)
+    if((*iter).getOutputPort("")->isAlreadyInList(portCasted))
+      break;
+  if(iter==_inputsTraducer.end())
+    {//first time that 'port' is delegated on higher level
+      _inputsTraducer.push_back(DSToDFForLoop(this,portCasted->getName(),Loop::MappingDF2DS(portCasted->edGetType())));
+      iter=_inputsTraducer.end(); iter--;
+      (*iter).getOutputPort("")->edAddInputPort(portCasted);
+      //WARNING control flow has to be added
+      (*iter).getOutGate()->edAddInGate(portCasted->getNode()->getInGate());//WARNING HERE MAYBE HAS TO BE IMPROVED - SEPARATE COUNTERS
+    }
+  else
+    (*iter).loopHasOneMoreRef();
+  return (*iter).getInputDataStreamPort("");
+}
+
+OutPort *Loop::buildDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView)
+{
+  std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
+  if(typeOfPortInstance!=OutputPort::NAME)
+    return port;
+  else
+    if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView))
+      return port;
+  OutputPort *portCasted=(OutputPort *)port;
+  std::list<DFToDSForLoop>::iterator iter;
+  //Determinig if a DFToDSForLoop node has already been created for delegation of 'port'
+  for(iter=_outputsTraducer.begin();iter!=_outputsTraducer.end();iter++)
+    if(portCasted->isAlreadyInList((*iter).getInputPort("")))
+      break;
+  if(iter==_outputsTraducer.end())
+    {//first time that 'port' is delegated on higher level
+      _outputsTraducer.push_back(DFToDSForLoop(this,portCasted->getName(),portCasted->edGetType()));
+      iter=_outputsTraducer.end(); iter--;
+      portCasted->edAddInputPort((*iter).getInputPort(""));
+      //WARNING control flow has to be added
+      portCasted->getNode()->getOutGate()->edAddInGate((*iter).getInGate());//WARNING HERE MAYBE HAS TO BE IMPROVED - SEPARATE COUNTERS
+    }
+  else
+    (*iter).loopHasOneMoreRef();
+  return (*iter).getOutputDataStreamPort("");
+}
+
+InPort *Loop::getDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
+{
+  std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
+  if(typeOfPortInstance!=InputPort::NAME)
+    return port;
+  else
+    if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView))
+      return port;
+  InputPort *portCasted=(InputPort *)port;
+  std::list<DSToDFForLoop>::iterator iter;
+  for(iter=_inputsTraducer.begin();iter!=_inputsTraducer.end();iter++)
+    if((*iter).getOutputPort("")->isAlreadyInList(portCasted))
+      break;
+  if(iter==_inputsTraducer.end())
+    {
+      std::string what("Loop::getDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; 
+      throw Exception(what);
+    }
+  else
+    return (*iter).getInputDataStreamPort("");
+}
+
+OutPort *Loop::getDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
+{
+  std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
+  if(typeOfPortInstance!=OutputPort::NAME)
+    return port;
+  else
+    if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView))
+      return port;
+  OutputPort *portCasted=(OutputPort *)port;
+  std::list<DFToDSForLoop>::iterator iter;
+  for(iter=_outputsTraducer.begin();iter!=_outputsTraducer.end();iter++)
+    if(portCasted->isAlreadyInList((*iter).getInputPort("")))
+      break;
+  if(iter==_outputsTraducer.end())
+    {
+      std::string what("Loop::getDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; 
+      throw Exception(what);
+    }
+  else
+    return (*iter).getOutputDataStreamPort("");
+}
+
+InPort *Loop::releaseDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
+{
+  std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
+  if(typeOfPortInstance!=InputPort::NAME)
+    return port;
+  else
+    if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView))
+      return port;
+  InputPort *portCasted=(InputPort *)port;
+  std::list<DSToDFForLoop>::iterator iter;
+  for(iter=_inputsTraducer.begin();iter!=_inputsTraducer.end();iter++)
+    if((*iter).getOutputPort("")->isAlreadyInList(portCasted))
+      break;
+  if(iter==_inputsTraducer.end())
+    {
+      std::string what("Loop::releaseDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; 
+      throw Exception(what);
+    }
+  else
+    {
+      InPort *ret=(*iter).getInputDataStreamPort("");
+      if((*iter).loopHasOneLessRef())
+       _inputsTraducer.erase(iter);
+      return ret;
+    }
+}
+
+OutPort *Loop::releaseDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
+{
+    std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
+  if(typeOfPortInstance!=OutputPort::NAME)
+    return port;
+  else
+    if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView))
+      return port;
+  OutputPort *portCasted=(OutputPort *)port;
+  std::list<DFToDSForLoop>::iterator iter;
+  for(iter=_outputsTraducer.begin();iter!=_outputsTraducer.end();iter++)
+    if(portCasted->isAlreadyInList((*iter).getInputPort("")))
+      break;
+  if(iter==_outputsTraducer.end())
+    {
+      std::string what("Loop::releaseDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; 
+      throw Exception(what);
+    }
+  else
+    {
+      OutPort *ret=(*iter).getOutputDataStreamPort("");
+      if((*iter).loopHasOneLessRef())
+       _outputsTraducer.erase(iter);
+      return ret;
+    }
+}
+
+void Loop::checkNoCyclePassingThrough(Node *node) throw(Exception)
+{
+  throw Exception("Loop::checkNoCyclePassingThrough : Internal error occured");
+}
+
+/**
+ * @ note : States if a DF port must be considered on an upper level in hierarchy as a DS port or not from 'pointsOfView' observers.
+ * @ return : 
+ *            - True : a traduction DF->DS has to be done
+ *            - False : no traduction needed
+ */
+bool Loop::isNecessaryToBuildSpecificDelegateDF2DS(const std::list<ComposedNode *>& pointsOfView)
+{
+  bool ret=false;
+  for(std::list<ComposedNode *>::const_iterator iter=pointsOfView.begin();iter!=pointsOfView.end() && !ret;iter++)
+    ret=(*iter)->isRepeatedUnpredictablySeveralTimes();
+  return ret;
+}
diff --git a/src/engine/Loop.hxx b/src/engine/Loop.hxx
new file mode 100644 (file)
index 0000000..2df5912
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef __LOOP_HXX__
+#define __LOOP_HXX__
+
+#include "ComposedNode.hxx"
+#include "ElementaryNode.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Loop;
+    
+    class DFToDSForLoop : public ElementaryNode
+    {
+      friend class Loop;
+    private:
+      int _nbOfTimeUsed;
+      Loop *_loopArtificiallyBuiltMe;
+    private:
+      DFToDSForLoop(Loop *loop, const std::string& name, YACS::DynType type);
+      void loopHasOneMoreRef() { _nbOfTimeUsed++; }
+      bool loopHasOneLessRef() { return --_nbOfTimeUsed==0; }
+      InputPort *getInputPort(const std::string& name) const throw(Exception);
+      OutputDataStreamPort *getOutputDataStreamPort(const std::string& name) const throw(Exception);
+      //run part
+      void execute();
+    public:
+      ~DFToDSForLoop();
+    };
+
+    class DSToDFForLoop : public ElementaryNode
+    {
+      friend class Loop;
+    private:
+      int _nbOfTimeUsed;
+      Loop *_loopArtificiallyBuiltMe;
+    private:
+      DSToDFForLoop(Loop *loop, const std::string& name, YACS::StreamType type);
+      void loopHasOneMoreRef() { _nbOfTimeUsed++; }
+      bool loopHasOneLessRef() { return --_nbOfTimeUsed==0; }
+      OutputPort *getOutputPort(const std::string& name) const throw(Exception);
+      InputDataStreamPort *getInputDataStreamPort(const std::string& name) const throw(Exception);
+      //run part
+      void execute();
+    public:
+      ~DSToDFForLoop();
+    };
+
+    class Loop : public ComposedNode
+    {
+    protected:
+      Node *_node;
+      std::list<InputPort *> _listOfExtraInputPort;
+      std::list<DSToDFForLoop> _inputsTraducer;
+      std::list<DFToDSForLoop> _outputsTraducer;
+    public:
+      Loop(const std::string& name);
+      ~Loop();
+      void edSetNode(Node *node);
+      void edAddExtraInputPort(const std::string& inputPortName, YACS::DynType type) throw(Exception);
+      void edRemoveExtraInputPort(InputPort *inputPort);
+      bool isRepeatedUnpredictablySeveralTimes() const { return true; }
+      static YACS::StreamType MappingDF2DS(YACS::DynType type) throw(Exception);
+      static YACS::DynType MappingDS2DF(YACS::StreamType type) throw(Exception);
+    protected:
+      InPort *buildDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView);
+      OutPort *buildDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView);
+      InPort *getDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
+      OutPort *getDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
+      InPort *releaseDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
+      OutPort *releaseDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
+      void checkNoCyclePassingThrough(Node *node) throw(Exception);
+      static bool isNecessaryToBuildSpecificDelegateDF2DS(const std::list<ComposedNode *>& pointsOfView);
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am
new file mode 100644 (file)
index 0000000..174ae78
--- /dev/null
@@ -0,0 +1,40 @@
+
+include $(top_srcdir)/adm/unix/make_begin.am
+
+SUBDIRS = Test
+
+lib_LTLIBRARIES = libYACSEngine.la
+
+libYACSEngine_la_SOURCES =         \
+       Port.cxx InGate.cxx        \
+       OutGate.cxx                \
+       DataFlowPort.cxx           \
+       InPort.cxx                 \
+       OutPort.cxx                \
+       InputPort.cxx              \
+       OutputPort.cxx             \
+       DataStreamPort.cxx         \
+       InputDataStreamPort.cxx    \
+       OutputDataStreamPort.cxx   \
+       Node.cxx                   \
+       ElementaryNode.cxx         \
+       ComposedNode.cxx           \
+       Bloc.cxx                   \
+       Loop.cxx                   \
+       Switch.cxx                 \
+       Scheduler.hxx              \
+       Task.hxx                   \
+       Executor.cxx               \
+       $(__dummy__)
+
+EXTRA_libYACSEngine_la_SOURCES =  \
+       $(__dummy__)
+
+libYACSEngine_la_LIBADD = ../bases/libYACSBases.la \
+                          ../basicData/libYACSBasicData.la 
+
+AM_CXXFLAGS = $(THREAD_DEF)  \
+              -I$(srcdir)/../bases \
+              -I$(srcdir)/../basicData
+
+include $(top_srcdir)/adm/unix/make_end.am
diff --git a/src/engine/Node.cxx b/src/engine/Node.cxx
new file mode 100644 (file)
index 0000000..31c93a4
--- /dev/null
@@ -0,0 +1,142 @@
+#include "Node.hxx"
+#include "InputPort.hxx"
+#include "OutputPort.hxx"
+#include "ComposedNode.hxx"
+#include "InputDataStreamPort.hxx"
+#include "OutputDataStreamPort.hxx"
+
+using namespace YACS::ENGINE;
+
+Node::Node(const std::string& name):_name(name),_inGate(this),_outGate(this),_father(0),_colour(YACS::White),_state(YACS::INITED)
+{
+}
+
+Node::~Node()
+{
+}
+
+void Node::init()
+{
+  _inGate.exReset();
+  for(std::list<OutputPort *>::iterator iter=_listOfOutputPort.begin();iter!=_listOfOutputPort.end();iter++)
+    (*iter)->exInit();
+  for(std::list<InputPort *>::iterator iter2=_listOfInputPort.begin();iter2!=_listOfInputPort.end();iter2++)
+    (*iter2)->exInit();
+  if(_inGate.exIsReady())
+    _state=YACS::TOACTIVATE;
+  else
+    _state=YACS::INITED;
+}
+
+std::list<Node *> Node::getOutNodes() const
+{
+  std::list<Node *> ret;
+  std::list<InGate *> inGates=_outGate.edListInGate();
+  for(std::list<InGate *>::iterator iter=inGates.begin();iter!=inGates.end();iter++)
+    ret.push_back((*iter)->getNode());
+  return ret;
+}
+
+/**
+ * @ note : Update the '_state' attribute.
+ *          Typically called by 'this->_inGate' when 'this->_inGate' is ready.
+ */
+void Node::exUpdateState()
+{
+  if(_inGate.exIsReady())
+    if(areAllInputPortsValid())
+      _state=YACS::TOACTIVATE;
+    else
+      {
+       std::string what("Node::exUpdateState : Invalid graph given : Node with name \"");
+       what+=_name; what+="\" ready to run whereas some inputports are not set correctly\nCheck coherence DF/CF";
+       throw Exception(what);
+      }
+}
+
+int Node::getNumberOfInputPorts() const
+{
+  return _listOfInputPort.size();
+}
+
+int Node::getNumberOfOutputPorts() const
+{
+  return _listOfOutputPort.size();
+}
+
+InputPort *Node::getInputPort(const std::string& name) const throw(Exception)
+{
+  return getPort<InputPort>(name,_listOfInputPort);
+}
+
+OutputPort *Node::getOutputPort(const std::string& name) const throw(Exception)
+{
+  return getPort<OutputPort>(name,_listOfOutputPort);
+}
+
+InputDataStreamPort *Node::getInputDataStreamPort(const std::string& name) const throw(Exception)
+{
+  return getPort<InputDataStreamPort>(name,_listOfInputDataStreamPort);
+}
+
+OutputDataStreamPort *Node::getOutputDataStreamPort(const std::string& name) const throw(Exception)
+{
+  return getPort<OutputDataStreamPort>(name,_listOfOutputDataStreamPort);
+}
+
+std::list<ComposedNode *> Node::getAllAscendanceOf(ComposedNode *levelToStop)
+{
+  std::list<ComposedNode *> ret;
+  for(ComposedNode *iter=_father;iter!=levelToStop && iter!=0; iter=iter->_father)
+      ret.push_back(iter);
+  return ret;
+}
+
+bool Node::areAllInputPortsValid() const
+{
+  bool ret=true;
+  for(std::list<InputPort *>::const_iterator iter=_listOfInputPort.begin();iter!=_listOfInputPort.end();iter++)
+    ret=!(*iter)->exGet().empty();
+  return ret;
+}
+
+ComposedNode *Node::getRootNode() throw(Exception)
+{
+  if(!_father)
+    throw Exception("No root node");
+  ComposedNode *iter=_father;
+  while(iter->_father)
+    iter=iter->_father;
+  return iter;
+}
+
+void Node::checkValidityOfPortName(const std::string& name) throw(Exception)
+{
+  if(name.find(SEP_CHAR_IN_PORT, 0 )!=std::string::npos)
+    {
+      std::string what("Port name "); what+=name; what+="not valid because it contains character "; what+=SEP_CHAR_IN_PORT;
+      throw Exception(what);
+    }
+}
+
+/**
+ * @ note : Check that 'node1' and 'node2' have exactly the same father
+ * @ exception : If 'node1' and 'node2' have NOT exactly the same father
+ */
+ComposedNode *Node::checkHavingCommonFather(Node *node1, Node *node2) throw(Exception)
+{
+  if(node1!=0 && node2!=0)
+    {
+      if(node1->_father==node2->_father)
+       return node1->_father;
+    }
+  throw Exception("check failed : nodes have not the same father");
+}
+
+void Node::initForDFS() const
+{
+  _colour=YACS::White;
+  std::list<InGate *> inGates=_outGate.edListInGate();
+  for(std::list<InGate *>::iterator iter=inGates.begin();iter!=inGates.end();iter++)
+    (*iter)->initForDFS();
+}
diff --git a/src/engine/Node.hxx b/src/engine/Node.hxx
new file mode 100644 (file)
index 0000000..8b24223
--- /dev/null
@@ -0,0 +1,134 @@
+#ifndef __NODE_HXX__
+#define __NODE_HXX__
+
+#include "define.hxx"
+#include "InGate.hxx"
+#include "OutGate.hxx"
+#include "Exception.hxx"
+
+#include <list>
+#include <string>
+#include <vector>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Task;
+    class InputPort;
+    class OutputPort;
+    class ComposedNode;
+    class ElementaryNode;
+    class InputDataStreamPort;
+    class OutputDataStreamPort;
+    
+    class Node
+    {
+      friend class Bloc;
+      friend class ComposedNode;
+      friend class ElementaryNode;
+    protected:
+      InGate _inGate;
+      OutGate _outGate;
+      std::string _name;
+      ComposedNode *_father;
+      YACS::StatesForNode _state;
+      std::list<InputPort *> _listOfInputPort;
+      std::list<OutputPort *> _listOfOutputPort;
+      std::list<InputDataStreamPort *> _listOfInputDataStreamPort;
+      std::list<OutputDataStreamPort *> _listOfOutputDataStreamPort;
+      static const char SEP_CHAR_IN_PORT='?';
+    private:
+      //for graphs algorithms
+      mutable YACS::Colour _colour;
+    protected:
+      Node(const std::string& name);
+    public:
+      virtual ~Node();
+      virtual void init();
+      InGate *getInGate() { return &_inGate; }
+      OutGate *getOutGate() { return &_outGate; }
+      const std::string& getName() const { return _name; }
+      std::list<Node *> getOutNodes() const;
+      virtual void exUpdateState();
+      virtual void getReadyTasks(std::vector<Task *>& tasks) = 0;
+      virtual std::list<ElementaryNode *> getRecursiveConstituents() = 0;
+      virtual int getNumberOfInputPorts() const;
+      virtual int getNumberOfOutputPorts() const;
+      virtual std::list<InputPort *> getListOfInputPort() const { return _listOfInputPort; }
+      virtual std::list<OutputPort *> getListOfOutputPort() const { return _listOfOutputPort; }
+      virtual InputPort *getInputPort(const std::string& name) const throw(Exception);
+      virtual OutputPort *getOutputPort(const std::string& name) const throw(Exception);
+      virtual std::list<InputDataStreamPort *> getListOfInputDataStreamPort() const { return _listOfInputDataStreamPort; }
+      virtual std::list<OutputDataStreamPort *> getListOfOutputDataStreamPort() const { return _listOfOutputDataStreamPort; }
+      virtual InputDataStreamPort *getInputDataStreamPort(const std::string& name) const throw(Exception);
+      virtual OutputDataStreamPort *getOutputDataStreamPort(const std::string& name) const throw(Exception);
+      std::list<ComposedNode *> getAllAscendanceOf(ComposedNode *levelToStop = 0);
+    protected:
+      bool areAllInputPortsValid() const;
+      virtual ComposedNode *getRootNode() throw(Exception);
+      virtual void disconnectAllLinksConnectedTo(Node *node) = 0;
+      static void checkValidityOfPortName(const std::string& name) throw(Exception);
+      static ComposedNode *checkHavingCommonFather(Node *node1, Node *node2) throw(Exception);
+      template<class PORT>
+      PORT *getPort(const std::string& name, const std::list<PORT *>& listOfPorts) const throw(Exception);
+      template<class PORT, class ENUMTYPE>
+      PORT *edAddPort(const std::string& portName, std::list<PORT *>& listOfPorts, ENUMTYPE type) throw(Exception);
+      template<class PORT>
+      static void edRemovePortTypedFromList(PORT *port, std::list<PORT *>& listOfPorts) throw(Exception);
+      template<class PORT>
+      static bool isPortNameAlreadyExist(const std::string& portName, const std::list<PORT *>& listOfPorts);
+    private:
+      void initForDFS() const;
+    };
+
+    template<class PORT>
+    PORT *Node::getPort(const std::string& name, const std::list<PORT *>& listOfPorts) const throw(Exception)
+    {
+      for(typename std::list<PORT *>::const_iterator iter=listOfPorts.begin();iter!=listOfPorts.end();iter++)
+       {
+         if((*iter)->getName()==name)
+           return *iter;
+       }
+      std::string what="Node::getPort : unexisting "; what+=PORT::NAME;
+      what+=" with name ";
+      what+=name;
+      throw Exception(what);
+    }
+
+    template<class PORT, class ENUMTYPE>
+    PORT *Node::edAddPort(const std::string& portName, std::list<PORT *>& listOfPorts, ENUMTYPE type) throw(Exception)
+    {
+      checkValidityOfPortName(portName);
+      if(isPortNameAlreadyExist<PORT>(portName, listOfPorts))
+       {
+         std::string what="Port of type "; what+=PORT::NAME; what += " with name : "; what+=portName; what+=" already exists";
+         throw Exception(what);
+       }
+      PORT *ret=new PORT(portName,this,type);
+      listOfPorts.push_back(ret);
+      return ret;
+    }
+
+    template<class PORT>
+    void Node::edRemovePortTypedFromList(PORT *port, std::list<PORT *>& listOfPorts) throw(Exception)
+    {
+      if(!isPortNameAlreadyExist<PORT>(port->getName(), listOfPorts))
+       throw Exception("Port is not part of the list : unable to remove it");
+      listOfPorts.remove(port);
+    }
+
+    template<class PORT>
+    bool Node::isPortNameAlreadyExist(const std::string& portName, const std::list<PORT *>& listOfPorts)
+    {
+      for(typename std::list<PORT *>::const_iterator iter=listOfPorts.begin();iter!=listOfPorts.end();iter++)
+       {
+         if((*iter)->getName()==portName)
+           return true;
+       }
+      return false;
+    }
+  }
+}
+
+#endif
diff --git a/src/engine/OutGate.cxx b/src/engine/OutGate.cxx
new file mode 100644 (file)
index 0000000..4a0ff12
--- /dev/null
@@ -0,0 +1,67 @@
+#include "OutGate.hxx"
+#include "InGate.hxx"
+
+using namespace YACS::ENGINE;
+using namespace std;
+
+const char OutGate::NAME[]="OutGate";
+
+OutGate::OutGate(Node *node):Port(node)
+{
+}
+
+std::string OutGate::getNameOfTypeOfCurrentInstance() const
+{
+  return NAME;
+}
+
+void OutGate::exNotifyDone()
+{
+  for(list<InGate *>::iterator iter=_listOfInGate.begin();iter!=_listOfInGate.end();iter++)
+    (*iter)->exNotifyFromPrecursor();
+}
+
+bool OutGate::edAddInGate(InGate *inGate)
+{
+  if(!isAlreadyInList(inGate))
+    {
+      inGate->edAppendPrecursor();
+      _listOfInGate.push_back(inGate);
+      return true;
+    }
+  else
+    return false;
+}
+
+std::list<InGate *> OutGate::edListInGate() const
+{
+  return _listOfInGate;
+}
+
+void OutGate::edRemoveInGate(InGate *inGate) throw(Exception)
+{
+  bool found=false;
+  for(list<InGate *>::iterator iter=_listOfInGate.begin();iter!=_listOfInGate.end() && !found;iter++)
+    if((*iter)==inGate)
+      {
+       _listOfInGate.erase(iter);
+       inGate->edRemovePrecursor();
+       found=true;
+      }
+  if(!found)
+    throw Exception("InGate not already connected to OutGate");
+}
+
+bool OutGate::isAlreadyInList(InGate *inGate) const
+{
+  bool ret=false;
+  for(list<InGate *>::const_iterator iter=_listOfInGate.begin();iter!=_listOfInGate.end() && !ret;iter++)
+    if((*iter)==inGate)
+      ret=true;
+  return ret;
+}
+
+int OutGate::getNbOfInGatesConnected() const
+{
+  return _listOfInGate.size();
+}
diff --git a/src/engine/OutGate.hxx b/src/engine/OutGate.hxx
new file mode 100644 (file)
index 0000000..03fd339
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef __OUTGATE_HXX__
+#define __OUTGATE_HXX__
+
+#include "Port.hxx"
+#include "Exception.hxx"
+
+#include <list>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class InGate;
+    
+    class OutGate : public Port
+    {
+    protected:
+      std::list<InGate *> _listOfInGate;
+    public:
+      static const char NAME[];
+    public:
+      OutGate(Node *node);
+      std::string getNameOfTypeOfCurrentInstance() const;
+      void exNotifyDone();
+      bool edAddInGate(InGate *inGate);
+      std::list<InGate *> edListInGate() const;
+      void edRemoveInGate(InGate *inGate) throw(Exception);
+      int getNbOfInGatesConnected() const;
+    protected:
+      bool isAlreadyInList(InGate *inGate) const;
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/OutPort.cxx b/src/engine/OutPort.cxx
new file mode 100644 (file)
index 0000000..c546035
--- /dev/null
@@ -0,0 +1,7 @@
+#include "OutPort.hxx"
+
+using namespace YACS::ENGINE;
+
+OutPort::OutPort(Node *node):Port(node)
+{
+}
diff --git a/src/engine/OutPort.hxx b/src/engine/OutPort.hxx
new file mode 100644 (file)
index 0000000..500c101
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef __OUTPORT_HXX__
+#define __OUTPORT_HXX__
+
+#include "Port.hxx"
+#include "Exception.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class InPort;
+    class OutPort : public virtual Port
+    {
+    protected:
+      OutPort(Node *node);
+    public:
+      virtual bool addInPort(InPort *inPort) throw(Exception) = 0;
+      virtual void removeInPort(InPort *inPort) throw(Exception) = 0;
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/OutputDataStreamPort.cxx b/src/engine/OutputDataStreamPort.cxx
new file mode 100644 (file)
index 0000000..2facea4
--- /dev/null
@@ -0,0 +1,57 @@
+#include "OutputDataStreamPort.hxx"
+#include "InputDataStreamPort.hxx"
+#include "TypeCheckerDataStream.hxx"
+
+using namespace YACS::ENGINE;
+
+const char OutputDataStreamPort::NAME[]="OutputDataStreamPort";
+
+OutputDataStreamPort::OutputDataStreamPort(const std::string& name, Node *node, StreamType type):DataStreamPort(name,node,type),OutPort(node),Port(node)
+{
+}
+
+std::string OutputDataStreamPort::getNameOfTypeOfCurrentInstance() const
+{
+  return NAME;
+}
+
+bool OutputDataStreamPort::edAddInputDataStreamPort(InputDataStreamPort *port) throw(ConversionException)
+{
+  if(!TypeCheckerDataStream::areStaticallyCompatible(edGetType(),port->edGetType()))
+    throw ConversionException(TypeCheckerDataStream::edGetTypeInPrintableForm(edGetType()),TypeCheckerDataStream::edGetTypeInPrintableForm(port->edGetType()));
+  if(!isAlreadyInList(port))
+    {
+      _listOfInputDataStreamPort.push_back(port);
+      return true;
+    }
+  else
+    return false;
+}
+
+void OutputDataStreamPort::edRemoveInputDataStreamPort(InputDataStreamPort *inputPort)
+{
+  if(isAlreadyInList(inputPort))
+    _listOfInputDataStreamPort.remove(inputPort);
+}
+
+bool OutputDataStreamPort::addInPort(InPort *inPort) throw(Exception)
+{
+}
+
+void OutputDataStreamPort::removeInPort(InPort *inPort) throw(Exception)
+{
+}
+
+bool OutputDataStreamPort::isLinked()
+{
+  return _listOfInputDataStreamPort.empty();
+}
+
+bool OutputDataStreamPort::isAlreadyInList(InputDataStreamPort *inputPort) const
+{
+  bool ret=false;
+  for(std::list<InputDataStreamPort *>::const_iterator iter=_listOfInputDataStreamPort.begin();iter!=_listOfInputDataStreamPort.end();iter++)
+    if((*iter)==inputPort)
+      ret=true;
+  return ret;
+}
diff --git a/src/engine/OutputDataStreamPort.hxx b/src/engine/OutputDataStreamPort.hxx
new file mode 100644 (file)
index 0000000..e4c8af6
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef __OUTPUTDATASTREAMPORT_HXX__
+#define __OUTPUTDATASTREAMPORT_HXX__
+
+#include "OutPort.hxx"
+#include "DataStreamPort.hxx"
+#include "ConversionException.hxx"
+
+#include <list>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class InputDataStreamPort;
+
+    class OutputDataStreamPort : public DataStreamPort, public OutPort
+    {
+    protected:
+      std::list<InputDataStreamPort *> _listOfInputDataStreamPort;
+    public:
+      static const char NAME[];
+    public:
+      OutputDataStreamPort(const std::string& name, Node *node, StreamType type);
+      std::string getNameOfTypeOfCurrentInstance() const;
+      bool edAddInputDataStreamPort(InputDataStreamPort *port) throw(ConversionException);
+      void edRemoveInputDataStreamPort(InputDataStreamPort *inputPort);
+      bool addInPort(InPort *inPort) throw(Exception);
+      void removeInPort(InPort *inPort) throw(Exception);
+      bool isLinked();
+    private:
+      bool isAlreadyInList(InputDataStreamPort *inputPort) const;
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/OutputPort.cxx b/src/engine/OutputPort.cxx
new file mode 100644 (file)
index 0000000..c17dfc1
--- /dev/null
@@ -0,0 +1,100 @@
+#include "OutputPort.hxx"
+#include "InputPort.hxx"
+
+using namespace YACS::ENGINE;
+using namespace std;
+
+const char OutputPort::NAME[]="OutputPort";
+
+OutputPort::OutputPort(const std::string& name, Node *node, DynType type):DataFlowPort(name,node,type),OutPort(node),Port(node)
+{
+}
+
+std::string OutputPort::getNameOfTypeOfCurrentInstance() const
+{
+  return NAME;
+}
+
+Data OutputPort::foGet() const
+{
+  return _data;
+}
+
+void OutputPort::exInit()
+{
+  _data.exInit();
+}
+
+void OutputPort::exPut(Data data) throw(ConversionException)
+{
+  _data=data;
+  for(list<InputPort *>::iterator iter=_listOfInputPort.begin();iter!=_listOfInputPort.end();iter++)
+    (*iter)->exAccept(data);
+}
+
+bool OutputPort::edAddInputPort(InputPort *inputPort) throw(ConversionException)
+{
+  if(!Data::areStaticallyCompatible(edGetType(),inputPort->edGetType()))
+    throw ConversionException(Data::edGetTypeInPrintableForm(edGetType()),Data::edGetTypeInPrintableForm(inputPort->edGetType()));
+  if(!isAlreadyInList(inputPort))
+    {
+      _listOfInputPort.push_back(inputPort);
+      inputPort->edNotifyReferenced();
+      return true;
+    }
+  else
+    return false;
+}
+
+list<InputPort *> OutputPort::edListInputPort()
+{
+  return _listOfInputPort;
+}
+
+void OutputPort::edRemoveInputPort(InputPort *inputPort) throw(Exception)
+{
+  if(isAlreadyInList(inputPort))
+    _listOfInputPort.remove(inputPort);
+  else
+    throw Exception("OutputPort::edRemoveInputPort : link does not exist, unable to remove it");
+}
+
+OutputPort::~OutputPort()
+{
+}
+
+bool OutputPort::isAlreadyInList(InputPort *inputPort) const
+{
+  bool ret=false;
+  for(list<InputPort *>::const_iterator iter=_listOfInputPort.begin();iter!=_listOfInputPort.end() && !ret;iter++)
+    if((*iter)==inputPort)
+      ret=true;
+  return ret;
+}
+
+bool OutputPort::addInPort(InPort *inPort) throw(Exception)
+{
+  if(inPort->getNameOfTypeOfCurrentInstance()!=InputPort::NAME)
+    {
+      std::string what="not compatible type of port requested during building of link FROM ";
+      what+=NAME; what+=" TO "; what+=inPort->getNameOfTypeOfCurrentInstance();
+      throw Exception(what);
+    }
+  return edAddInputPort(static_cast<InputPort*>(inPort));
+}
+
+void OutputPort::removeInPort(InPort *inPort) throw(Exception)
+{
+  if(inPort->getNameOfTypeOfCurrentInstance()!=InputPort::NAME)
+    {
+      std::string what="not compatible type of port requested during destruction of for link FROM ";
+      what+=NAME; what+=" TO "; what+=inPort->getNameOfTypeOfCurrentInstance();
+      throw Exception(what);
+    }
+  edRemoveInputPort(static_cast<InputPort*>(inPort));
+}
+
+bool OutputPort::isLinked()
+{
+  return _listOfInputPort.empty();
+}
diff --git a/src/engine/OutputPort.hxx b/src/engine/OutputPort.hxx
new file mode 100644 (file)
index 0000000..7f6c3df
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __OUTPUTPORT_HXX__
+#define __OUTPUTPORT_HXX__
+
+#include "OutPort.hxx"
+#include "DataFlowPort.hxx"
+#include "ConversionException.hxx"
+
+#include <list>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class InputPort;
+
+    class OutputPort : public DataFlowPort, public OutPort
+    {
+    protected:
+      std::list<InputPort *> _listOfInputPort;
+    public:
+      static const char NAME[];
+    public:
+      OutputPort(const std::string& name, Node *node, DynType type);
+      ~OutputPort();
+      std::string getNameOfTypeOfCurrentInstance() const;
+      Data foGet() const;
+      void exInit();
+      void exPut(Data data) throw(ConversionException);
+      bool edAddInputPort(InputPort *inputPort) throw(ConversionException);
+      std::list<InputPort *> edListInputPort();
+      void edRemoveInputPort(InputPort *inputPort) throw(Exception);
+      bool addInPort(InPort *inPort) throw(Exception);
+      void removeInPort(InPort *inPort) throw(Exception);
+      bool isLinked();
+      bool isAlreadyInList(InputPort *inputPort) const;
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/Port.cxx b/src/engine/Port.cxx
new file mode 100644 (file)
index 0000000..1fc5920
--- /dev/null
@@ -0,0 +1,18 @@
+#include "Port.hxx"
+
+using namespace YACS::ENGINE;
+
+const char Port::NAME[]="Port";
+
+Port::Port(Node *node):_node(node)
+{
+}
+
+Port::~Port()
+{
+}
+
+std::string Port::getNameOfTypeOfCurrentInstance() const
+{
+  return NAME;
+}
diff --git a/src/engine/Port.hxx b/src/engine/Port.hxx
new file mode 100644 (file)
index 0000000..69ce0bf
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __PORT_HXX__
+#define __PORT_HXX__
+
+#include <string>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Node;
+  }
+}
+
+/**
+ *
+ * Not instanciable class that factorizes all basic data and behaviours relative the in and out interfaces of all nodes.
+ * End-user should not neither instanciate a sub-class of 'Port' nor called other methods than accessor.
+ *
+ */
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Port
+    {
+    protected:
+      Node *_node;//NOT OWNERED
+    public:
+      static const char NAME[];
+    protected:
+      Port(Node *node);
+    public:
+      virtual ~Port();
+      Node *getNode() const { return _node; }
+      virtual std::string getNameOfTypeOfCurrentInstance() const;
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/Scheduler.hxx b/src/engine/Scheduler.hxx
new file mode 100644 (file)
index 0000000..00c25cf
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __SCHEDULER_HXX__
+#define __SCHEDULER_HXX__
+
+#include <vector>
+#include "define.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Task;
+    
+    class Scheduler
+    {
+    public:
+      virtual void init() = 0;
+      virtual bool isFinished() = 0;
+      virtual std::vector<Task *> getNextTasks(bool& isMore) = 0;
+      virtual void selectRunnableTasks(std::vector<Task *>& tasks) = 0;
+      virtual void notifyFrom(const Task *sender, YACS::Event event) = 0;
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/Switch.cxx b/src/engine/Switch.cxx
new file mode 100644 (file)
index 0000000..93779d6
--- /dev/null
@@ -0,0 +1,28 @@
+#include "Switch.hxx"
+
+using namespace YACS::ENGINE;
+
+Switch::Switch(const std::string& name):ComposedNode(name)
+{
+}
+
+Switch::~Switch()
+{
+}
+
+void Switch::edSetNumberOfCases(int numberOfCases)
+{
+  _vectorOfNode.resize(numberOfCases);
+}
+
+void Switch::edSetNode(int caseId, Node *node) throw(Exception)
+{
+  if(caseId>=_vectorOfNode.size())
+    throw Exception("Switch::edSetNode : caseId is too large compared to number of cases");
+  _vectorOfNode[caseId]=node;
+}
+
+void Switch::checkNoCyclePassingThrough(Node *node) throw(Exception)
+{
+  throw Exception("Switch::checkNoCyclePassingThrough : uncorrect control flow link relative to switch");
+}
diff --git a/src/engine/Switch.hxx b/src/engine/Switch.hxx
new file mode 100644 (file)
index 0000000..34687bb
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef __SWITCH_HXX__
+#define __SWITCH_HXX__
+
+#include "ComposedNode.hxx"
+
+#include <vector>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Switch : public ComposedNode
+    {
+    protected:
+      std::vector<Node *> _vectorOfNode;//Nodes ownered
+    public:
+      Switch(const std::string& name);
+      ~Switch();
+      void edSetNumberOfCases(int numberOfCases);
+      void edSetNode(int caseId, Node *node) throw(Exception);
+    protected:
+      void checkNoCyclePassingThrough(Node *node) throw(Exception);
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/Task.hxx b/src/engine/Task.hxx
new file mode 100644 (file)
index 0000000..2f20fe7
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __TASK_HXX__
+#define __TASK_HXX__
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Task
+    {
+    public:
+      virtual void begin() = 0;
+      virtual bool isReady() = 0;
+      virtual void execute() = 0;
+      virtual void finished() = 0;
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/Test/Makefile.am b/src/engine/Test/Makefile.am
new file mode 100644 (file)
index 0000000..c79eed9
--- /dev/null
@@ -0,0 +1,36 @@
+
+include $(top_srcdir)/adm/unix/make_begin.am
+
+check_PROGRAMS = testPorts testBloc
+
+testPorts_SOURCES = testPorts.cxx ToyNode.cxx
+
+testPorts_LDADD = ../libYACSEngine.la \
+                  ../../bases/libYACSBases.la \
+                  ../../basicData/libYACSBasicData.la 
+
+
+testPorts_LDFLAGS = $(CPPUNIT_LIBS) -pthread -ldl
+
+testPorts_CXXFLAGS = $(CPPUNIT_INCLUDES) \
+                     -I$(srcdir)/.. \
+                     -I$(srcdir)/../../bases \
+                     -I$(srcdir)/../../basicData
+
+testBloc_SOURCES = testBloc.cxx ToyNode.cxx
+
+testBloc_LDADD =  ../libYACSEngine.la \
+                  ../../bases/libYACSBases.la \
+                  ../../basicData/libYACSBasicData.la 
+
+
+testBloc_LDFLAGS = $(CPPUNIT_LIBS) -pthread -ldl
+
+testBloc_CXXFLAGS = $(THREAD_DEF) $(CPPUNIT_INCLUDES) \
+                     -I$(srcdir)/..               \
+                     -I$(srcdir)/../../bases      \
+                     -I$(srcdir)/../../basicData
+
+TESTS = testPorts testBloc
+
+include $(top_srcdir)/adm/unix/make_end.am
diff --git a/src/engine/Test/ToyNode.cxx b/src/engine/Test/ToyNode.cxx
new file mode 100644 (file)
index 0000000..e182109
--- /dev/null
@@ -0,0 +1,72 @@
+#include "ToyNode.hxx"
+#include "InputPort.hxx"
+#include "OutputPort.hxx"
+
+#include <iostream>
+
+using namespace std;
+
+#define TAB_LENGTH 100
+
+using namespace YACS::ENGINE;
+
+ToyNode::ToyNode(const std::string& name, int time):ElementaryNode(name),_time(time)
+{
+}
+InputPort *ToyNode::edAddInputPort(const std::string& inputPortName)
+{
+  return edAddInputPort(inputPortName, YACS::Double);
+}
+
+OutputPort *ToyNode::edAddOutputPort(const std::string& outputPortName)
+{
+  return edAddOutputPort(outputPortName, YACS::Double);
+}
+
+InputPort *ToyNode::edAddInputPort(const std::string& inputPortName, YACS::DynType type) throw(Exception)
+{
+  if(type!=YACS::Double)
+    throw Exception("ToyNode only deals double dataflow ports");
+  return ElementaryNode::edAddInputPort(inputPortName,type);
+}
+
+OutputPort *ToyNode::edAddOutputPort(const std::string& outputPortName, YACS::DynType type) throw(Exception)
+{
+  if(type!=YACS::Double)
+    throw Exception("ToyNode only deals double dataflow ports");
+  return ElementaryNode::edAddOutputPort(outputPortName,type);
+}
+
+InputDataStreamPort *ToyNode::edAddInputDataStreamPort(const std::string& inputPortDSName, YACS::StreamType type) throw(Exception)
+{
+  throw Exception("ToyNode Not designed to support DataStream");
+}
+
+OutputDataStreamPort *ToyNode::edAddOutputDataStreamPort(const std::string& outputPortDSName, YACS::StreamType type) throw(Exception)
+{
+  throw Exception("ToyNode Not designed to support DataStream");
+}
+
+void ToyNode::execute()
+{
+  std::list<InputPort *>::iterator iter;
+  double sum=0.;
+  for(iter=_listOfInputPort.begin();iter!=_listOfInputPort.end();iter++)
+    sum+=(*iter)->exGet().exGet<double>();
+  cerr << "Node " << _name << " executing " << sum << endl;
+  double tab[TAB_LENGTH];
+  if(_time!=0)
+    {
+      for(int i=0;i<100000;i++)
+       for(int j=0;j<20*_time;j++)
+         tab[((i+j)/2)%TAB_LENGTH]=i*i*j;
+    }
+  cerr << "Node " << _name << " executing " << sum << endl;
+  if(_listOfOutputPort.empty())
+    return;
+  sum/=_listOfOutputPort.size();
+  std::list<OutputPort *>::iterator iter2;
+  for(iter2=_listOfOutputPort.begin();iter2!=_listOfOutputPort.end();iter2++)
+    (*iter2)->exPut(sum);
+}
+
diff --git a/src/engine/Test/ToyNode.hxx b/src/engine/Test/ToyNode.hxx
new file mode 100644 (file)
index 0000000..173f802
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __TOYNODE_HXX__
+#define __TOYNODE_HXX__
+
+#include "ElementaryNode.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class ToyNode : public ElementaryNode
+    {
+    private:
+      int _time;
+    public:
+      ToyNode(const std::string& name, int time=0);
+      void setTime(int time) { _time=time; }
+      InputPort *edAddInputPort(const std::string& inputPortName);
+      OutputPort *edAddOutputPort(const std::string& outputPortName);
+      InputPort *edAddInputPort(const std::string& inputPortName, YACS::DynType type) throw(Exception);
+      OutputPort *edAddOutputPort(const std::string& outputPortName, YACS::DynType type) throw(Exception);
+      InputDataStreamPort *edAddInputDataStreamPort(const std::string& inputPortDSName, YACS::StreamType type) throw(Exception);
+      OutputDataStreamPort *edAddOutputDataStreamPort(const std::string& outputPortDSName, YACS::StreamType type) throw(Exception);
+      void execute();
+    };
+  }
+}
+
+#endif
diff --git a/src/engine/Test/testBloc.cxx b/src/engine/Test/testBloc.cxx
new file mode 100644 (file)
index 0000000..eabd4ce
--- /dev/null
@@ -0,0 +1,153 @@
+#ifndef __TESTBLOC_HXX__
+#define __TESTBLOC_HXX__
+
+#include "Bloc.hxx"
+#include "Data.hxx"
+#include "ToyNode.hxx"
+#include "Executor.hxx"
+#include "Exception.hxx"
+#include "InputPort.hxx"
+#include "OutputPort.hxx"
+//
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <sstream>
+#include <string.h>
+//
+
+#define DBL_PRECISION_COMPARE 1e-15
+
+using namespace YACS::ENGINE;
+
+class BlocTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( BlocTest );
+  CPPUNIT_TEST( test1 );
+  CPPUNIT_TEST( test2 );
+  CPPUNIT_TEST( test3 );
+  CPPUNIT_TEST_SUITE_END();
+public: 
+  void tearDown();
+  void test1();
+  void test2();
+  void test3();
+};
+
+void BlocTest::tearDown()
+{
+}
+
+//Simplest test to test basic mechanisms like Data, initialisation of ports.
+void BlocTest::test1()
+{
+  ToyNode *n1=new ToyNode("T1");
+  InputPort *i8=n1->edAddInputPort("o");
+  InputPort *i9=n1->edAddInputPort("p");
+  Bloc *graph=new Bloc("toto");
+  graph->edAddChild(n1);
+  OutputPort *o1=n1->edAddOutputPort("b");
+  Data v1(5.67);
+  i9->edInit(v1);
+  v1=2.78;
+  i8->edInit(v1);
+  Executor exe;
+  exe.RunW(graph);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL( o1->foGet().exGet<double>(),8.45,DBL_PRECISION_COMPARE );
+  OutputPort *o2=n1->edAddOutputPort("c");
+  exe.RunW(graph);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL( o1->foGet().exGet<double>(),4.225,DBL_PRECISION_COMPARE );
+  delete graph;
+}
+
+//Only one level(hierarchy) simple graph. Tests DF and CF links.
+void BlocTest::test2()
+{
+  ToyNode *n1=new ToyNode("T1");
+  ToyNode *n2=new ToyNode("T2",50);
+  ToyNode *n3=new ToyNode("T3",20);
+  ToyNode *n4=new ToyNode("T4");
+  Bloc *graph=new Bloc("Global");
+  graph->edAddChild(n1); graph->edAddChild(n2); graph->edAddChild(n3); graph->edAddChild(n4);
+  InputPort *i1_a=n1->edAddInputPort("a"); InputPort *i1_b=n1->edAddInputPort("b"); OutputPort *o1_j=n1->edAddOutputPort("j"); OutputPort *o1_k=n1->edAddOutputPort("k");
+  InputPort *i2_c=n2->edAddInputPort("c"); InputPort *i2_d=n2->edAddInputPort("d"); OutputPort *o2_f=n2->edAddOutputPort("f");
+  InputPort *i3_e=n3->edAddInputPort("e"); OutputPort *o3_g=n3->edAddOutputPort("g"); OutputPort *o3_h=n3->edAddOutputPort("h");
+  InputPort *i4_l=n4->edAddInputPort("l"); InputPort *i4_m=n4->edAddInputPort("m"); OutputPort *o4_i=n4->edAddOutputPort("i");
+  //Retrieving gates
+  InGate *iN1=n1->getInGate(); InGate *iN2=n2->getInGate(); InGate *iN3=n3->getInGate(); InGate *iN4=n4->getInGate();
+  OutGate *oN1=n1->getOutGate(); OutGate *oN2=n2->getOutGate(); OutGate *oN3=n3->getOutGate(); OutGate *oN4=n4->getOutGate();
+  Data v1(1.2);
+  i1_a->edInit(v1);
+  v1=3.4;
+  i1_b->edInit(v1);
+  v1=7;
+  i2_d->edInit(v1);
+  //DF                                                                      //CF
+  graph->edAddLink(o1_j,i2_c);                                              graph->edAddLink(oN1,iN2);
+  graph->edAddLink(o1_k,i3_e);                                              graph->edAddLink(oN1,iN3);
+  graph->edAddLink(o2_f,i4_l);                                              graph->edAddLink(oN2,iN4);
+  graph->edAddLink(o3_g,i4_m);                                              graph->edAddLink(oN3,iN4);
+  Executor exe;
+  exe.RunW(graph);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL( o4_i->foGet().exGet<double>(),10.45,DBL_PRECISION_COMPARE );
+  n2->setTime(0); n3->setTime(0);
+  exe.RunW(graph);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL( o4_i->foGet().exGet<double>(),10.45,DBL_PRECISION_COMPARE );
+  bool testOfCycleSucceed=false;
+  try
+    { graph->edAddLink(oN4,iN1); }
+  catch(YACS::Exception &e)
+    { if(strcmp(e.what(),"Cycle has been detected")==0)
+      testOfCycleSucceed=true; }
+  CPPUNIT_ASSERT(testOfCycleSucceed);
+  delete graph;
+}
+
+//test multi level graphs
+void BlocTest::test3()
+{
+  Bloc *toto=new Bloc("toto");
+  Bloc *tata=new Bloc("tata");
+  Bloc *titi=new Bloc("titi");
+  ToyNode *n2=new ToyNode("T2"); ToyNode *n3=new ToyNode("T3"); ToyNode *n4=new ToyNode("T4"); ToyNode *n5=new ToyNode("T5"); ToyNode *n6=new ToyNode("T6");
+  ToyNode *n7=new ToyNode("T7",20); ToyNode *n8=new ToyNode("T8");
+  toto->edAddChild(titi); titi->edAddChild(tata); titi->edAddChild(n3); toto->edAddChild(n2); tata->edAddChild(n4); tata->edAddChild(n5); tata->edAddChild(n6);
+  titi->edAddChild(n7); titi->edAddChild(n8);
+  toto->edAddCFLink(n2,titi); toto->edAddCFLink(n3,tata); toto->edAddCFLink(n5,n4); titi->edAddCFLink(n7,n8); titi->edAddCFLink(tata,n8);
+  //
+  InputPort *i2_a=n2->edAddInputPort("a"); OutputPort *o2_a=n2->edAddOutputPort("a"); OutputPort *o2_b=n2->edAddOutputPort("b");
+  InputPort *i3_a=n3->edAddInputPort("a"); OutputPort *o3_a=n3->edAddOutputPort("a"); OutputPort *o3_b=n3->edAddOutputPort("b");
+  InputPort *i4_a=n4->edAddInputPort("a"); InputPort *i4_b=n4->edAddInputPort("b"); OutputPort *o4_a=n4->edAddOutputPort("a"); OutputPort *o4_b=n4->edAddOutputPort("b");
+  InputPort *i5_a=n5->edAddInputPort("a"); InputPort *i5_b=n5->edAddInputPort("b"); OutputPort *o5_a=n5->edAddOutputPort("a");
+  InputPort *i6_a=n6->edAddInputPort("a"); InputPort *i6_b=n6->edAddInputPort("b"); OutputPort *o6_a=n6->edAddOutputPort("a");
+  InputPort *i7_a=n7->edAddInputPort("a"); OutputPort *o7_a=n7->edAddOutputPort("a");
+  InputPort *i8_a=n8->edAddInputPort("a"); InputPort *i8_b=n8->edAddInputPort("b"); OutputPort *o8_a=n8->edAddOutputPort("a");
+  //
+  toto->edAddLink(o2_a,i3_a);  toto->edAddLink(o3_a,i5_a); toto->edAddLink(o2_b,i5_b); toto->edAddLink(o2_a,i4_b);
+  toto->edAddLink(o3_b,i6_a); toto->edAddLink(o6_a,i8_a); toto->edAddLink(o7_a,i8_b);
+  //
+  Data v1(1.2);
+  i2_a->edInit(v1);
+  v1=7;
+  i6_b->edInit(v1);
+  i4_a->edInit(v1);
+  v1=3;
+  i7_a->edInit(v1);
+  CPPUNIT_ASSERT( toto->getNumberOfCFLinks()== 1 ); CPPUNIT_ASSERT( titi->getNumberOfCFLinks()== 3 ); CPPUNIT_ASSERT( tata->getNumberOfCFLinks()== 1 );
+  Executor exe;
+  exe.RunW(toto);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL( o6_a->foGet().exGet<double>(),7.3,DBL_PRECISION_COMPARE );
+  CPPUNIT_ASSERT_DOUBLES_EQUAL( o4_a->foGet().exGet<double>(),3.8,DBL_PRECISION_COMPARE );
+  CPPUNIT_ASSERT_DOUBLES_EQUAL( o8_a->foGet().exGet<double>(),10.3,DBL_PRECISION_COMPARE );
+  delete toto;
+}
+
+int main()
+{
+  CppUnit::TextUi::TestRunner runner;
+  runner.addTest( BlocTest::suite() );
+  runner.run();
+  return 0;
+}
+
+
+#endif
diff --git a/src/engine/Test/testPorts.cxx b/src/engine/Test/testPorts.cxx
new file mode 100644 (file)
index 0000000..11f9080
--- /dev/null
@@ -0,0 +1,103 @@
+#include "Node.hxx"
+#include "Data.hxx"
+#include "InGate.hxx"
+#include "OutGate.hxx"
+#include "InputPort.hxx"
+#include "OutputPort.hxx"
+//
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <sstream>
+//
+
+using namespace YACS::ENGINE;
+
+class PortsTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( PortsTest );
+  CPPUNIT_TEST( testControlFlow );
+  CPPUNIT_TEST( testDataFlow1 );
+  CPPUNIT_TEST_EXCEPTION( testDataFlowTypeCheck, YACS::ENGINE::ConversionException);
+  CPPUNIT_TEST_SUITE_END();
+public: 
+  void tearDown();
+  void testControlFlow();
+  void testDataFlow1();
+  void testDataFlowTypeCheck();
+};
+
+void PortsTest::tearDown()
+{
+}
+
+void PortsTest::testControlFlow()
+{
+  Node *n1=0,*n2=0,*n3=0,*n4=0;
+  OutGate *o1=new OutGate(n1);
+  OutGate *o2=new OutGate(n2);
+  OutGate *o3=new OutGate(n3);
+  OutGate *o4=new OutGate(n4);
+  InGate *i1=new InGate(n1);
+  InGate *i2=new InGate(n2);
+  InGate *i3=new InGate(n3);
+  InGate *i4=new InGate(n4);
+  // Simuling edition
+  o1->edAddInGate(i2); o1->edAddInGate(i3);
+  o2->edAddInGate(i2); o2->edAddInGate(i4);
+  o3->edAddInGate(i2); o3->edAddInGate(i4); o3->edAddInGate(i3);
+  o4->edAddInGate(i2); o4->edAddInGate(i4);
+  // Simuling execution
+  CPPUNIT_ASSERT( i1->exIsReady() ); CPPUNIT_ASSERT( !i2->exIsReady() ); CPPUNIT_ASSERT( !i3->exIsReady() ); CPPUNIT_ASSERT( !i4->exIsReady() );
+  o1->exNotifyDone();
+  CPPUNIT_ASSERT( i1->exIsReady() ); CPPUNIT_ASSERT( !i2->exIsReady() ); CPPUNIT_ASSERT( !i3->exIsReady() ); CPPUNIT_ASSERT( !i4->exIsReady() );
+  o2->exNotifyDone();
+  CPPUNIT_ASSERT( i1->exIsReady() ); CPPUNIT_ASSERT( !i2->exIsReady() ); CPPUNIT_ASSERT( !i3->exIsReady() ); CPPUNIT_ASSERT( !i4->exIsReady() );
+  o3->exNotifyDone();
+  CPPUNIT_ASSERT( i1->exIsReady() ); CPPUNIT_ASSERT( !i2->exIsReady() ); CPPUNIT_ASSERT( i3->exIsReady() ); CPPUNIT_ASSERT( !i4->exIsReady() );
+  o4->exNotifyDone();
+  CPPUNIT_ASSERT( i1->exIsReady() ); CPPUNIT_ASSERT( i2->exIsReady() ); CPPUNIT_ASSERT( i3->exIsReady() ); CPPUNIT_ASSERT( i4->exIsReady() );
+  //
+  delete o1; delete o2; delete o3; delete o4;
+  delete i1; delete i2; delete i3; delete i4;
+}
+
+void PortsTest::testDataFlow1()
+{
+  Node *n1=0,*n2=0,*n3=0,*n4=0;
+  OutputPort *o1=new OutputPort("o1",n1,YACS::Double);
+  OutputPort *o3=new OutputPort("o3",n3,YACS::Int);
+  InputPort *i1=new InputPort("i1",n1,YACS::Double);
+  InputPort *i2=new InputPort("i2",n2,YACS::Int);
+  InputPort *i4=new InputPort("i4",n4,YACS::Bool);
+  // Simuling edition
+  o1->edAddInputPort(i1); o1->edAddInputPort(i2);
+  o3->edAddInputPort(i1); o3->edAddInputPort(i2); o3->edAddInputPort(i4);
+  CPPUNIT_ASSERT( o1->foGet().edGetRepresentation() == "41_NULL" ); CPPUNIT_ASSERT( o3->foGet().edGetRepresentation() == "42_NULL" );
+  CPPUNIT_ASSERT( i1->exGet().edGetRepresentation() == "41_NULL" ); CPPUNIT_ASSERT( i2->exGet().edGetRepresentation() == "42_NULL" ); CPPUNIT_ASSERT( i4->exGet().edGetRepresentation() == "45_NULL" );
+  // Simuling execution
+  o1->exPut(3.14);
+  CPPUNIT_ASSERT( i1->exGet().edGetRepresentation() == "41_3.14" ); CPPUNIT_ASSERT( i2->exGet().edGetRepresentation() == "42_3" ); CPPUNIT_ASSERT( i4->exGet().edGetRepresentation() == "45_NULL" );
+  o3->exPut(325);
+  CPPUNIT_ASSERT( i1->exGet().edGetRepresentation() == "41_325" ); CPPUNIT_ASSERT( i2->exGet().edGetRepresentation() == "42_325" ); CPPUNIT_ASSERT( i4->exGet().edGetRepresentation() == "45_1" );
+  o1->exPut(-2.78);
+  CPPUNIT_ASSERT( i1->exGet().edGetRepresentation() == "41_-2.78" ); CPPUNIT_ASSERT( i2->exGet().edGetRepresentation() == "42_-2" ); CPPUNIT_ASSERT( i4->exGet().edGetRepresentation() == "45_1" );
+  //
+  delete o1; delete o3;
+  delete i1; delete i2; delete i4;
+}
+
+void PortsTest::testDataFlowTypeCheck()
+{
+  Node *n1=0;
+  OutputPort o1("o1",n1,YACS::Double);
+  InputPort i1("i1",n1,YACS::Bool);
+  o1.edAddInputPort(&i1);//Should throw exception
+}
+
+int main()
+{
+  CppUnit::TextUi::TestRunner runner;
+  runner.addTest( PortsTest::suite() );
+  runner.run();
+  return 0;
+}