From 24ab175e1695bf31f5b1f47b43ec8b45322dc6d3 Mon Sep 17 00:00:00 2001 From: prascle Date: Wed, 25 Oct 2006 08:26:22 +0000 Subject: [PATCH] PR: merge from BR_DATACONV_PR tag "mergeto_trunk_25oct06" --- COPYING | 340 ++++++ INSTALL | 273 ++++- README | 20 + adm/unix/config_files/check_omniorb.m4 | 313 +++++ adm/unix/make_end.am | 11 +- build_configure | 3 +- configure.in.base | 3 +- doc/Doxyfile | 273 +++++ root_clean | 1 - src/Makefile.am | 2 +- src/bases/Test/BasicMainTest.hxx | 88 ++ src/bases/Test/Makefile.am | 14 +- src/bases/Test/TestBases.cxx | 14 + src/bases/Test/basesTest.cxx | 99 ++ src/bases/Test/basesTest.hxx | 49 + src/bases/Test/test1.cxx | 139 --- src/bases/define.hxx | 26 +- src/basicData/ContentOfDataFlow.cxx | 104 -- src/basicData/ContentOfDataFlow.hxx | 88 -- src/basicData/ConversionException.cxx | 14 - src/basicData/Data.cxx | 127 -- src/basicData/Data.hxx | 84 -- src/basicData/Makefile.am | 26 - src/basicData/Test/Makefile.am | 21 - src/basicData/Test/testData.cxx | 118 -- src/basicData/TypeCheckerDataFlow.cxx | 11 - src/basicData/TypeCheckerDataFlow.hxx | 332 ------ src/basicData/TypeCheckerDataStream.cxx | 127 -- src/basicData/TypeCheckerDataStream.hxx | 24 - src/engine/Bloc.cxx | 132 ++- src/engine/Bloc.hxx | 6 +- src/engine/ComposedNode.cxx | 165 ++- src/engine/ComposedNode.hxx | 15 +- src/engine/ConversionException.cxx | 12 + .../ConversionException.hxx | 2 +- src/engine/DataFlowPort.cxx | 21 +- src/engine/DataFlowPort.hxx | 10 +- src/engine/DataStreamPort.cxx | 5 +- src/engine/DataStreamPort.hxx | 8 +- src/engine/ElementaryNode.cxx | 131 +- src/engine/ElementaryNode.hxx | 15 +- src/engine/Executor.cxx | 9 +- src/engine/InGate.cxx | 3 +- src/engine/InputDataStreamPort.cxx | 5 +- src/engine/InputDataStreamPort.hxx | 2 +- src/engine/InputPort.cxx | 44 +- src/engine/InputPort.hxx | 49 +- src/engine/Loop.cxx | 180 +-- src/engine/Loop.hxx | 30 +- src/engine/Makefile.am | 9 +- src/engine/Node.cxx | 112 +- src/engine/Node.hxx | 95 +- src/engine/OutGate.cxx | 35 +- src/engine/OutGate.hxx | 11 +- src/engine/OutputDataStreamPort.cxx | 35 +- src/engine/OutputDataStreamPort.hxx | 14 +- src/engine/OutputPort.cxx | 82 +- src/engine/OutputPort.hxx | 41 +- src/engine/Port.cxx | 14 +- src/engine/Port.hxx | 40 +- src/engine/Runtime.cxx | 53 + src/engine/Runtime.hxx | 70 ++ src/engine/Switch.cxx | 3 +- src/engine/Test/Makefile.am | 38 +- src/engine/Test/TestEngine.cxx | 13 + src/engine/Test/ToyNode.cxx | 72 -- src/engine/Test/ToyNode.hxx | 28 - src/engine/Test/engineTest.cxx | 338 ++++++ src/engine/Test/engineTest.hxx | 66 ++ src/engine/Test/testBloc.cxx | 153 --- src/engine/Test/testPorts.cxx | 103 -- src/engine/TypeCode.cxx | 181 +++ src/engine/TypeCode.hxx | 102 ++ src/runtime/CORBACORBAConv.cxx | 29 + src/runtime/CORBACORBAConv.hxx | 23 + src/runtime/CORBANode.cxx | 158 +++ src/runtime/CORBANode.hxx | 28 + src/runtime/CORBAPorts.cxx | 167 +++ src/runtime/CORBAPorts.hxx | 45 + src/runtime/CORBAPythonConv.cxx | 113 ++ src/runtime/CORBAPythonConv.hxx | 63 + src/runtime/CORBAXMLConv.cxx | 37 + src/runtime/CORBAXMLConv.hxx | 23 + src/runtime/CppNode.cxx | 48 + src/runtime/CppNode.hxx | 29 + src/runtime/Makefile.am | 38 + src/runtime/PythonCORBAConv.cxx | 152 +++ src/runtime/PythonCORBAConv.hxx | 63 + src/runtime/PythonNode.cxx | 79 ++ src/runtime/PythonNode.hxx | 25 + src/runtime/PythonPorts.cxx | 65 + src/runtime/PythonPorts.hxx | 42 + src/runtime/RuntimeSALOME.cxx | 592 +++++++++ src/runtime/RuntimeSALOME.hxx | 124 ++ src/runtime/Test/Makefile.am | 52 + src/runtime/Test/TestRuntime.cxx | 13 + src/runtime/Test/echo.idl | 70 ++ src/runtime/Test/echoSrv.cxx | 394 ++++++ src/runtime/Test/runtimeTest.cxx | 971 +++++++++++++++ src/runtime/Test/runtimeTest.hxx | 30 + src/runtime/Test/runtimeTest.sh | 31 + src/runtime/TypeConversions.cxx | 1053 +++++++++++++++++ src/runtime/TypeConversions.hxx | 53 + src/runtime/XMLCORBAConv.cxx | 51 + src/runtime/XMLCORBAConv.hxx | 22 + src/runtime/XMLNode.cxx | 39 + src/runtime/XMLNode.hxx | 26 + src/runtime/XMLPorts.cxx | 63 + src/runtime/XMLPorts.hxx | 37 + 109 files changed, 8069 insertions(+), 2075 deletions(-) create mode 100644 COPYING create mode 100644 adm/unix/config_files/check_omniorb.m4 create mode 100644 doc/Doxyfile create mode 100644 src/bases/Test/BasicMainTest.hxx create mode 100644 src/bases/Test/TestBases.cxx create mode 100644 src/bases/Test/basesTest.cxx create mode 100644 src/bases/Test/basesTest.hxx delete mode 100644 src/bases/Test/test1.cxx delete mode 100644 src/basicData/ContentOfDataFlow.cxx delete mode 100644 src/basicData/ContentOfDataFlow.hxx delete mode 100644 src/basicData/ConversionException.cxx delete mode 100644 src/basicData/Data.cxx delete mode 100644 src/basicData/Data.hxx delete mode 100644 src/basicData/Makefile.am delete mode 100644 src/basicData/Test/Makefile.am delete mode 100644 src/basicData/Test/testData.cxx delete mode 100644 src/basicData/TypeCheckerDataFlow.cxx delete mode 100644 src/basicData/TypeCheckerDataFlow.hxx delete mode 100644 src/basicData/TypeCheckerDataStream.cxx delete mode 100644 src/basicData/TypeCheckerDataStream.hxx create mode 100644 src/engine/ConversionException.cxx rename src/{basicData => engine}/ConversionException.hxx (77%) create mode 100644 src/engine/Runtime.cxx create mode 100644 src/engine/Runtime.hxx create mode 100644 src/engine/Test/TestEngine.cxx delete mode 100644 src/engine/Test/ToyNode.cxx delete mode 100644 src/engine/Test/ToyNode.hxx create mode 100644 src/engine/Test/engineTest.cxx create mode 100644 src/engine/Test/engineTest.hxx delete mode 100644 src/engine/Test/testBloc.cxx delete mode 100644 src/engine/Test/testPorts.cxx create mode 100644 src/engine/TypeCode.cxx create mode 100644 src/engine/TypeCode.hxx create mode 100644 src/runtime/CORBACORBAConv.cxx create mode 100644 src/runtime/CORBACORBAConv.hxx create mode 100644 src/runtime/CORBANode.cxx create mode 100644 src/runtime/CORBANode.hxx create mode 100644 src/runtime/CORBAPorts.cxx create mode 100644 src/runtime/CORBAPorts.hxx create mode 100644 src/runtime/CORBAPythonConv.cxx create mode 100644 src/runtime/CORBAPythonConv.hxx create mode 100644 src/runtime/CORBAXMLConv.cxx create mode 100644 src/runtime/CORBAXMLConv.hxx create mode 100644 src/runtime/CppNode.cxx create mode 100644 src/runtime/CppNode.hxx create mode 100644 src/runtime/Makefile.am create mode 100644 src/runtime/PythonCORBAConv.cxx create mode 100644 src/runtime/PythonCORBAConv.hxx create mode 100644 src/runtime/PythonNode.cxx create mode 100644 src/runtime/PythonNode.hxx create mode 100644 src/runtime/PythonPorts.cxx create mode 100644 src/runtime/PythonPorts.hxx create mode 100644 src/runtime/RuntimeSALOME.cxx create mode 100644 src/runtime/RuntimeSALOME.hxx create mode 100644 src/runtime/Test/Makefile.am create mode 100644 src/runtime/Test/TestRuntime.cxx create mode 100644 src/runtime/Test/echo.idl create mode 100644 src/runtime/Test/echoSrv.cxx create mode 100644 src/runtime/Test/runtimeTest.cxx create mode 100644 src/runtime/Test/runtimeTest.hxx create mode 100644 src/runtime/Test/runtimeTest.sh create mode 100644 src/runtime/TypeConversions.cxx create mode 100644 src/runtime/TypeConversions.hxx create mode 100644 src/runtime/XMLCORBAConv.cxx create mode 100644 src/runtime/XMLCORBAConv.hxx create mode 100644 src/runtime/XMLNode.cxx create mode 100644 src/runtime/XMLNode.hxx create mode 100644 src/runtime/XMLPorts.cxx create mode 100644 src/runtime/XMLPorts.hxx diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..d60c31a97 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/INSTALL b/INSTALL index 81888cbe6..96b298df3 100644 --- a/INSTALL +++ b/INSTALL @@ -1 +1,272 @@ -YACS is for dYnamic pArallel Coupling System +Installation Instructions +************************* + +Specific part for YACS +~~~~~~~~~~~~~~~~~~~~~~ +Prerequisites +============= +YACS needs: + - g++ 3.3.5 or more, + - CPPUNIT + - omniORB 4.05 or more, + - Python + +Build and check +=============== + +build and install are done in separate directories, not in source directory. +For instance, if the path to YACS sources is ${BASEREP}/YACS_SRC:: + + cd ${BASEREP} + rm -rf build install + mkdir build install + + cd ${BASEREP}/YACS_SRC + ./root_clean + ./build_configure + + cd ${BASEREP}/build + ../YACS_SRC/configure --prefix=${BASEREP}/install + + make + make check + + make install + + +Generic part +~~~~~~~~~~~~ + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PREFIX', the package will +use PREFIX as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/README b/README index 1f79074dd..6d0a46bbd 100644 --- a/README +++ b/README @@ -1,6 +1,26 @@ YACS is for dYnamic pArallel Coupling System ============================================ +TODOlist, questions +------------------- + +Les noms de noeuds devraient avoir une portée relative au bloc qui les contient, +et pouvoir être identifiés au sein d'une hiérarchie de bloc par un nom +construit de la même façon que pour les ports: +"bloc1.bloc2.noeud3" + +Dans quels cas faut-il créer des ports de données sur des noeuds composés ? +(Switch, boucle...). +La création est elle faite automatiquement au niveau de l'engine ? + +Fonction de vérification de la compétude d'un graphe à l'édition: +- tous les ports de donnée entrants doivent être initialisés ou connectés. +- inventaire des ports de donnée entrants non initialisés et non connectés. +- faut-il vérifier quelque chose pour les gates ? + + + + IMPROVEMENTS : - OutGate::isAlreadyInList : use std::find diff --git a/adm/unix/config_files/check_omniorb.m4 b/adm/unix/config_files/check_omniorb.m4 new file mode 100644 index 000000000..998acd86e --- /dev/null +++ b/adm/unix/config_files/check_omniorb.m4 @@ -0,0 +1,313 @@ + +AC_DEFUN([CHECK_OMNIORB],[ +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 omniORB) +omniORB_ok=yes + +if test "x$PYTHON" = "x" +then + CHECK_PYTHON +fi + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +AC_PATH_PROG(OMNIORB_IDL, omniidl) +if test "xOMNIORB_IDL" = "x" +then + omniORB_ok=no + AC_MSG_RESULT(omniORB binaries not in PATH variable) +else + omniORB_ok=yes +fi + +if test "x$omniORB_ok" = "xyes" +then + AC_SUBST(OMNIORB_IDL) + + OMNIORB_BIN=`echo ${OMNIORB_IDL} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + OMNIORB_ROOT=${OMNIORB_BIN} + # one-level up + OMNIORB_ROOT=`echo ${OMNIORB_ROOT} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + # + # + if test -d $OMNIORB_ROOT/include ; then + # if $OMNIORB_ROOT/include exists, there are a lot of chance that + # this is omniORB4.x installed via configure && make && make install + OMNIORB_LIB=`echo ${OMNIORB_BIN} | sed -e "s,bin\$,lib,"` + OMNIORB_VERSION=4 + else + # omniORB has been installed old way + OMNIORB_LIB=`echo ${OMNIORB_BIN} | sed -e "s,bin/,lib/,"` + # one-level up again + OMNIORB_ROOT=`echo ${OMNIORB_ROOT} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + if test -d $OMNIORB_ROOT/include/omniORB4 ; then + OMNIORB_VERSION=4 + else + OMNIORB_VERSION=3 + fi + fi + AC_SUBST(OMNIORB_ROOT) + + OMNIORB_INCLUDES="-I$OMNIORB_ROOT/include -I$OMNIORB_ROOT/include/omniORB${OMNIORB_VERSION} -I$OMNIORB_ROOT/include/COS" + AC_SUBST(OMNIORB_INCLUDES) + + OMNIORB_CXXFLAGS="-DOMNIORB_VERSION=$OMNIORB_VERSION" + case $build_cpu in + sparc*) + AC_DEFINE(__sparc__) + OMNIORB_CXXFLAGS="$OMNIORB_CXXFLAGS -D__sparc__" + ;; + *86*) + AC_DEFINE(__x86__) + OMNIORB_CXXFLAGS="$OMNIORB_CXXFLAGS -D__x86__" + ;; + esac + case $build_os in + osf*) + AC_DEFINE(__osf1__) + __OSVERSION__=5 + AC_DEFINE(__OSVERSION__) + OMNIORB_CXXFLAGS="$OMNIORB_CXXFLAGS -D__osf1__" + ;; + solaris*) + AC_DEFINE(__sunos__) + __OSVERSION__=5 + AC_DEFINE(__OSVERSION__) + OMNIORB_CXXFLAGS="$OMNIORB_CXXFLAGS -D__sunos__" + ;; + linux*) + AC_DEFINE(__linux__) + __OSVERSION__=2 + AC_DEFINE(__OSVERSION__) + OMNIORB_CXXFLAGS="$OMNIORB_CXXFLAGS -D__linux__" + ;; + esac + AC_SUBST(OMNIORB_CXXFLAGS) + + CPPFLAGS_old=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $OMNIORB_CXXFLAGS $OMNIORB_INCLUDES" + + AC_LANG_CPLUSPLUS + AC_CHECK_HEADER(CORBA.h,omniORB_ok="yes",omniORB_ok="no") + + CPPFLAGS=$CPPFLAGS_old + +fi + +dnl omniORB_ok=yes + +if test "x$omniORB_ok" = "xyes" +then + if test "x$OMNIORB_LIB" = "x/usr/lib" + then + OMNIORB_LDFLAGS="" + else + OMNIORB_LDFLAGS="-L$OMNIORB_LIB" + fi + + LIBS_old=$LIBS + LIBS="$LIBS $OMNIORB_LDFLAGS -lomnithread" + + CXXFLAGS_old=$CXXFLAGS + CXXFLAGS="$CXXFLAGS $OMNIORB_CXXFLAGS $OMNIORB_INCLUDES" + + AC_MSG_CHECKING(whether we can link with omnithreads) + AC_CACHE_VAL(salome_cv_lib_omnithreads,[ + AC_TRY_LINK( +#include +, omni_mutex my_mutex, + eval "salome_cv_lib_omnithreads=yes",eval "salome_cv_lib_omnithreads=no") + ]) + + omniORB_ok="$salome_cv_lib_omnithreads" + if test "x$omniORB_ok" = "xno" + then + AC_MSG_RESULT(omnithreads not found) + else + AC_MSG_RESULT(yes) + fi + + LIBS=$LIBS_old + CXXFLAGS=$CXXFLAGS_old +fi + + +dnl omniORB_ok=yes +if test "x$omniORB_ok" = "xyes" +then + + AC_CHECK_LIB(socket,socket, LIBS="-lsocket $LIBS",,) + AC_CHECK_LIB(nsl,gethostbyname, LIBS="-lnsl $LIBS",,) + + LIBS_old=$LIBS + OMNIORB_LIBS="$OMNIORB_LDFLAGS" + OMNIORB_LIBS="$OMNIORB_LIBS -lomniORB${OMNIORB_VERSION}" + OMNIORB_LIBS="$OMNIORB_LIBS -lomniDynamic${OMNIORB_VERSION}" + OMNIORB_LIBS="$OMNIORB_LIBS -lCOS${OMNIORB_VERSION}" + OMNIORB_LIBS="$OMNIORB_LIBS -lCOSDynamic${OMNIORB_VERSION}" + OMNIORB_LIBS="$OMNIORB_LIBS -lomnithread" + if test $OMNIORB_VERSION = 3 ; then + OMNIORB_LIBS="$OMNIORB_LIBS -ltcpwrapGK" + fi + AC_SUBST(OMNIORB_LIBS) + + LIBS="$OMNIORB_LIBS $LIBS" + CXXFLAGS_old=$CXXFLAGS + CXXFLAGS="$CXXFLAGS $OMNIORB_CXXFLAGS $OMNIORB_INCLUDES" + + AC_MSG_CHECKING(whether we can link with omniORB) + AC_CACHE_VAL(salome_cv_lib_omniorb,[ + AC_TRY_LINK( +#include +, CORBA::ORB_var orb, + eval "salome_cv_lib_omniorb3=yes",eval "salome_cv_lib_omniorb3=no") + ]) + omniORB_ok="$salome_cv_lib_omniorb3" + + omniORB_ok=yes + if test "x$omniORB_ok" = "xno" + then + AC_MSG_RESULT(omniORB library linking failed) + omniORB_ok=no + else + AC_MSG_RESULT(yes) + fi + LIBS="$LIBS_old" + CXXFLAGS=$CXXFLAGS_old +fi + + +if test "x$omniORB_ok" = "xyes" +then + + OMNIORB_IDLCXXFLAGS="-nf -I${OMNIORB_ROOT}/idl" + OMNIORB_IDLPYFLAGS_1='-bpythonbe -p ${top_srcdir}/salome_adm/unix' + OMNIORB_IDLPYFLAGS_2=" -I${OMNIORB_ROOT}/idl" + OMNIORB_IDLPYFLAGS=${OMNIORB_IDLPYFLAGS_1}${OMNIORB_IDLPYFLAGS_2} + + AC_SUBST(OMNIORB_IDLCXXFLAGS) + AC_SUBST(OMNIORB_IDLPYFLAGS) + + OMNIORB_IDL_CLN_H=.hh + OMNIORB_IDL_CLN_CXX=SK.cc + OMNIORB_IDL_CLN_OBJ=SK.o + AC_SUBST(OMNIORB_IDL_CLN_H) + AC_SUBST(OMNIORB_IDL_CLN_CXX) + AC_SUBST(OMNIORB_IDL_CLN_OBJ) + + OMNIORB_IDL_SRV_H=.hh + OMNIORB_IDL_SRV_CXX=SK.cc + OMNIORB_IDL_SRV_OBJ=SK.o + AC_SUBST(OMNIORB_IDL_SRV_H) + AC_SUBST(OMNIORB_IDL_SRV_CXX) + AC_SUBST(OMNIORB_IDL_SRV_OBJ) + + OMNIORB_IDL_TIE_H= + OMNIORB_IDL_TIE_CXX= + AC_SUBST(OMNIORB_IDL_TIE_H) + AC_SUBST(OMNIORB_IDL_TIE_CXX) + + AC_DEFINE(OMNIORB) + + CORBA_HAVE_POA=1 + AC_DEFINE(CORBA_HAVE_POA) + + CORBA_ORB_INIT_HAVE_3_ARGS=1 + AC_DEFINE(CORBA_ORB_INIT_HAVE_3_ARGS) + CORBA_ORB_INIT_THIRD_ARG='"omniORB"' + AC_DEFINE(CORBA_ORB_INIT_THIRD_ARG, "omniORB") + +fi + +omniORBpy_ok=no +if test "x$omniORB_ok" = "xyes" +then + AC_MSG_CHECKING(omniORBpy) + $PYTHON -c "import omniORB" &> /dev/null + if test $? = 0 ; then + AC_MSG_RESULT(yes) + omniORBpy_ok=yes + else + AC_MSG_RESULT(no, check your installation of omniORBpy) + omniORBpy_ok=no + fi +fi + +dnl AC_LANG_RESTORE + +AC_MSG_RESULT(for omniORBpy: $omniORBpy_ok) +AC_MSG_RESULT(for omniORB: $omniORB_ok) + +# Save cache +AC_CACHE_SAVE + +dnl AC_LANG_CPLUSPLUS + +CXXFLAGS_old=$CXXFLAGS +CXXFLAGS="$CXXFLAGS $OMNIORB_CXXFLAGS $OMNIORB_INCLUDES" +LIBS_old=$LIBS +LIBS="$LIBS $OMNIORB_LDFLAGS $OMNIORB_LIBS" +AC_MSG_CHECKING(whether we have double and CORBA::Double compatibility) +AC_TRY_RUN( +#include +#include +int main () +{ + CORBA::Double *a=new CORBA::Double(2.5); + double c=2.5; + double *b; + b=(double *)a; + + if( (c==*b) && (sizeof(double)==sizeof(CORBA::Double)) ){ + delete a; + exit(0); + } + else{ + delete a; + exit(1); + } +} +,DOUBLECOMP="yes",DOUBLECOMP="no") +if test "$DOUBLECOMP" = yes; then + OMNIORB_CXXFLAGS="$OMNIORB_CXXFLAGS -DCOMP_CORBA_DOUBLE" + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi +AC_MSG_CHECKING(whether we have int and CORBA::Long compatibility) +AC_TRY_RUN( +#include +#include +int main () +{ + CORBA::Long *a=new CORBA::Long(2); + int c=2; + int *b; + b=(int *)a; + + if( (c==*b) && (sizeof(int)==sizeof(CORBA::Long)) ) + exit(0); + else + exit(1); +} +,LONGCOMP="yes",LONGCOMP="no") +if test "$LONGCOMP" = yes; then + OMNIORB_CXXFLAGS="$OMNIORB_CXXFLAGS -DCOMP_CORBA_LONG" + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi +CXXFLAGS=$CXXFLAGS_old +LIBS=$LIBS_old + +AC_LANG_RESTORE + +AC_SUBST(OMNIORB_CXXFLAGS) + +])dnl +dnl diff --git a/adm/unix/make_end.am b/adm/unix/make_end.am index 9d769bc65..a6a697426 100755 --- a/adm/unix/make_end.am +++ b/adm/unix/make_end.am @@ -5,7 +5,16 @@ SUFFIXES = # *.i --> *wrap.cxx # -------------------------------------------- -SUFFIXES += .i WRAP.cxx +SUFFIXES += .i WRAP.cxx .idl .hh SK.cc _idl.py .iWRAP.cxx : $(SWIG) $(SWIG_PYTHON_OPT) $(SWIG_PYTHON_INCLUDES) -o $@ $< + +.idlSK.cc: + $(OMNIORB_IDL) $(OMNIORB_IDLCXXFLAGS) -bcxx $< + +.idl.hh: + $(OMNIORB_IDL) $(OMNIORB_IDLCXXFLAGS) -bcxx $< + +.idl_idl.py: + $(OMNIORB_IDL) -bpython $< diff --git a/build_configure b/build_configure index a1aed8bb3..db3c5f437 100755 --- a/build_configure +++ b/build_configure @@ -45,7 +45,8 @@ cd ${CONF_DIR} # -- configure.in construction rm -f configure.in touch configure.in -echo "AC_INIT(src)" >> configure.in +#echo "AC_INIT(src)" >> configure.in +echo "AC_INIT(YACS,0.1)" >> configure.in echo "RELEASE=$VERSION" >> configure.in echo "PROJECT=$PROJECT" >> configure.in cat configure.in.base >> configure.in diff --git a/configure.in.base b/configure.in.base index 41e7232f2..a35cbf8e4 100644 --- a/configure.in.base +++ b/configure.in.base @@ -3,7 +3,7 @@ # Author : Anthony Geay (CEA) # -- -AC_ENABLE_DEBUG(no) +AC_ENABLE_DEBUG(yes) AC_DISABLE_PRODUCTION AC_SUBST(RELEASE) AM_INIT_AUTOMAKE($PROJECT, $RELEASE) @@ -14,3 +14,4 @@ AC_PROG_SWIG(1.3.17) SWIG_ENABLE_CXX SWIG_PYTHON CHECK_THREAD +CHECK_OMNIORB diff --git a/doc/Doxyfile b/doc/Doxyfile new file mode 100644 index 000000000..a885516fe --- /dev/null +++ b/doc/Doxyfile @@ -0,0 +1,273 @@ +# Doxyfile 1.4.2 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = YACS +PROJECT_NUMBER = 0.0.1 +OUTPUT_DIRECTORY = /home/prascle/SALOME2/YACS/BR_V0_0_1_PR/doc/ +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = /home/prascle/SALOME2/YACS/BR_V0_0_1_PR +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = \ + /home/prascle/SALOME2/YACS/BR_V0_0_1_PR/YACS_SRC/src/bases \ + /home/prascle/SALOME2/YACS/BR_V0_0_1_PR/YACS_SRC/src/data \ + /home/prascle/SALOME2/YACS/BR_V0_0_1_PR/YACS_SRC/src/engine \ + /home/prascle/SALOME2/YACS/BR_V0_0_1_PR/YACS_SRC/src/runtime +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/root_clean b/root_clean index 2116b3b7d..bb28a91fa 100755 --- a/root_clean +++ b/root_clean @@ -10,7 +10,6 @@ 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' diff --git a/src/Makefile.am b/src/Makefile.am index c234fb027..1660ccb3b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = bases basicData engine +SUBDIRS = bases engine runtime diff --git a/src/bases/Test/BasicMainTest.hxx b/src/bases/Test/BasicMainTest.hxx new file mode 100644 index 000000000..3794dcc1c --- /dev/null +++ b/src/bases/Test/BasicMainTest.hxx @@ -0,0 +1,88 @@ +// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef _BASICMAINTEST_HXX_ +#define _BASICMAINTEST_HXX_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// ============================================================================ +/*! + * Main program source for Unit Tests with cppunit package does not depend + * on actual tests, so we use the same for all partial unit tests. + */ +// ============================================================================ + +int main(int argc, char* argv[]) +{ + // --- Create the event manager and test controller + CPPUNIT_NS::TestResult controller; + + // --- Add a listener that colllects test result + CPPUNIT_NS::TestResultCollector result; + controller.addListener( &result ); + + // --- Add a listener that print dots as test run. +#ifdef WIN32 + CPPUNIT_NS::TextTestProgressListener progress; +#else + CPPUNIT_NS::BriefTestProgressListener progress; +#endif + controller.addListener( &progress ); + + // --- Get the top level suite from the registry + + CPPUNIT_NS::Test *suite = + CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest(); + + // --- Adds the test to the list of test to run + + CPPUNIT_NS::TestRunner runner; + runner.addTest( suite ); + runner.run( controller); + + // --- Print test in a compiler compatible format. + + std::ofstream testFile; + testFile.open("UnitTestsResult", std::ios::out | std::ios::trunc); + //CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr ); + CPPUNIT_NS::CompilerOutputter outputter( &result, testFile ); + outputter.write(); + + // --- Run the tests. + + bool wasSucessful = result.wasSuccessful(); + testFile.close(); + + // --- Return error code 1 if the one of test failed. + + return wasSucessful ? 0 : 1; +} + +#endif diff --git a/src/bases/Test/Makefile.am b/src/bases/Test/Makefile.am index 1e256d6e9..70c681e5a 100644 --- a/src/bases/Test/Makefile.am +++ b/src/bases/Test/Makefile.am @@ -3,16 +3,18 @@ include $(top_srcdir)/adm/unix/make_begin.am AM_CXXFLAGS = $(THREAD_DEF) -I$(srcdir)/.. -check_PROGRAMS = test1 +check_PROGRAMS = TestBases -test1_SOURCES = test1.cxx +TestBases_SOURCES = \ + TestBases.cxx \ + basesTest.cxx -test1_LDADD = ../libYACSBases.la +TestBases_LDADD = ../libYACSBases.la -test1_LDFLAGS = $(CPPUNIT_LIBS) -pthread -ldl +TestBases_LDFLAGS = $(CPPUNIT_LIBS) -pthread -ldl -test1_CXXFLAGS = $(THREAD_DEF) $(CPPUNIT_INCLUDES) -I$(srcdir)/.. +TestBases_CXXFLAGS = $(THREAD_DEF) $(CPPUNIT_INCLUDES) -I$(srcdir)/.. -TESTS = test1 +TESTS = TestBases include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/bases/Test/TestBases.cxx b/src/bases/Test/TestBases.cxx new file mode 100644 index 000000000..1f2d9a726 --- /dev/null +++ b/src/bases/Test/TestBases.cxx @@ -0,0 +1,14 @@ + +#include "basesTest.hxx" + +using namespace YACS::BASES; +using namespace YACS; +using namespace std; + +// --- Registers the fixture into the 'registry' + +CPPUNIT_TEST_SUITE_REGISTRATION( BasesTest ); + +// --- generic Main program from Bases/Test + +#include "BasicMainTest.hxx" diff --git a/src/bases/Test/basesTest.cxx b/src/bases/Test/basesTest.cxx new file mode 100644 index 000000000..bc16727b0 --- /dev/null +++ b/src/bases/Test/basesTest.cxx @@ -0,0 +1,99 @@ + +#include "basesTest.hxx" + +#include + +using namespace YACS::BASES; +using namespace YACS; +using namespace std; + +Mutex BasesTest::_m; +Semaphore BasesTest::_s1; +Semaphore BasesTest::_s2; +ostringstream BasesTest::_glob; +int BasesTest::_var=7; + +const int BasesTest::THREAD_NUM=5; + +const int BasesTest::LOOPS=4; + +int BasesTest::_value=0; + +void *BasesTest::th1_1(void *st) +{ + char myName=*((char *) st); + _s1.wait(); + _glob<< myName << _var; + _var+=2; + _s1.post(); + _s2.post(); +} + +void *BasesTest::th1_2(void *st) +{ + char myName=*((char *) st); + _s2.wait(); + _glob<< myName << _var; + _s2.post(); +} + +void *BasesTest::th1_3(void *st) +{ + char myName=*((char *) st); + _glob<< myName << _var++; + _s1.post(); +} + +void *BasesTest::th2_1(void *) +{ + int i, tmp; + int rc = 0; + for (i=0; ijoin(); + delete ths[i]; + } + delete [] ths; + CPPUNIT_ASSERT( _value == THREAD_NUM*LOOPS ); +} diff --git a/src/bases/Test/basesTest.hxx b/src/bases/Test/basesTest.hxx new file mode 100644 index 000000000..dc974d647 --- /dev/null +++ b/src/bases/Test/basesTest.hxx @@ -0,0 +1,49 @@ + +#ifndef _BASESTEST_HXX_ +#define _BASESTEST_HXX_ + +#include +#include "Mutex.hxx" +#include "Thread.hxx" +#include "Semaphore.hxx" + +namespace YACS +{ + class BasesTest: public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( BasesTest ); + CPPUNIT_TEST(test1 ); + CPPUNIT_TEST(test2 ); + CPPUNIT_TEST_SUITE_END(); + + public: + + void setUp(); + void tearDown(); + + void test1(); + void test2(); + + protected: + + private: + static void *th1_1(void *); + static void *th1_2(void *); + static void *th1_3(void *); + static void *th2_1(void *); + + static int _var; + static std::ostringstream _glob; + static YACS::BASES::Mutex _m; + static YACS::BASES::Semaphore _s1; + static YACS::BASES::Semaphore _s2; + + static const int THREAD_NUM; + static const int LOOPS; + static int _value; + + }; + +} + +#endif diff --git a/src/bases/Test/test1.cxx b/src/bases/Test/test1.cxx deleted file mode 100644 index 6bf766246..000000000 --- a/src/bases/Test/test1.cxx +++ /dev/null @@ -1,139 +0,0 @@ -#include "Mutex.hxx" -#include "Thread.hxx" -#include "Semaphore.hxx" -// -#include -#include -#include -// - -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; ijoin(); - 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 -class TreatmentForNewContentDataFlow -{ -public: - static void perform(const std::string& input, ContentOfDataFlow::Type& ret) - { - ret=ContentOfDataFlow::createNewContent(input); - } -}; - -template< YACS::DynType fromType, YACS::DynType toType > -class TreatmentForConvertContentDataFlow -{ - public: - static void perform(ContentOfDataFlow::Type input, ContentOfDataFlow::Type& ret) - { - ret=StaticAndDynamicTypeConverter::convert(input); - } -}; - -template< YACS::DynType fromType, YACS::DynType toType > -class TreatmentToCheckStaticallyTypes -{ - public: - static void perform(ContentOfDataFlow::Type input, bool& ret) - { - ret=StaticTypeConverter::_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::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::perform(fromType, toType, content, ret); - return ret; - } -} - -bool ContentOfDataFlow::isStaticallyCompatibleWith(DynType fromType, DynType toType) throw(Exception) -{ - bool ret; - DynToStaticTypeDispatcher2::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 deleted file mode 100644 index bb4e6655d..000000000 --- a/src/basicData/ContentOfDataFlow.hxx +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef __CONTENTOFDATAFLOW_HXX__ -#define __CONTENTOFDATAFLOW_HXX__ - -#include "define.hxx" -#include "TypeCheckerDataFlow.hxx" -#include "ConversionException.hxx" - -#include -#include -#include -#include - -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 - static Type createNewContent(T value); - template - static Type createNewContent(const std::string& content) throw(Exception); - template - 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 - 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 - 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::_typeEnum; - std::istringstream stream(contentC); - stream >> value; - if(stream.fail() || !stream.eof()) - { - std::string what="Content not recognized as "; what+=TypeDescriptorTraits::_typeEnum>::_name; - throw Exception(what); - } - } - - template - ContentOfDataFlow::Type ContentOfDataFlow::createNewContent(const std::string& content) throw(Exception) - { - std::istringstream stream(content); - typename TypeDescriptorTraits::ConcreteType value; - stream >> value; - if(!stream.fail() && stream.eof()) - return createNewContent(value); - else - { - std::string what(content); - what+=" is not recognized as "; what+=TypeDescriptorTraits::_name; - throw Exception(what); - } - } - } -} - -#endif diff --git a/src/basicData/ConversionException.cxx b/src/basicData/ConversionException.cxx deleted file mode 100644 index d9b1da096..000000000 --- a/src/basicData/ConversionException.cxx +++ /dev/null @@ -1,14 +0,0 @@ -#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/Data.cxx b/src/basicData/Data.cxx deleted file mode 100644 index e0bd62c18..000000000 --- a/src/basicData/Data.cxx +++ /dev/null @@ -1,127 +0,0 @@ -#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::_name; - } -}; - -std::string Data::edGetTypeInPrintableForm(DynType type) -{ - try - { - int fake1; - std::string ret; - DynToStaticTypeDispatcher1::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 deleted file mode 100644 index 6c2e0e534..000000000 --- a/src/basicData/Data.hxx +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef __DATA_HXX__ -#define __DATA_HXX__ - -#include "define.hxx" -#include "ContentOfDataFlow.hxx" -#include "ConversionException.hxx" -#include - -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 - Data(T val); - Data(const Data& other); - ~Data(); - Data &operator =(const Data& other) throw(ConversionException); - template - 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 - 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 - Data::Data(T val) - { - _edType=TypeDescriptorTraitsInv::_typeEnum; - _exContent=ContentOfDataFlow::createNewContent(val); - } - - template - Data &Data::operator =(T val) throw(ConversionException) - { - ContentOfDataFlow::release(_exContent); - typename ContentOfDataFlow::Type content=ContentOfDataFlow::createNewContent(val); - if(_edType==TypeDescriptorTraitsInv::_typeEnum) - { - _exContent=content; - } - else - { - _exContent=ContentOfDataFlow::convertContent(content,TypeDescriptorTraitsInv::_typeEnum,_edType); - ContentOfDataFlow::release(content); - } - return *this; - } - - template - 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 deleted file mode 100644 index 723ae284f..000000000 --- a/src/basicData/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ - -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 deleted file mode 100644 index 484d0632f..000000000 --- a/src/basicData/Test/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ - -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 deleted file mode 100644 index b8dee373c..000000000 --- a/src/basicData/Test/testData.cxx +++ /dev/null @@ -1,118 +0,0 @@ -#include "Data.hxx" -// -#include -#include -#include -// - -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 deleted file mode 100644 index a54f9607d..000000000 --- a/src/basicData/TypeCheckerDataFlow.cxx +++ /dev/null @@ -1,11 +0,0 @@ -#include "TypeCheckerDataFlow.hxx" - -using namespace YACS::ENGINE; - -const char TypeDescriptorTraits::_name[]="Double"; - -const char TypeDescriptorTraits::_name[]="Int"; - -const char TypeDescriptorTraits::_name[]="Bool"; - -const char TypeDescriptorTraits::_name[]="String"; diff --git a/src/basicData/TypeCheckerDataFlow.hxx b/src/basicData/TypeCheckerDataFlow.hxx deleted file mode 100644 index b26094616..000000000 --- a/src/basicData/TypeCheckerDataFlow.hxx +++ /dev/null @@ -1,332 +0,0 @@ -#ifndef __TYPECHECKERDATAFLOW_HXX__ -#define __TYPECHECKERDATAFLOW_HXX__ - -#include "define.hxx" -#include "ConversionException.hxx" - -#include -#include - -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 - static void perform(YACS::DynType myTypeDyn, T input, U& output) throw(Exception) - { - switch(myTypeDyn) - { - case Double: - TREATMENTPERTYPE::perform(input, output); - break; - case Int: - TREATMENTPERTYPE::perform(input, output); - break; - case String: - TREATMENTPERTYPE::perform(input, output); - break; - case Bool: - TREATMENTPERTYPE::perform(input, output); - break; - default: - throw Exception("Unknow type enum"); - } - } - }; - - template< template< DynType fromType, DynType toType> class TREATMENTPERTYPE > - class DynToStaticTypeDispatcher2 - { - template class TREATMENTPERTYPEDOUBLE : public TREATMENTPERTYPE { }; - template class TREATMENTPERTYPEINT : public TREATMENTPERTYPE { }; - template class TREATMENTPERTYPEBOOL : public TREATMENTPERTYPE { }; - template class TREATMENTPERTYPESTRING : public TREATMENTPERTYPE { }; - public: - template - static void perform(YACS::DynType myTypeDynFrom, YACS::DynType myTypeDynTo, T input, U& output) throw(Exception) - { - switch(myTypeDynFrom) - { - case Double: -#ifndef __OLD_GCC__ - DynToStaticTypeDispatcher1::perform(myTypeDynTo, input, output); -#else - switch(myTypeDynTo) - { - case Double: - TREATMENTPERTYPE::perform(input, output); - break; - case Int: - TREATMENTPERTYPE::perform(input, output); - break; - case String: - TREATMENTPERTYPE::perform(input, output); - break; - case Bool: - TREATMENTPERTYPE::perform(input, output); - break; - default: - throw Exception("Unknow type enum"); - } -#endif - break; - case Int: -#ifndef __OLD_GCC__ - DynToStaticTypeDispatcher1::perform(myTypeDynTo, input, output); -#else - switch(myTypeDynTo) - { - case Double: - TREATMENTPERTYPE::perform(input, output); - break; - case Int: - TREATMENTPERTYPE::perform(input, output); - break; - case String: - TREATMENTPERTYPE::perform(input, output); - break; - case Bool: - TREATMENTPERTYPE::perform(input, output); - break; - default: - throw Exception("Unknow type enum"); - } -#endif - break; - case String: -#ifndef __OLD_GCC__ - DynToStaticTypeDispatcher1::perform(myTypeDynTo, input, output); -#else - switch(myTypeDynTo) - { - case Double: - TREATMENTPERTYPE::perform(input, output); - break; - case Int: - TREATMENTPERTYPE::perform(input, output); - break; - case String: - TREATMENTPERTYPE::perform(input, output); - break; - case Bool: - TREATMENTPERTYPE::perform(input, output); - break; - default: - throw Exception("Unknow type enum"); - } -#endif - break; - case Bool: -#ifndef __OLD_GCC__ - DynToStaticTypeDispatcher1::perform(myTypeDynTo, input, output); -#else - switch(myTypeDynTo) - { - case Double: - TREATMENTPERTYPE::perform(input, output); - break; - case Int: - TREATMENTPERTYPE::perform(input, output); - break; - case String: - TREATMENTPERTYPE::perform(input, output); - break; - case Bool: - TREATMENTPERTYPE::perform(input, output); - break; - default: - throw Exception("Unknow type enum"); - } -#endif - break; - default: - throw Exception("Unknow type enum"); - } - } - }; - - template - class TypeDescriptorTraits - { - }; - - template - class TypeDescriptorTraitsInv - { - }; - - template<> - class TypeDescriptorTraits - { - public: - typedef double ConcreteType; - static const char _name[]; - }; - - template<> - class TypeDescriptorTraitsInv - { - public: - static const YACS::DynType _typeEnum=Double; - }; - - template<> - class TypeDescriptorTraits - { - public: - typedef int ConcreteType; - static const char _name[]; - }; - - template<> - class TypeDescriptorTraitsInv - { - public: - static const YACS::DynType _typeEnum=Int; - }; - - template<> - class TypeDescriptorTraits - { - public: - typedef bool ConcreteType; - static const char _name[]; - }; - - template<> - class TypeDescriptorTraitsInv - { - public: - static const YACS::DynType _typeEnum=Bool; - }; - - template<> - class TypeDescriptorTraits - { - public: - typedef std::string ConcreteType; - static const char _name[]; - }; - - template<> - class TypeDescriptorTraitsInv - { - 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 - class StaticTypeConverter - { - public: - enum { _staticallyCompatible=0 }; - static typename TypeDescriptorTraits::ConcreteType traduce(typename TypeDescriptorTraits::ConcreteType input) throw(ConversionException) - { - throw ConversionException(TypeDescriptorTraits::_name, TypeDescriptorTraits::_name); - } - }; - - //Specialisation of the previously declared StaticTypeConverter class when 'fromType' and 'toType' are equal. - template - class StaticTypeConverter - { - public: - enum { _staticallyCompatible=1 }; - static typename TypeDescriptorTraits::ConcreteType traduce(typename TypeDescriptorTraits::ConcreteType input) throw(ConversionException) - { - return input; - } - }; - - template<> - class StaticTypeConverter - { - public: - enum { _staticallyCompatible=1 }; - static TypeDescriptorTraits::ConcreteType traduce(TypeDescriptorTraits::ConcreteType input) throw(ConversionException) - { - return (TypeDescriptorTraits::ConcreteType) input; - } - }; - - template<> - class StaticTypeConverter - { - public: - enum { _staticallyCompatible=1 }; - static TypeDescriptorTraits::ConcreteType traduce(TypeDescriptorTraits::ConcreteType input) throw(ConversionException) - { - return (TypeDescriptorTraits::ConcreteType) input; - } - }; - - template<> - class StaticTypeConverter - { - public: - enum { _staticallyCompatible=1 }; - static TypeDescriptorTraits::ConcreteType traduce(TypeDescriptorTraits::ConcreteType input) throw(ConversionException) - { - if(input!=0) - return true; - else - return false; - } - }; - - template<> - class StaticTypeConverter - { - public: - enum { _staticallyCompatible=1 }; - static TypeDescriptorTraits::ConcreteType traduce(TypeDescriptorTraits::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 StaticAndDynamicTypeConverter - { - public: - static typename container::Type convert(typename container::Type source) throw(ConversionException) - { - if(!StaticTypeConverter::_staticallyCompatible) - throw ConversionException(TypeDescriptorTraits::_name, TypeDescriptorTraits::_name); - typename TypeDescriptorTraits::ConcreteType sourceValue; - container::readContent(source,sourceValue); - typename TypeDescriptorTraits::ConcreteType targetValue=StaticTypeConverter::traduce(sourceValue); - return container::createNewContent(targetValue); - } - }; - } -} - -#endif diff --git a/src/basicData/TypeCheckerDataStream.cxx b/src/basicData/TypeCheckerDataStream.cxx deleted file mode 100644 index 977c9f8c4..000000000 --- a/src/basicData/TypeCheckerDataStream.cxx +++ /dev/null @@ -1,127 +0,0 @@ -#include "TypeCheckerDataStream.hxx" - -namespace YACS -{ - namespace ENGINE - { - template< template< StreamType type> class TREATMENTPERTYPE > - class DynToStaticStreamTypeDispatcher1 - { - public: - template - static void perform(YACS::StreamType myTypeDyn, T input, U& output) throw(Exception) - { - switch(myTypeDyn) - { - case SDouble: - TREATMENTPERTYPE::perform(input, output); - break; - default: - throw Exception("Unknow stream type enum"); - } - } - }; - - template< template< StreamType fromType, StreamType toType> class TREATMENTPERTYPE > - class DynToStaticStreamTypeDispatcher2 - { - template class TREATMENTPERTYPESDOUBLE : public TREATMENTPERTYPE { }; - public: - template - static void perform(YACS::StreamType myTypeDynFrom, YACS::StreamType myTypeDynTo, T input, U& output) throw(Exception) - { - switch(myTypeDynFrom) - { - case SDouble: - DynToStaticStreamTypeDispatcher1::perform(myTypeDynTo, input, output); - break; - default: - throw Exception("Unknow stream type enum"); - } - } - }; - - template - class StreamTypeDescriptorTraits - { - }; - - template<> - class StreamTypeDescriptorTraits - { - 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 - class StaticStreamTypeConverter - { - public: - enum { _staticallyCompatible=1 }; - }; - } -} - -using namespace YACS::ENGINE; - -const char StreamTypeDescriptorTraits::_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::_staticallyCompatible; - } -}; - -bool TypeCheckerDataStream::areStaticallyCompatible(YACS::StreamType type1, YACS::StreamType type2) throw(Exception) -{ - bool ret; - int fake; - //DynToStaticStreamTypeDispatcher2::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::_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 deleted file mode 100644 index 8954922fa..000000000 --- a/src/basicData/TypeCheckerDataStream.hxx +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __TYPECHECKERDATASTREAM_HXX__ -#define __TYPECHECKERDATASTREAM_HXX__ - -#include "define.hxx" -#include "Exception.hxx" - -#include - -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 index e02d45950..b25477be8 100644 --- a/src/engine/Bloc.cxx +++ b/src/engine/Bloc.cxx @@ -2,20 +2,22 @@ #include "ElementaryNode.hxx" using namespace YACS::ENGINE; +using namespace std; -Bloc::Bloc(const std::string& name):ComposedNode(name) +Bloc::Bloc(const string& name):ComposedNode(name) { } Bloc::~Bloc() { - for(std::list::iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++) + for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) delete *iter; } void Bloc::init() { - for(std::list::iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++) + _inGate.exReset(); + for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) (*iter)->init(); if(_inGate.exIsReady()) _state=YACS::TOACTIVATE; @@ -31,54 +33,62 @@ bool Bloc::isFinished() int Bloc::getNumberOfCFLinks() const { int ret=0; - for(std::list::const_iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++) + for(set::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) { ret+=(*iter)->getOutGate()->getNbOfInGatesConnected(); } return ret; } -std::vector Bloc::getNextTasks(bool& isMore) +vector Bloc::getNextTasks(bool& isMore) { - std::vector ret; + vector ret; isMore=false; if(_state==YACS::DONE || _state==YACS::INITED) return ret; - for(std::list::iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++) + for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) (*iter)->getReadyTasks(ret); isMore=!ret.empty(); return ret; } -void Bloc::getReadyTasks(std::vector& tasks) +void Bloc::getReadyTasks(vector& tasks) { if(_state==YACS::TOACTIVATE || _state==YACS::ACTIVATED) - for(std::list::iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++) + for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) (*iter)->getReadyTasks(tasks); } -std::list Bloc::getRecursiveConstituents() +set Bloc::getRecursiveConstituents() { - std::list ret; - for(std::list::iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++) + set ret; + for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) { - std::list myCurrentList=(*iter)->getRecursiveConstituents(); - ret.insert(ret.begin(),myCurrentList.begin(),myCurrentList.end()); + set myCurrentSet=(*iter)->getRecursiveConstituents(); + ret.insert(myCurrentSet.begin(),myCurrentSet.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. + * 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; } +/** +* If node is already a direct child of current bloc, do nothing. +* If node is a child of another bloc, throw exception. +* If node name already used in bloc, throw exception. +* Publish inputPorts in current bloc and ancestors. +*/ + bool Bloc::edAddChild(Node *node) throw(Exception) { if(isNodeAlreadyAggregated(node)) @@ -88,26 +98,41 @@ bool Bloc::edAddChild(Node *node) throw(Exception) else throw Exception("Bloc::edAddChild : Internal error occured"); } + if(node->_father) - throw Exception("Bloc::edAddChild : node is not orphan"); + { + string what = "Bloc::edAddChild: node is not orphan: "; what += node->getName(); + throw Exception(what); + } + if(isNameAlreadyUsed(node->getName())) { - std::string what("Bloc::edAddChild : name "); what+=node->getName(); what+=" already exists in the scope of "; what+=_name; + 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); + _setOfNode.insert(node); + + ComposedNode *iter=node->_father; + while(iter) + { + for(set::iterator itn = node->_setOfInputPort.begin(); itn != node->_setOfInputPort.end(); itn++) + iter->publishInputPort(*itn); + iter=iter->_father; + } + 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'. - * + * Remove 'node' from the set 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) @@ -116,18 +141,18 @@ void Bloc::edRemoveChild(Node *node) throw(Exception) throw Exception("Bloc::edRemoveChild : Internal error occured"); ComposedNode *myRootNode=getRootNode(); myRootNode->disconnectAllLinksConnectedTo(node); - _listOfNode.remove(node); + _setOfNode.erase(node); delete node; } -void Bloc::selectRunnableTasks(std::vector& tasks) +void Bloc::selectRunnableTasks(vector& tasks) { } bool Bloc::areAllSubNodesFinished() const { bool ret=true; - for(std::list::const_iterator iter=_listOfNode.begin();iter!=_listOfNode.end() && ret;iter++) + for(set::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end() && ret;iter++) if((*iter)->_state!=YACS::DONE) ret=false; return ret; @@ -135,7 +160,7 @@ bool Bloc::areAllSubNodesFinished() const bool Bloc::isNodeAlreadyAggregated(Node *node) const { - for(std::list::const_iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++) + for(set::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) { if((*iter)==node) return true; @@ -143,52 +168,49 @@ bool Bloc::isNodeAlreadyAggregated(Node *node) const return false; } -bool Bloc::isNameAlreadyUsed(const std::string& name) const +bool Bloc::isNameAlreadyUsed(const string& name) const { - for(std::list::const_iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++) + for(set::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) if((*iter)->getName()==name) return true; return false; } +bool insertNodeChildrenInSet(Node *node, set nodeSet) +{ + bool verdict=true; + set outNodes=node->getOutNodes(); + for (set::iterator iter=outNodes.begin();iter!=outNodes.end(); iter++) + { + verdict=(nodeSet.insert(*iter)).second; + if (verdict) verdict = insertNodeChildrenInSet((*iter),nodeSet); + if (!verdict) break; + } + return verdict; +} + /** - * @ note : Checks that in the forest from 'node' there are NO back-edges. + * @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 currentNodesToTest; - currentNodesToTest.push_back(node); - for(std::list::iterator iter1=currentNodesToTest.begin();iter1!=currentNodesToTest.end() && verdict;) - { - std::list outNodes=(*iter1)->getOutNodes(); - for(std::list::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) + set currentNodesToTest; + currentNodesToTest.insert(node); + if (!insertNodeChildrenInSet(node,currentNodesToTest)) throw Exception("Cycle has been detected"); } void Bloc::initChildrenForDFS() const { - for(std::list::const_iterator iter=_listOfNode.begin();iter!=_listOfNode.end();iter++) + for(set::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) (*iter)->initForDFS(); } /** * - * @ note : Runtime called method. Indirectly called by ComposedNode::updateStateFrom which has dispatch to this method + * @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) * @@ -201,7 +223,7 @@ YACS::Event Bloc::updateStateOnStartEventFrom(Node *node) /** * - * @ note : Runtime called method. Indirectly called by ComposedNode::updateStateFrom which has dispatch to this method + * @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) * diff --git a/src/engine/Bloc.hxx b/src/engine/Bloc.hxx index 1f0f15cb1..2edf8bdeb 100644 --- a/src/engine/Bloc.hxx +++ b/src/engine/Bloc.hxx @@ -10,7 +10,7 @@ namespace YACS class Bloc : public ComposedNode { protected: - std::list _listOfNode;//OWNERSHIP OF ALL NODES + std::set _setOfNode;//OWNERSHIP OF ALL NODES public: Bloc(const std::string& name); ~Bloc(); @@ -19,11 +19,11 @@ namespace YACS int getNumberOfCFLinks() const; std::vector getNextTasks(bool& isMore); void getReadyTasks(std::vector& tasks); - std::list getRecursiveConstituents(); + std::set getRecursiveConstituents(); void exUpdateState(); bool edAddChild(Node *node) throw(Exception); void edRemoveChild(Node *node) throw(Exception); - std::list getChildren() { return _listOfNode; } + std::set getChildren() { return _setOfNode; } void selectRunnableTasks(std::vector& tasks); protected: bool areAllSubNodesFinished() const; diff --git a/src/engine/ComposedNode.cxx b/src/engine/ComposedNode.cxx index 10359d18f..c19bdc05d 100644 --- a/src/engine/ComposedNode.cxx +++ b/src/engine/ComposedNode.cxx @@ -4,17 +4,21 @@ #include "ElementaryNode.hxx" #include +#include using namespace YACS::ENGINE; +using namespace std; -ComposedNode::ComposedNode(const std::string& name):Node(name) +ComposedNode::ComposedNode(const 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'. + * A COMMENTER DAVANTAGE + * @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 @@ -36,41 +40,56 @@ void ComposedNode::notifyFrom(const Task *sender, //* I : task emitting event } /** - * @ 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. + * 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 multiple 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 allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr); - std::list allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr); + set allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr); + set allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr); checkInMyDescendance(lwstCmnAnctr); ComposedNode *iterS=start->getNode()->_father; + OutPort *currentPortO=start; while(iterS!=lwstCmnAnctr) { - currentPortO=iterS->buildDelegateOf(currentPortO, allAscendanceOfNodeEnd); + currentPortO=iterS->buildDelegateOf(currentPortO, allAscendanceOfNodeStart); 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); + + bool linkDone = currentPortO->addInPort(currentPortI); + if (linkDone) + { + ComposedNode *iter=end->getNode()->_father; + while(iter) + { + iter->unpublishInputPort(end); + iter=iter->_father; + } + } + + return linkDone; } /** - * @ note : Add a controlflow link. + * @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 + * @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. + * @return : true if a new link has been created, false otherwise. */ bool ComposedNode::edAddLink(OutGate *start, InGate *end) throw(Exception) { @@ -101,17 +120,21 @@ bool ComposedNode::edAddCFLink(Node *nodeS, Node *nodeE) throw(Exception) } /** - * @ 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. + * 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 allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr); - std::list allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr); - //Part of test if the link from 'start' to 'end' really exist particulary all eventually intermediate ports created + set allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr); + set 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) @@ -119,6 +142,7 @@ void ComposedNode::edRemoveLink(OutputPort *start, InputPort *end) throw(Excepti currentPortO=iterS->getDelegateOf(currentPortO, allAscendanceOfNodeEnd); iterS=iterS->_father; } + iterS=end->getNode()->_father; InPort *currentPortI=end; while(iterS!=lwstCmnAnctr) @@ -126,9 +150,13 @@ void ComposedNode::edRemoveLink(OutputPort *start, InputPort *end) throw(Excepti currentPortI=iterS->getDelegateOf(currentPortI, allAscendanceOfNodeStart); iterS=iterS->_father; } - //End of test for evt intermediate ports created + + // --- End of test for evt intermediate ports created + currentPortO->removeInPort(currentPortI); - //Performing deletion of intermediate ports + + // --- Performing deletion of intermediate ports + iterS=start->getNode()->_father; currentPortO=start; currentPortI=end; while(iterS!=lwstCmnAnctr) @@ -136,12 +164,22 @@ void ComposedNode::edRemoveLink(OutputPort *start, InputPort *end) throw(Excepti currentPortO=iterS->releaseDelegateOf(currentPortO, allAscendanceOfNodeEnd); iterS=iterS->_father; } + iterS=end->getNode()->_father; while(iterS!=lwstCmnAnctr) { currentPortI=iterS->releaseDelegateOf(currentPortI, allAscendanceOfNodeStart); iterS=iterS->_father; } + + // --- publish inputPort in ancestors + + ComposedNode *iter=end->getNode()->_father; + while(iter) + { + iter->publishInputPort(end); + iter=iter->_father; + } } void ComposedNode::edRemoveLink(OutGate *start, InGate *end) throw(Exception) @@ -155,14 +193,20 @@ void ComposedNode::edRemoveLink(OutGate *start, InGate *end) throw(Exception) void ComposedNode::publishOutputPort(OutputPort *port) throw(Exception) { checkInMyDescendance(port->getNode()); - _listOfOutputPort.push_back(port); + _setOfOutputPort.insert(port); } void ComposedNode::publishInputPort(InputPort *port) { - _listOfInputPort.push_back(port); + _setOfInputPort.insert(port); } +void ComposedNode::unpublishInputPort(InputPort *port) +{ + _setOfInputPort.erase(port); +} + + ComposedNode *ComposedNode::getRootNode() throw(Exception) { if(!_father) @@ -171,19 +215,19 @@ ComposedNode *ComposedNode::getRootNode() throw(Exception) } /** - * @ note : perform the disconnection of all links under the scope of 'this' connected to an input (dataflow or datastream) of node 'node'. + * @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 listOfAllNodes=getRecursiveConstituents(); - for(std::list::iterator iter=listOfAllNodes.begin();iter!=listOfAllNodes.end();iter++) + set setOfAllNodes=getRecursiveConstituents(); + for(set::iterator iter=setOfAllNodes.begin();iter!=setOfAllNodes.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' + * @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) { @@ -200,11 +244,11 @@ void ComposedNode::checkInMyDescendance(Node *nodeToTest) const throw(Exception) } /** - * - * @ note : Retrieves the lowest common ancestor of 'node1' AND 'node2'. If 'node1' AND 'node2' are equals and are instance of ComposedNode + * + * @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. + * @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) @@ -213,7 +257,7 @@ ComposedNode *ComposedNode::getLowestCommonAncestor(Node *node1, Node *node2) th if(node1==0 || node2==0) throw Exception(what); ComposedNode *temp=node1->_father; - std::set s; + set s; while(temp) { s.insert(temp); @@ -221,7 +265,7 @@ ComposedNode *ComposedNode::getLowestCommonAncestor(Node *node1, Node *node2) th } // temp=node2->_father; - std::set::iterator iter=s.find(temp); + set::iterator iter=s.find(temp); while(temp && iter==s.end()) { iter=s.find(temp); @@ -232,11 +276,42 @@ ComposedNode *ComposedNode::getLowestCommonAncestor(Node *node1, Node *node2) th return *iter; } +/** + * get the input port name used by the current node, reursively built with children names. + */ + +const string ComposedNode::getInputPortName(const InputPort * inputPort) throw (Exception) +{ + Node *node = inputPort->getNode(); + string portName = inputPort->getName(); + string nodeName = node->getName(); + + set nodePortAncestors = node->getAllAscendanceOf(); + + if ( nodePortAncestors.find(this) == nodePortAncestors.end() ) + { + string what("InputPort "); what+= portName; what+=" does not belong to node "; what += nodeName; + throw Exception(what); + } + + Node *father = node; + while (father != this) + { + portName = father->getName() + '.' + portName; + father = father->_father; + } + return portName; +} + +const string ComposedNode::getOutputPortName(const OutputPort *outputPort) throw (Exception) +{ +} + /** * - * @ note : Runtime called method. Perform, the state updating, from the son node 'node' emitting the event 'event' (among Executor static const var). + * @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. + * @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 @@ -257,32 +332,32 @@ YACS::Event ComposedNode::updateStateFrom(Node *node, //* I : node emitti } } -InPort *ComposedNode::buildDelegateOf(InPort *port, const std::list& pointsOfView) +InPort *ComposedNode::buildDelegateOf(InPort *port, const set& pointsOfView) { return port; } -OutPort *ComposedNode::buildDelegateOf(OutPort *port, const std::list& pointsOfView) +OutPort *ComposedNode::buildDelegateOf(OutPort *port, const set& pointsOfView) { return port; } -InPort *ComposedNode::getDelegateOf(InPort *port, const std::list& pointsOfView) throw(Exception) +InPort *ComposedNode::getDelegateOf(InPort *port, const set& pointsOfView) throw(Exception) { return port; } -OutPort *ComposedNode::getDelegateOf(OutPort *port, const std::list& pointsOfView) throw(Exception) +OutPort *ComposedNode::getDelegateOf(OutPort *port, const set& pointsOfView) throw(Exception) { return port; } -InPort *ComposedNode::releaseDelegateOf(InPort *port, const std::list& pointsOfView) throw(Exception) +InPort *ComposedNode::releaseDelegateOf(InPort *port, const set& pointsOfView) throw(Exception) { return port; } -OutPort *ComposedNode::releaseDelegateOf(OutPort *port, const std::list& pointsOfView) throw(Exception) +OutPort *ComposedNode::releaseDelegateOf(OutPort *port, const set& pointsOfView) throw(Exception) { return port; } diff --git a/src/engine/ComposedNode.hxx b/src/engine/ComposedNode.hxx index c24e60119..b70b7ef94 100644 --- a/src/engine/ComposedNode.hxx +++ b/src/engine/ComposedNode.hxx @@ -28,19 +28,22 @@ namespace YACS void edRemoveLink(OutGate *start, InGate *end) throw(Exception); virtual void publishOutputPort(OutputPort *port) throw(Exception); virtual bool isRepeatedUnpredictablySeveralTimes() const { return false; } + virtual const std::string getInputPortName(const InputPort *) throw (Exception); + virtual const std::string getOutputPortName(const OutputPort *) throw (Exception); protected: ComposedNode *getRootNode() throw(Exception); void disconnectAllLinksConnectedTo(Node *node); virtual void publishInputPort(InputPort *port); + virtual void unpublishInputPort(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& pointsOfView); - virtual OutPort *buildDelegateOf(OutPort *port, const std::list& pointsOfView); - virtual InPort *getDelegateOf(InPort *port, const std::list& pointsOfView) throw(Exception); - virtual OutPort *getDelegateOf(OutPort *port, const std::list& pointsOfView) throw(Exception); - virtual InPort *releaseDelegateOf(InPort *port, const std::list& pointsOfView) throw(Exception); - virtual OutPort *releaseDelegateOf(OutPort *port, const std::list& pointsOfView) throw(Exception); + virtual InPort *buildDelegateOf(InPort *port, const std::set& pointsOfView); + virtual OutPort *buildDelegateOf(OutPort *port, const std::set& pointsOfView); + virtual InPort *getDelegateOf(InPort *port, const std::set& pointsOfView) throw(Exception); + virtual OutPort *getDelegateOf(OutPort *port, const std::set& pointsOfView) throw(Exception); + virtual InPort *releaseDelegateOf(InPort *port, const std::set& pointsOfView) throw(Exception); + virtual OutPort *releaseDelegateOf(OutPort *port, const std::set& 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); diff --git a/src/engine/ConversionException.cxx b/src/engine/ConversionException.cxx new file mode 100644 index 000000000..06b839cf6 --- /dev/null +++ b/src/engine/ConversionException.cxx @@ -0,0 +1,12 @@ +#include "ConversionException.hxx" + +using namespace YACS::ENGINE; + +const char ConversionException::TYPEOFEXCEPTION[]="Conversion between types failed : "; + + +ConversionException::ConversionException(const std::string& what):Exception(TYPEOFEXCEPTION) +{ + _what=TYPEOFEXCEPTION; + _what+=what; +} diff --git a/src/basicData/ConversionException.hxx b/src/engine/ConversionException.hxx similarity index 77% rename from src/basicData/ConversionException.hxx rename to src/engine/ConversionException.hxx index f32f6091e..a9d2c2323 100644 --- a/src/basicData/ConversionException.hxx +++ b/src/engine/ConversionException.hxx @@ -12,7 +12,7 @@ namespace YACS class ConversionException : public Exception { public: - ConversionException(const std::string& content, const std::string& expectedType); + ConversionException(const std::string& what); private: static const char TYPEOFEXCEPTION[]; }; diff --git a/src/engine/DataFlowPort.cxx b/src/engine/DataFlowPort.cxx index 013033825..bc5825446 100644 --- a/src/engine/DataFlowPort.cxx +++ b/src/engine/DataFlowPort.cxx @@ -1,25 +1,32 @@ #include "DataFlowPort.hxx" using namespace YACS::ENGINE; -using YACS::DynType; +using namespace std; const char DataFlowPort::NAME[]="DataFlowPort"; -DataFlowPort::DataFlowPort(const std::string& name, Node *node, DynType type):Port(node),_name(name),_data(type) +DataFlowPort::DataFlowPort(const string& name, Node *node, TypeCode* type):Port(node),_name(name) { + _type = type; } -std::string DataFlowPort::getNameOfTypeOfCurrentInstance() const +string DataFlowPort::getNameOfTypeOfCurrentInstance() const { return NAME; } -DynType DataFlowPort::edGetType() const +TypeCode* DataFlowPort::edGetType() const { - return _data.edGetType(); + return _type; } -void DataFlowPort::edSetType(DynType type) +TypeCode * DataFlowPort::type() { - _data.edInitToType(type); + return _type; } + +void DataFlowPort::edSetType(TypeCode* type) +{ + _type = type; +} + diff --git a/src/engine/DataFlowPort.hxx b/src/engine/DataFlowPort.hxx index 9c04f05f1..3237b72ae 100644 --- a/src/engine/DataFlowPort.hxx +++ b/src/engine/DataFlowPort.hxx @@ -2,7 +2,6 @@ #define __DATAFLOWPORT_HXX__ #include "Port.hxx" -#include "Data.hxx" #include @@ -13,16 +12,17 @@ namespace YACS class DataFlowPort : public virtual Port { protected: - Data _data; + void* _data; std::string _name; public: static const char NAME[]; protected: - DataFlowPort(const std::string& name, Node *node, DynType type); + DataFlowPort(const std::string& name, Node *node, TypeCode* type); public: std::string getNameOfTypeOfCurrentInstance() const; - DynType edGetType() const; - virtual void edSetType(DynType type); + TypeCode* edGetType() const; + virtual TypeCode * type(); + virtual void edSetType(TypeCode* type); std::string getName() const { return _name; } }; } diff --git a/src/engine/DataStreamPort.cxx b/src/engine/DataStreamPort.cxx index 258e21925..50f4efb69 100644 --- a/src/engine/DataStreamPort.cxx +++ b/src/engine/DataStreamPort.cxx @@ -1,14 +1,15 @@ #include "DataStreamPort.hxx" using namespace YACS::ENGINE; +using namespace std; const char DataStreamPort::NAME[]="DataStreamPort"; -DataStreamPort::DataStreamPort(const std::string& name, Node *node, StreamType type):Port(node),_name(name),_edType(type) +DataStreamPort::DataStreamPort(const string& name, Node *node, TypeCode* type):Port(node),_name(name),_edType(type) { } -std::string DataStreamPort::getNameOfTypeOfCurrentInstance() const +string DataStreamPort::getNameOfTypeOfCurrentInstance() const { return NAME; } diff --git a/src/engine/DataStreamPort.hxx b/src/engine/DataStreamPort.hxx index dc0803860..9aef868f3 100644 --- a/src/engine/DataStreamPort.hxx +++ b/src/engine/DataStreamPort.hxx @@ -2,7 +2,7 @@ #define __DATASTREAMPORT_HXX__ #include "Port.hxx" -#include "define.hxx" +#include "TypeCode.hxx" #include @@ -14,15 +14,15 @@ namespace YACS { protected: std::string _name; - StreamType _edType; + TypeCode* _edType; public: static const char NAME[]; protected: - DataStreamPort(const std::string& name, Node *node, StreamType type); + DataStreamPort(const std::string& name, Node *node, TypeCode* type); public: std::string getNameOfTypeOfCurrentInstance() const; std::string getName() const { return _name; } - StreamType edGetType() const { return _edType; } + TypeCode* edGetType() const { return _edType; } }; } } diff --git a/src/engine/ElementaryNode.cxx b/src/engine/ElementaryNode.cxx index b1913d906..ea7a84115 100644 --- a/src/engine/ElementaryNode.cxx +++ b/src/engine/ElementaryNode.cxx @@ -1,4 +1,5 @@ #include "ElementaryNode.hxx" +#include "Runtime.hxx" #include "InputPort.hxx" #include "OutputPort.hxx" #include "ComposedNode.hxx" @@ -6,92 +7,150 @@ #include "OutputDataStreamPort.hxx" using namespace YACS::ENGINE; +using namespace std; -ElementaryNode::ElementaryNode(const std::string& name):Node(name) +ElementaryNode::ElementaryNode(const string& name):Node(name) { } ElementaryNode::~ElementaryNode() { - for(std::list::iterator iter1=_listOfInputPort.begin();iter1!=_listOfInputPort.end();iter1++) + for(set::iterator iter1=_setOfInputPort.begin();iter1!=_setOfInputPort.end();iter1++) delete *iter1; - for(std::list::iterator iter2=_listOfOutputPort.begin();iter2!=_listOfOutputPort.end();iter2++) + for(set::iterator iter2=_setOfOutputPort.begin();iter2!=_setOfOutputPort.end();iter2++) delete *iter2; - for(std::list::iterator iter3=_listOfInputDataStreamPort.begin();iter3!=_listOfInputDataStreamPort.end();iter3++) + for(set::iterator iter3=_setOfInputDataStreamPort.begin();iter3!=_setOfInputDataStreamPort.end();iter3++) delete *iter3; - for(std::list::iterator iter4=_listOfOutputDataStreamPort.begin();iter4!=_listOfOutputDataStreamPort.end();iter4++) + for(set::iterator iter4=_setOfOutputDataStreamPort.begin();iter4!=_setOfOutputDataStreamPort.end();iter4++) delete *iter4; } -void ElementaryNode::getReadyTasks(std::vector& tasks) +/** + * add this node task to a given set of ready tasks, if this task is ready to activate + */ + +void ElementaryNode::getReadyTasks(vector& tasks) { if(_state==YACS::TOACTIVATE) tasks.push_back(this); } +/** + * remove port from node at edition. Ports are typed. + */ + 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(); + throw Exception("ElementaryNode::edRemovePort : Port is not owned by this"); + string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); if(typeOfPortInstance==InputPort::NAME) - edRemovePortTypedFromList(dynamic_cast(port),_listOfInputPort); + edRemovePortTypedFromSet(dynamic_cast(port),_setOfInputPort); else if(typeOfPortInstance==OutputPort::NAME) - edRemovePortTypedFromList(dynamic_cast(port),_listOfOutputPort); + edRemovePortTypedFromSet(dynamic_cast(port),_setOfOutputPort); else if(typeOfPortInstance==InputDataStreamPort::NAME) - edRemovePortTypedFromList(dynamic_cast(port),_listOfInputDataStreamPort); + edRemovePortTypedFromSet(dynamic_cast(port),_setOfInputDataStreamPort); else if(typeOfPortInstance==OutputDataStreamPort::NAME) - edRemovePortTypedFromList(dynamic_cast(port),_listOfOutputDataStreamPort); + edRemovePortTypedFromSet(dynamic_cast(port),_setOfOutputDataStreamPort); else throw Exception("ElementaryNode::edRemovePort : unknown port type"); delete port; } -std::list ElementaryNode::getRecursiveConstituents() +/** + * @return a set with only this node. (Same method in composed nodes) + */ + +set ElementaryNode::getRecursiveConstituents() { - std::list ret; - ret.push_back(this); + set ret; + ret.insert(this); return ret; } -InputPort *ElementaryNode::edAddInputPort(const std::string& inputPortName, YACS::DynType type) throw(Exception) +/** + * the input port is also published recursively in ancestors because it may be visible from everywhere. + * WARNING: CHECK CASE OF BLOC: ONLY INPUT PORTS NOT INTERNALLY CONNECTED MUST BE VISIBLE. + */ + +InputPort *ElementaryNode::edAddInputPort(const string& inputPortName, TypeCode* type) throw(Exception) { - InputPort *ret=edAddPort(inputPortName,_listOfInputPort,type); - //By default all inputports are seen from upper level nodes NOT outputports - ComposedNode *iter=_father; - while(iter) + InputPort *ret = 0; + if (edCheckAddPort(inputPortName,_setOfInputPort,type)) { - iter->publishInputPort(_listOfInputPort.back()); - iter=iter->_father; + //InputPort *ret=edAddPort(inputPortName,_setOfInputPort,type); + ret = getRuntime()->createInputPort(inputPortName, _implementation, this, type); + _setOfInputPort.insert(ret); + //By default all inputports are seen from upper level nodes NOT outputports + ComposedNode *iter=_father; + while(iter) + { + iter->publishInputPort(ret); + iter=iter->_father; + } } return ret; } -OutputPort *ElementaryNode::edAddOutputPort(const std::string& outputPortName, YACS::DynType type) throw(Exception) +/** + * The output port is not published in father. Father must create an output port. + */ + +OutputPort *ElementaryNode::edAddOutputPort(const string& outputPortName, TypeCode* type) throw(Exception) { - return edAddPort(outputPortName,_listOfOutputPort,type); + OutputPort *ret =0; + if (edCheckAddPort(outputPortName,_setOfOutputPort,type)) + { + ret = getRuntime()->createOutputPort(outputPortName, _implementation, this, type); + _setOfOutputPort.insert(ret); + } + return ret; } -InputDataStreamPort *ElementaryNode::edAddInputDataStreamPort(const std::string& inputPortDSName, YACS::StreamType type) throw(Exception) +InputDataStreamPort *ElementaryNode::edAddInputDataStreamPort(const string& inputPortDSName, TypeCode* type) throw(Exception) { - return edAddPort(inputPortDSName,_listOfInputDataStreamPort,type); + return edAddPort(inputPortDSName,_setOfInputDataStreamPort,type); } -OutputDataStreamPort *ElementaryNode::edAddOutputDataStreamPort(const std::string& outputPortDSName, YACS::StreamType type) throw(Exception) +OutputDataStreamPort *ElementaryNode::edAddOutputDataStreamPort(const string& outputPortDSName, TypeCode* type) throw(Exception) { - return edAddPort(outputPortDSName,_listOfOutputDataStreamPort,type); + return edAddPort(outputPortDSName,_setOfOutputDataStreamPort,type); } +/** + * Disconnect all links from output ports of this node to input ports of a given node + */ + void ElementaryNode::disconnectAllLinksConnectedTo(Node *node) { - std::list inputDF=node->getListOfInputPort(); - for(std::list::iterator iter1=_listOfOutputPort.begin();iter1!=_listOfOutputPort.end();iter1++) - for(std::list::iterator iter2=inputDF.begin();iter2!=inputDF.end();iter2++) - (*iter1)->edRemoveInputPort(*iter2); - std::list inputDS=node->getListOfInputDataStreamPort(); - for(std::list::iterator iter3=_listOfOutputDataStreamPort.begin();iter3!=_listOfOutputDataStreamPort.end();iter3++) - for(std::list::iterator iter4=inputDS.begin();iter4!=inputDS.end();iter4++) - (*iter3)->edRemoveInputDataStreamPort(*iter4); + set inputDF=node->getSetOfInputPort(); + for(set::iterator iter1=_setOfOutputPort.begin();iter1!=_setOfOutputPort.end();iter1++) + for(set::iterator iter2=inputDF.begin();iter2!=inputDF.end();iter2++) + (*iter1)->edRemoveInputPortOneWay(*iter2); + set inputDS=node->getSetOfInputDataStreamPort(); + for(set::iterator iter3=_setOfOutputDataStreamPort.begin();iter3!=_setOfOutputDataStreamPort.end();iter3++) + for(set::iterator iter4=inputDS.begin();iter4!=inputDS.end();iter4++) + (*iter3)->edRemoveInputDataStreamPortOneWay(*iter4); + _outGate.edRemoveInGateOneWay(node->getInGate()); +} + +/** + * get the input port name used by the current node (see composed nodes) + */ + +const string ElementaryNode::getInputPortName(const InputPort * inputPort) throw (Exception) +{ + Node *node = inputPort->getNode(); + if ( node != this ) + { + string what("InputPort "); what += inputPort->getName(); what += " does not belong to node "; what += node->getName(); + throw Exception(what); + } + return inputPort->getName(); +} + +const string ElementaryNode::getOutputPortName(const OutputPort *outputPort) throw (Exception) +{ } void ElementaryNode::begin() diff --git a/src/engine/ElementaryNode.hxx b/src/engine/ElementaryNode.hxx index 3bafac5e8..7937cccac 100644 --- a/src/engine/ElementaryNode.hxx +++ b/src/engine/ElementaryNode.hxx @@ -1,9 +1,12 @@ #ifndef __ELEMENTARYNODE_HXX__ #define __ELEMENTARYNODE_HXX__ +#include "TypeCode.hxx" #include "Node.hxx" #include "Task.hxx" #include "define.hxx" +//#include "Data.hxx" +#include namespace YACS { @@ -25,11 +28,13 @@ namespace YACS public: void getReadyTasks(std::vector& tasks); void edRemovePort(Port *port) throw(Exception); - std::list 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); + std::set getRecursiveConstituents(); + virtual InputPort *edAddInputPort(const std::string& inputPortName, TypeCode* type) throw(Exception); + virtual OutputPort *edAddOutputPort(const std::string& outputPortName, TypeCode* type) throw(Exception); + virtual InputDataStreamPort *edAddInputDataStreamPort(const std::string& inputPortDSName, TypeCode* type) throw(Exception); + virtual OutputDataStreamPort *edAddOutputDataStreamPort(const std::string& outputPortDSName, TypeCode* type) throw(Exception); + virtual const std::string getInputPortName(const InputPort *) throw (Exception); + virtual const std::string getOutputPortName(const OutputPort *) throw (Exception); //run part void begin(); bool isReady(); diff --git a/src/engine/Executor.cxx b/src/engine/Executor.cxx index 64938dad5..f9f8f3669 100644 --- a/src/engine/Executor.cxx +++ b/src/engine/Executor.cxx @@ -5,6 +5,7 @@ #include using namespace YACS::ENGINE; +using namespace std; using YACS::BASES::Mutex; using YACS::BASES::Thread; @@ -16,7 +17,7 @@ Executor::Executor():_nbOfConcurrentThreads(0)//,_cond(PTHREAD_COND_INITIALIZER) Executor::~Executor() { - for(std::list::iterator iter=_groupOfAllThreadsCreated.begin();iter!=_groupOfAllThreadsCreated.end();iter++) + for(list::iterator iter=_groupOfAllThreadsCreated.begin();iter!=_groupOfAllThreadsCreated.end();iter++) delete *iter; } @@ -26,8 +27,8 @@ void Executor::RunW(Scheduler *graph) bool isMore; int i=0; graph->init(); - std::vector tasks; - std::vector::iterator iter; + vector tasks; + vector::iterator iter; bool toContinue=true; wakeUp(); while(toContinue) @@ -55,7 +56,7 @@ void Executor::launchTask(Task *task) void **args=new void *[3]; _mutexForNbOfConcurrentThreads.lock(); _groupOfAllThreadsCreated.push_back(0); - std::list::iterator iter=_groupOfAllThreadsCreated.end(); + list::iterator iter=_groupOfAllThreadsCreated.end(); iter--; _mutexForNbOfConcurrentThreads.unlock(); args[0]=(void *)task; diff --git a/src/engine/InGate.cxx b/src/engine/InGate.cxx index 57008d4ef..ec6574e18 100644 --- a/src/engine/InGate.cxx +++ b/src/engine/InGate.cxx @@ -2,6 +2,7 @@ #include "Node.hxx" using namespace YACS::ENGINE; +using namespace std; const char InGate::NAME[]="InGate"; @@ -9,7 +10,7 @@ InGate::InGate(Node *node):Port(node),_nbPrecursor(0),_nbPrecursorDone(0),_colou { } -std::string InGate::getNameOfTypeOfCurrentInstance() const +string InGate::getNameOfTypeOfCurrentInstance() const { return NAME; } diff --git a/src/engine/InputDataStreamPort.cxx b/src/engine/InputDataStreamPort.cxx index 8c54db5b5..305ea9992 100644 --- a/src/engine/InputDataStreamPort.cxx +++ b/src/engine/InputDataStreamPort.cxx @@ -1,16 +1,17 @@ #include "InputDataStreamPort.hxx" using namespace YACS::ENGINE; +using namespace std; const char InputDataStreamPort::NAME[]="InputDataStreamPort"; -InputDataStreamPort::InputDataStreamPort(const std::string& name, Node *node, StreamType type):DataStreamPort(name,node,type), +InputDataStreamPort::InputDataStreamPort(const string& name, Node *node, TypeCode* type):DataStreamPort(name,node,type), InPort(node), Port(node) { } -std::string InputDataStreamPort::getNameOfTypeOfCurrentInstance() const +string InputDataStreamPort::getNameOfTypeOfCurrentInstance() const { return NAME; } diff --git a/src/engine/InputDataStreamPort.hxx b/src/engine/InputDataStreamPort.hxx index e62687e8e..468f02ed9 100644 --- a/src/engine/InputDataStreamPort.hxx +++ b/src/engine/InputDataStreamPort.hxx @@ -13,7 +13,7 @@ namespace YACS public: static const char NAME[]; public: - InputDataStreamPort(const std::string& name, Node *node, StreamType type); + InputDataStreamPort(const std::string& name, Node *node, TypeCode* type); std::string getNameOfTypeOfCurrentInstance() const; }; } diff --git a/src/engine/InputPort.cxx b/src/engine/InputPort.cxx index c14347fc8..3a7c97540 100644 --- a/src/engine/InputPort.cxx +++ b/src/engine/InputPort.cxx @@ -1,23 +1,28 @@ #include "InputPort.hxx" +#include +#include + using namespace YACS::ENGINE; +using namespace std; 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) +InputPort::InputPort(const string& name, Node *node, TypeCode* type) + : DataFlowPort(name,node,type), InPort(node),Port(node), _manuallySet(false), _empty(true) { } -std::string InputPort::getNameOfTypeOfCurrentInstance() const +string InputPort::getNameOfTypeOfCurrentInstance() const { return NAME; } -void InputPort::edInit(Data data) throw(ConversionException) -{ - _data=data; - _manuallySet=true; -} +// void InputPort::edInit(Data data) throw(ConversionException) +// { +// _data=data; +// _manuallySet=true; +// } void InputPort::edNotifyReferenced() { @@ -26,20 +31,33 @@ void InputPort::edNotifyReferenced() void InputPort::exInit() { - if(!_manuallySet) - _data.exInit(); +// if(!_manuallySet) +// _data.exInit(); +} + +bool InputPort::isEmpty() +{ + return _empty; } -Data InputPort::exGet() const +void InputPort::edInit(const void *data) throw(ConversionException) { - return _data; + _manuallySet=true; + put(data); } -void InputPort::exAccept(Data data) throw(ConversionException) +void InputPort::put(const void *data) throw(ConversionException) { - _data=data; +// _data = (void *)data; + cerr << _name << endl; + cerr << _impl << endl; + stringstream msg; + msg << "Not implemented (" << __FILE__ << ":" << __LINE__ << ")"; + throw Exception(msg.str()); } + + InputPort::~InputPort() { } diff --git a/src/engine/InputPort.hxx b/src/engine/InputPort.hxx index 815b497de..20d550661 100644 --- a/src/engine/InputPort.hxx +++ b/src/engine/InputPort.hxx @@ -1,30 +1,61 @@ #ifndef __INPUTPORT_HXX__ #define __INPUTPORT_HXX__ +//#include +//#include + +#include "TypeCode.hxx" #include "InPort.hxx" #include "DataFlowPort.hxx" #include "ConversionException.hxx" +#include + namespace YACS { namespace ENGINE { + + class Runtime; + class InputPort : public DataFlowPort, public InPort { - protected: - bool _manuallySet; - public: - static const char NAME[]; + friend class Runtime; // for port creation public: - InputPort(const std::string& name, Node *node, DynType type); + ~InputPort(); + std::string getNameOfTypeOfCurrentInstance() const; - void edInit(Data data) throw(ConversionException); + void edNotifyReferenced(); + void edInit(const void *data) throw(ConversionException); + void exInit(); - Data exGet() const; - void exAccept(Data data) throw(ConversionException); - ~InputPort(); + bool isEmpty(); + + virtual void put(const void *data) throw(ConversionException); + + static const char NAME[]; + + protected: + InputPort(const std::string& name, Node *node, TypeCode* type); + bool _empty; + bool _manuallySet; + }; + + + class ProxyPort : public InputPort + { + public: + ProxyPort(InputPort* p) + : InputPort("Convertor", p->getNode(), p->type()), + Port( p->getNode()) + { _port = p; } + protected: + InputPort* _port; }; + + + } } diff --git a/src/engine/Loop.cxx b/src/engine/Loop.cxx index 94bf78e20..b9a2960b7 100644 --- a/src/engine/Loop.cxx +++ b/src/engine/Loop.cxx @@ -3,30 +3,35 @@ #include "OutputPort.hxx" #include "InputDataStreamPort.hxx" #include "OutputDataStreamPort.hxx" -#include "TypeCheckerDataStream.hxx" +#include "Runtime.hxx" + +//#include "TypeCheckerDataStream.hxx" using namespace YACS::ENGINE; +using namespace std; -DFToDSForLoop::DFToDSForLoop(Loop *loop, const std::string& name, YACS::DynType type):ElementaryNode(""),_nbOfTimeUsed(1) +DFToDSForLoop::DFToDSForLoop(Loop *loop, const string& name, TypeCode* 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))); +// _setOfInputPort.insert(new InputPort("",this,type)); // probleme si constructeur protege, a voir + _setOfOutputDataStreamPort.insert(new OutputDataStreamPort("",this,Loop::MappingDF2DS(type))); } DFToDSForLoop::~DFToDSForLoop() { } -InputPort *DFToDSForLoop::getInputPort(const std::string& name) const throw(Exception) +InputPort *DFToDSForLoop::getInputPort(const string& name) const throw(Exception) { - return (InputPort *) &_listOfInputPort.back(); + set::iterator it =_setOfInputPort.begin(); + return (*it); } -OutputDataStreamPort *DFToDSForLoop::getOutputDataStreamPort(const std::string& name) const throw(Exception) +OutputDataStreamPort *DFToDSForLoop::getOutputDataStreamPort(const string& name) const throw(Exception) { - return (OutputDataStreamPort *) &_listOfOutputDataStreamPort.back(); + set ::iterator it =_setOfOutputDataStreamPort.begin(); + return (*it); } void DFToDSForLoop::execute() @@ -34,26 +39,28 @@ void DFToDSForLoop::execute() //TO IMPLEMENT } -DSToDFForLoop::DSToDFForLoop(Loop *loop, const std::string& name, YACS::StreamType type):ElementaryNode(""),_nbOfTimeUsed(1) +DSToDFForLoop::DSToDFForLoop(Loop *loop, const string& name, TypeCode* 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)); + // _setOfOutputPort.insert(new OutputPort("",this,Loop::MappingDS2DF(type))); // probleme si constructeur protege, a voir + _setOfInputDataStreamPort.insert(new InputDataStreamPort("",this,type)); } DSToDFForLoop::~DSToDFForLoop() { } -OutputPort *DSToDFForLoop::getOutputPort(const std::string& name) const throw(Exception) +OutputPort *DSToDFForLoop::getOutputPort(const string& name) const throw(Exception) { - return (OutputPort *) &_listOfOutputPort.back(); + set::iterator it = _setOfOutputPort.begin(); + return (*it); } -InputDataStreamPort *DSToDFForLoop::getInputDataStreamPort(const std::string& name) const throw(Exception) +InputDataStreamPort *DSToDFForLoop::getInputDataStreamPort(const string& name) const throw(Exception) { - return (InputDataStreamPort *) &_listOfInputDataStreamPort.back(); + set::iterator it = _setOfInputDataStreamPort.begin(); + return (*it); } void DSToDFForLoop::execute() @@ -61,7 +68,7 @@ void DSToDFForLoop::execute() //TO IMPLEMENT } -Loop::Loop(const std::string& name):ComposedNode(name),_node(0) +Loop::Loop(const string& name):ComposedNode(name),_node(0) { } @@ -76,187 +83,194 @@ void Loop::edSetNode(Node *node) _node=node; } -void Loop::edAddExtraInputPort(const std::string& inputPortName, YACS::DynType type) throw(Exception) +void Loop::edAddExtraInputPort(const string& inputPortName, TypeCode* type) throw(Exception) { - edAddPort(inputPortName,_listOfExtraInputPort,type); + InputPort *ret = 0; + if (edCheckAddPort(inputPortName,_setOfInputPort,type)) + { + //InputPort *ret=edAddPort(inputPortName,_setOfInputPort,type); + ret = getRuntime()->createInputPort(inputPortName, _implementation, this, type); + _setOfExtraInputPort.insert(ret); + } + //edAddPort(inputPortName,_setOfExtraInputPort,type); } void Loop::edRemoveExtraInputPort(InputPort *inputPort) { - edRemovePortTypedFromList(inputPort,_listOfExtraInputPort); + edRemovePortTypedFromSet(inputPort,_setOfExtraInputPort); } -YACS::StreamType Loop::MappingDF2DS(YACS::DynType type) throw(Exception) +TypeCode* Loop::MappingDF2DS(TypeCode* 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); +// switch(type) +// { +// case Double: +// return SDouble; +// } + 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) +TypeCode* Loop::MappingDS2DF(TypeCode* 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); +// switch(type) +// { +// case SDouble: +// return Double; +// } + 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& pointsOfView) +InPort *Loop::buildDelegateOf(InPort *port, const set& pointsOfView) { - std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); + string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); if(typeOfPortInstance!=InputPort::NAME) return port; else if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) return port; InputPort *portCasted=(InputPort *)port; - std::list::iterator iter; + set::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)) + if((*iter)->getOutputPort("")->isAlreadyInSet(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()))); + _inputsTraducer.insert(new DSToDFForLoop(this,portCasted->getName(),Loop::MappingDF2DS(portCasted->edGetType()))); iter=_inputsTraducer.end(); iter--; - (*iter).getOutputPort("")->edAddInputPort(portCasted); + (*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 + (*iter)->getOutGate()->edAddInGate(portCasted->getNode()->getInGate());//WARNING HERE MAYBE HAS TO BE IMPROVED - SEPARATE COUNTERS } else - (*iter).loopHasOneMoreRef(); - return (*iter).getInputDataStreamPort(""); + (*iter)->loopHasOneMoreRef(); + return (*iter)->getInputDataStreamPort(""); } -OutPort *Loop::buildDelegateOf(OutPort *port, const std::list& pointsOfView) +OutPort *Loop::buildDelegateOf(OutPort *port, const set& pointsOfView) { - std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); + string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); if(typeOfPortInstance!=OutputPort::NAME) return port; else if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) return port; OutputPort *portCasted=(OutputPort *)port; - std::list::iterator iter; + set::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(""))) + if(portCasted->isAlreadyInSet((*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())); + _outputsTraducer.insert(new DFToDSForLoop(this,portCasted->getName(),portCasted->edGetType())); iter=_outputsTraducer.end(); iter--; - portCasted->edAddInputPort((*iter).getInputPort("")); + 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 + portCasted->getNode()->getOutGate()->edAddInGate((*iter)->getInGate());//WARNING HERE MAYBE HAS TO BE IMPROVED - SEPARATE COUNTERS } else - (*iter).loopHasOneMoreRef(); - return (*iter).getOutputDataStreamPort(""); + (*iter)->loopHasOneMoreRef(); + return (*iter)->getOutputDataStreamPort(""); } -InPort *Loop::getDelegateOf(InPort *port, const std::list& pointsOfView) throw(Exception) +InPort *Loop::getDelegateOf(InPort *port, const set& pointsOfView) throw(Exception) { - std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); + string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); if(typeOfPortInstance!=InputPort::NAME) return port; else if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) return port; InputPort *portCasted=(InputPort *)port; - std::list::iterator iter; + set::iterator iter; for(iter=_inputsTraducer.begin();iter!=_inputsTraducer.end();iter++) - if((*iter).getOutputPort("")->isAlreadyInList(portCasted)) + if((*iter)->getOutputPort("")->isAlreadyInSet(portCasted)) break; if(iter==_inputsTraducer.end()) { - std::string what("Loop::getDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; + string what("Loop::getDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; throw Exception(what); } else - return (*iter).getInputDataStreamPort(""); + return (*iter)->getInputDataStreamPort(""); } -OutPort *Loop::getDelegateOf(OutPort *port, const std::list& pointsOfView) throw(Exception) +OutPort *Loop::getDelegateOf(OutPort *port, const set& pointsOfView) throw(Exception) { - std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); + string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); if(typeOfPortInstance!=OutputPort::NAME) return port; else if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) return port; OutputPort *portCasted=(OutputPort *)port; - std::list::iterator iter; + set::iterator iter; for(iter=_outputsTraducer.begin();iter!=_outputsTraducer.end();iter++) - if(portCasted->isAlreadyInList((*iter).getInputPort(""))) + if(portCasted->isAlreadyInSet((*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; + string what("Loop::getDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; throw Exception(what); } else - return (*iter).getOutputDataStreamPort(""); + return (*iter)->getOutputDataStreamPort(""); } -InPort *Loop::releaseDelegateOf(InPort *port, const std::list& pointsOfView) throw(Exception) +InPort *Loop::releaseDelegateOf(InPort *port, const set& pointsOfView) throw(Exception) { - std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); + string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); if(typeOfPortInstance!=InputPort::NAME) return port; else if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) return port; InputPort *portCasted=(InputPort *)port; - std::list::iterator iter; + set::iterator iter; for(iter=_inputsTraducer.begin();iter!=_inputsTraducer.end();iter++) - if((*iter).getOutputPort("")->isAlreadyInList(portCasted)) + if((*iter)->getOutputPort("")->isAlreadyInSet(portCasted)) break; if(iter==_inputsTraducer.end()) { - std::string what("Loop::releaseDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; + 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()) + InPort *ret=(*iter)->getInputDataStreamPort(""); + if((*iter)->loopHasOneLessRef()) _inputsTraducer.erase(iter); return ret; } } -OutPort *Loop::releaseDelegateOf(OutPort *port, const std::list& pointsOfView) throw(Exception) +OutPort *Loop::releaseDelegateOf(OutPort *port, const set& pointsOfView) throw(Exception) { - std::string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); + string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); if(typeOfPortInstance!=OutputPort::NAME) return port; else if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) return port; OutputPort *portCasted=(OutputPort *)port; - std::list::iterator iter; + set::iterator iter; for(iter=_outputsTraducer.begin();iter!=_outputsTraducer.end();iter++) - if(portCasted->isAlreadyInList((*iter).getInputPort(""))) + if(portCasted->isAlreadyInSet((*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; + 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()) + OutPort *ret=(*iter)->getOutputDataStreamPort(""); + if((*iter)->loopHasOneLessRef()) _outputsTraducer.erase(iter); return ret; } @@ -268,15 +282,15 @@ void Loop::checkNoCyclePassingThrough(Node *node) throw(Exception) } /** - * @ 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 : + * @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& pointsOfView) +bool Loop::isNecessaryToBuildSpecificDelegateDF2DS(const set& pointsOfView) { bool ret=false; - for(std::list::const_iterator iter=pointsOfView.begin();iter!=pointsOfView.end() && !ret;iter++) + for(set::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 index 2df59123e..f3ed0eb32 100644 --- a/src/engine/Loop.hxx +++ b/src/engine/Loop.hxx @@ -17,7 +17,7 @@ namespace YACS int _nbOfTimeUsed; Loop *_loopArtificiallyBuiltMe; private: - DFToDSForLoop(Loop *loop, const std::string& name, YACS::DynType type); + DFToDSForLoop(Loop *loop, const std::string& name, TypeCode* type); void loopHasOneMoreRef() { _nbOfTimeUsed++; } bool loopHasOneLessRef() { return --_nbOfTimeUsed==0; } InputPort *getInputPort(const std::string& name) const throw(Exception); @@ -35,7 +35,7 @@ namespace YACS int _nbOfTimeUsed; Loop *_loopArtificiallyBuiltMe; private: - DSToDFForLoop(Loop *loop, const std::string& name, YACS::StreamType type); + DSToDFForLoop(Loop *loop, const std::string& name, TypeCode* type); void loopHasOneMoreRef() { _nbOfTimeUsed++; } bool loopHasOneLessRef() { return --_nbOfTimeUsed==0; } OutputPort *getOutputPort(const std::string& name) const throw(Exception); @@ -50,27 +50,27 @@ namespace YACS { protected: Node *_node; - std::list _listOfExtraInputPort; - std::list _inputsTraducer; - std::list _outputsTraducer; + std::set _setOfExtraInputPort; + std::set _inputsTraducer; + std::set _outputsTraducer; public: Loop(const std::string& name); ~Loop(); void edSetNode(Node *node); - void edAddExtraInputPort(const std::string& inputPortName, YACS::DynType type) throw(Exception); + void edAddExtraInputPort(const std::string& inputPortName, TypeCode* 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); + static TypeCode* MappingDF2DS(TypeCode* type) throw(Exception); + static TypeCode* MappingDS2DF(TypeCode* type) throw(Exception); protected: - InPort *buildDelegateOf(InPort *port, const std::list& pointsOfView); - OutPort *buildDelegateOf(OutPort *port, const std::list& pointsOfView); - InPort *getDelegateOf(InPort *port, const std::list& pointsOfView) throw(Exception); - OutPort *getDelegateOf(OutPort *port, const std::list& pointsOfView) throw(Exception); - InPort *releaseDelegateOf(InPort *port, const std::list& pointsOfView) throw(Exception); - OutPort *releaseDelegateOf(OutPort *port, const std::list& pointsOfView) throw(Exception); + InPort *buildDelegateOf(InPort *port, const std::set& pointsOfView); + OutPort *buildDelegateOf(OutPort *port, const std::set& pointsOfView); + InPort *getDelegateOf(InPort *port, const std::set& pointsOfView) throw(Exception); + OutPort *getDelegateOf(OutPort *port, const std::set& pointsOfView) throw(Exception); + InPort *releaseDelegateOf(InPort *port, const std::set& pointsOfView) throw(Exception); + OutPort *releaseDelegateOf(OutPort *port, const std::set& pointsOfView) throw(Exception); void checkNoCyclePassingThrough(Node *node) throw(Exception); - static bool isNecessaryToBuildSpecificDelegateDF2DS(const std::list& pointsOfView); + static bool isNecessaryToBuildSpecificDelegateDF2DS(const std::set& pointsOfView); }; } } diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am index 174ae78f0..476b4cf33 100644 --- a/src/engine/Makefile.am +++ b/src/engine/Makefile.am @@ -6,6 +6,8 @@ SUBDIRS = Test lib_LTLIBRARIES = libYACSEngine.la libYACSEngine_la_SOURCES = \ + TypeCode.cxx \ + ConversionException.cxx \ Port.cxx InGate.cxx \ OutGate.cxx \ DataFlowPort.cxx \ @@ -22,6 +24,7 @@ libYACSEngine_la_SOURCES = \ Bloc.cxx \ Loop.cxx \ Switch.cxx \ + Runtime.cxx \ Scheduler.hxx \ Task.hxx \ Executor.cxx \ @@ -30,11 +33,9 @@ libYACSEngine_la_SOURCES = \ EXTRA_libYACSEngine_la_SOURCES = \ $(__dummy__) -libYACSEngine_la_LIBADD = ../bases/libYACSBases.la \ - ../basicData/libYACSBasicData.la +libYACSEngine_la_LIBADD = ../bases/libYACSBases.la AM_CXXFLAGS = $(THREAD_DEF) \ - -I$(srcdir)/../bases \ - -I$(srcdir)/../basicData + -I$(srcdir)/../bases include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/engine/Node.cxx b/src/engine/Node.cxx index 31c93a4b8..5f08eea00 100644 --- a/src/engine/Node.cxx +++ b/src/engine/Node.cxx @@ -6,8 +6,9 @@ #include "OutputDataStreamPort.hxx" using namespace YACS::ENGINE; +using namespace std; -Node::Node(const std::string& name):_name(name),_inGate(this),_outGate(this),_father(0),_colour(YACS::White),_state(YACS::INITED) +Node::Node(const string& name):_name(name),_inGate(this),_outGate(this),_father(0),_colour(YACS::White),_state(YACS::INITED) { } @@ -15,12 +16,16 @@ Node::~Node() { } +/** + * initialisation of all input and output ports and gates, for execution + */ + void Node::init() { _inGate.exReset(); - for(std::list::iterator iter=_listOfOutputPort.begin();iter!=_listOfOutputPort.end();iter++) + for(set::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++) (*iter)->exInit(); - for(std::list::iterator iter2=_listOfInputPort.begin();iter2!=_listOfInputPort.end();iter2++) + for(set::iterator iter2=_setOfInputPort.begin();iter2!=_setOfInputPort.end();iter2++) (*iter2)->exInit(); if(_inGate.exIsReady()) _state=YACS::TOACTIVATE; @@ -28,19 +33,24 @@ void Node::init() _state=YACS::INITED; } -std::list Node::getOutNodes() const +/** + * get the set of all nodes connected to the outGate + */ + +set Node::getOutNodes() const { - std::list ret; - std::list inGates=_outGate.edListInGate(); - for(std::list::iterator iter=inGates.begin();iter!=inGates.end();iter++) - ret.push_back((*iter)->getNode()); + set ret; + set inGates=_outGate.edSetInGate(); + for(set::iterator iter=inGates.begin();iter!=inGates.end();iter++) + ret.insert((*iter)->getNode()); return ret; } /** - * @ note : Update the '_state' attribute. + * @note : Update the '_state' attribute. * Typically called by 'this->_inGate' when 'this->_inGate' is ready. */ + void Node::exUpdateState() { if(_inGate.exIsReady()) @@ -48,7 +58,7 @@ void Node::exUpdateState() _state=YACS::TOACTIVATE; else { - std::string what("Node::exUpdateState : Invalid graph given : Node with name \""); + 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); } @@ -56,47 +66,75 @@ void Node::exUpdateState() int Node::getNumberOfInputPorts() const { - return _listOfInputPort.size(); + return _setOfInputPort.size(); } int Node::getNumberOfOutputPorts() const { - return _listOfOutputPort.size(); + return _setOfOutputPort.size(); } -InputPort *Node::getInputPort(const std::string& name) const throw(Exception) +InputPort *Node::getInputPort(const string& name) const throw(Exception) { - return getPort(name,_listOfInputPort); + return getPort(name,_setOfInputPort); } -OutputPort *Node::getOutputPort(const std::string& name) const throw(Exception) +OutputPort *Node::getOutputPort(const string& name) const throw(Exception) { - return getPort(name,_listOfOutputPort); + return getPort(name,_setOfOutputPort); } -InputDataStreamPort *Node::getInputDataStreamPort(const std::string& name) const throw(Exception) +InputDataStreamPort *Node::getInputDataStreamPort(const string& name) const throw(Exception) { - return getPort(name,_listOfInputDataStreamPort); + return getPort(name,_setOfInputDataStreamPort); } -OutputDataStreamPort *Node::getOutputDataStreamPort(const std::string& name) const throw(Exception) +OutputDataStreamPort *Node::getOutputDataStreamPort(const string& name) const throw(Exception) { - return getPort(name,_listOfOutputDataStreamPort); + return getPort(name,_setOfOutputDataStreamPort); } -std::list Node::getAllAscendanceOf(ComposedNode *levelToStop) + +/** + * gets a set of the composed nodes that constitute the ascendancy of this node, starting from root + * or from a particular ancestor + * @param levelToStop composed node which is the oldest ancestor required + * @return ascendancy, direct father first in set. + */ + +set Node::getAllAscendanceOf(ComposedNode *levelToStop) { - std::list ret; + set ret; for(ComposedNode *iter=_father;iter!=levelToStop && iter!=0; iter=iter->_father) - ret.push_back(iter); + ret.insert(iter); return ret; } +/** + * @return Implementation of node: C++, Python, CORBA... + * _implementation is set by a derived class in a Runtime + * it normally applies only to elementaryNodes and it is used by Ports to select Data Converters. + * Potential problem with Ports attached to composed Nodes... + */ + +string Node::getImplementation() +{ + return _implementation; +} + +/** + * checks if all input ports contains a valid data. Used at execution to change the state of the node + * for activation. + */ + bool Node::areAllInputPortsValid() const { bool ret=true; - for(std::list::const_iterator iter=_listOfInputPort.begin();iter!=_listOfInputPort.end();iter++) - ret=!(*iter)->exGet().empty(); + for(set::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + { + ret=!(*iter)->isEmpty(); + if (!ret) break; + } return ret; } @@ -110,18 +148,23 @@ ComposedNode *Node::getRootNode() throw(Exception) return iter; } -void Node::checkValidityOfPortName(const std::string& name) throw(Exception) +/** + * checks validity of ports name, that must not contain a particular character '?' + * USAGE NOT CLEAR, not used so far, when are those characters set ? + */ + +void Node::checkValidityOfPortName(const string& name) throw(Exception) { - if(name.find(SEP_CHAR_IN_PORT, 0 )!=std::string::npos) + if(name.find(SEP_CHAR_IN_PORT, 0 )!=string::npos) { - std::string what("Port name "); what+=name; what+="not valid because it contains character "; what+=SEP_CHAR_IN_PORT; + 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 + * @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) { @@ -133,10 +176,15 @@ ComposedNode *Node::checkHavingCommonFather(Node *node1, Node *node2) throw(Exce throw Exception("check failed : nodes have not the same father"); } +/** + * set color for inGates : display + * USAGE NOT CLEAR, not used so far + */ + void Node::initForDFS() const { _colour=YACS::White; - std::list inGates=_outGate.edListInGate(); - for(std::list::iterator iter=inGates.begin();iter!=inGates.end();iter++) + set inGates=_outGate.edSetInGate(); + for(set::iterator iter=inGates.begin();iter!=inGates.end();iter++) (*iter)->initForDFS(); } diff --git a/src/engine/Node.hxx b/src/engine/Node.hxx index 8b24223c8..fda509861 100644 --- a/src/engine/Node.hxx +++ b/src/engine/Node.hxx @@ -1,12 +1,12 @@ #ifndef __NODE_HXX__ #define __NODE_HXX__ -#include "define.hxx" #include "InGate.hxx" #include "OutGate.hxx" #include "Exception.hxx" +#include "define.hxx" -#include +#include #include #include @@ -33,11 +33,12 @@ namespace YACS std::string _name; ComposedNode *_father; YACS::StatesForNode _state; - std::list _listOfInputPort; - std::list _listOfOutputPort; - std::list _listOfInputDataStreamPort; - std::list _listOfOutputDataStreamPort; + std::set _setOfInputPort; + std::set _setOfOutputPort; + std::set _setOfInputDataStreamPort; + std::set _setOfOutputDataStreamPort; static const char SEP_CHAR_IN_PORT='?'; + std::string _implementation; private: //for graphs algorithms mutable YACS::Colour _colour; @@ -49,21 +50,24 @@ namespace YACS InGate *getInGate() { return &_inGate; } OutGate *getOutGate() { return &_outGate; } const std::string& getName() const { return _name; } - std::list getOutNodes() const; + std::set getOutNodes() const; virtual void exUpdateState(); virtual void getReadyTasks(std::vector& tasks) = 0; - virtual std::list getRecursiveConstituents() = 0; + virtual std::set getRecursiveConstituents() = 0; virtual int getNumberOfInputPorts() const; virtual int getNumberOfOutputPorts() const; - virtual std::list getListOfInputPort() const { return _listOfInputPort; } - virtual std::list getListOfOutputPort() const { return _listOfOutputPort; } + virtual std::set getSetOfInputPort() const { return _setOfInputPort; } + virtual std::set getSetOfOutputPort() const { return _setOfOutputPort; } virtual InputPort *getInputPort(const std::string& name) const throw(Exception); virtual OutputPort *getOutputPort(const std::string& name) const throw(Exception); - virtual std::list getListOfInputDataStreamPort() const { return _listOfInputDataStreamPort; } - virtual std::list getListOfOutputDataStreamPort() const { return _listOfOutputDataStreamPort; } + virtual const std::string getInputPortName(const InputPort *) throw (Exception) =0; + virtual const std::string getOutputPortName(const OutputPort *) throw (Exception) =0; + virtual std::set getSetOfInputDataStreamPort() const { return _setOfInputDataStreamPort; } + virtual std::set getSetOfOutputDataStreamPort() const { return _setOfOutputDataStreamPort; } virtual InputDataStreamPort *getInputDataStreamPort(const std::string& name) const throw(Exception); virtual OutputDataStreamPort *getOutputDataStreamPort(const std::string& name) const throw(Exception); - std::list getAllAscendanceOf(ComposedNode *levelToStop = 0); + std::set getAllAscendanceOf(ComposedNode *levelToStop = 0); + std::string getImplementation(); protected: bool areAllInputPortsValid() const; virtual ComposedNode *getRootNode() throw(Exception); @@ -71,21 +75,27 @@ namespace YACS static void checkValidityOfPortName(const std::string& name) throw(Exception); static ComposedNode *checkHavingCommonFather(Node *node1, Node *node2) throw(Exception); template - PORT *getPort(const std::string& name, const std::list& listOfPorts) const throw(Exception); + PORT *getPort(const std::string& name, const std::set& setOfPorts) const throw(Exception); template - PORT *edAddPort(const std::string& portName, std::list& listOfPorts, ENUMTYPE type) throw(Exception); + PORT *edAddPort(const std::string& portName, std::set& setOfPorts, ENUMTYPE type) throw(Exception); + template + bool edCheckAddPort(const std::string& portName, std::set& setOfPorts, ENUMTYPE type) throw(Exception); template - static void edRemovePortTypedFromList(PORT *port, std::list& listOfPorts) throw(Exception); + static void edRemovePortTypedFromSet(PORT *port, std::set& setOfPorts) throw(Exception); template - static bool isPortNameAlreadyExist(const std::string& portName, const std::list& listOfPorts); + static bool isPortNameAlreadyExist(const std::string& portName, const std::set& setOfPorts); private: void initForDFS() const; }; + /** + * protected: get a port in a set given it's name + */ + template - PORT *Node::getPort(const std::string& name, const std::list& listOfPorts) const throw(Exception) + PORT *Node::getPort(const std::string& name, const std::set& setOfPorts) const throw(Exception) { - for(typename std::list::const_iterator iter=listOfPorts.begin();iter!=listOfPorts.end();iter++) + for(typename std::set::const_iterator iter=setOfPorts.begin();iter!=setOfPorts.end();iter++) { if((*iter)->getName()==name) return *iter; @@ -96,32 +106,61 @@ namespace YACS throw Exception(what); } + /** + * protected: add a port given it's name and type, in a given set of ports + * WHY TEMPLATE PARAMETER ENUMTYPE? + */ + template - PORT *Node::edAddPort(const std::string& portName, std::list& listOfPorts, ENUMTYPE type) throw(Exception) + PORT *Node::edAddPort(const std::string& portName, std::set& setOfPorts, ENUMTYPE type) throw(Exception) { checkValidityOfPortName(portName); - if(isPortNameAlreadyExist(portName, listOfPorts)) + if(isPortNameAlreadyExist(portName, setOfPorts)) { 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); + // PORT *ret= getRuntime()->createInputPort(portName, _implementation, type); + setOfPorts.insert(ret); return ret; } + template + bool Node::edCheckAddPort(const std::string& portName, std::set& setOfPorts, ENUMTYPE type) throw(Exception) + { + checkValidityOfPortName(portName); + if(isPortNameAlreadyExist(portName, setOfPorts)) + { + 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); +// PORT *ret= getRuntime()->createOutputPort(portName, _implementation, type); +// setOfPorts.insert(ret); + return true; + } + + /** + * protected: remove a port from a given set + */ + template - void Node::edRemovePortTypedFromList(PORT *port, std::list& listOfPorts) throw(Exception) + void Node::edRemovePortTypedFromSet(PORT *port, std::set& setOfPorts) throw(Exception) { - if(!isPortNameAlreadyExist(port->getName(), listOfPorts)) - throw Exception("Port is not part of the list : unable to remove it"); - listOfPorts.remove(port); + if(!isPortNameAlreadyExist(port->getName(), setOfPorts)) + throw Exception("Port is not part of the set : unable to remove it"); + setOfPorts.erase(port); } + /** + * protected: checks existence of a port, given it's name, in a set + */ + template - bool Node::isPortNameAlreadyExist(const std::string& portName, const std::list& listOfPorts) + bool Node::isPortNameAlreadyExist(const std::string& portName, const std::set& setOfPorts) { - for(typename std::list::const_iterator iter=listOfPorts.begin();iter!=listOfPorts.end();iter++) + for(typename std::set::const_iterator iter=setOfPorts.begin();iter!=setOfPorts.end();iter++) { if((*iter)->getName()==portName) return true; diff --git a/src/engine/OutGate.cxx b/src/engine/OutGate.cxx index 4a0ff1265..3781918fd 100644 --- a/src/engine/OutGate.cxx +++ b/src/engine/OutGate.cxx @@ -10,41 +10,41 @@ OutGate::OutGate(Node *node):Port(node) { } -std::string OutGate::getNameOfTypeOfCurrentInstance() const +string OutGate::getNameOfTypeOfCurrentInstance() const { return NAME; } void OutGate::exNotifyDone() { - for(list::iterator iter=_listOfInGate.begin();iter!=_listOfInGate.end();iter++) + for(set::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) (*iter)->exNotifyFromPrecursor(); } bool OutGate::edAddInGate(InGate *inGate) { - if(!isAlreadyInList(inGate)) + if(!isAlreadyInSet(inGate)) { inGate->edAppendPrecursor(); - _listOfInGate.push_back(inGate); + _setOfInGate.insert(inGate); return true; } else return false; } -std::list OutGate::edListInGate() const +set OutGate::edSetInGate() const { - return _listOfInGate; + return _setOfInGate; } void OutGate::edRemoveInGate(InGate *inGate) throw(Exception) { bool found=false; - for(list::iterator iter=_listOfInGate.begin();iter!=_listOfInGate.end() && !found;iter++) + for(set::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end() && !found;iter++) if((*iter)==inGate) { - _listOfInGate.erase(iter); + _setOfInGate.erase(iter); inGate->edRemovePrecursor(); found=true; } @@ -52,10 +52,23 @@ void OutGate::edRemoveInGate(InGate *inGate) throw(Exception) throw Exception("InGate not already connected to OutGate"); } -bool OutGate::isAlreadyInList(InGate *inGate) const +//Idem OutGate::edRemoveInGateOneWay except that no exception thrown if CF not exists +void OutGate::edRemoveInGateOneWay(InGate *inGate) +{ + bool found=false; + for(set::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end() && !found;iter++) + if((*iter)==inGate) + { + _setOfInGate.erase(iter); + inGate->edRemovePrecursor(); + found=true; + } +} + +bool OutGate::isAlreadyInSet(InGate *inGate) const { bool ret=false; - for(list::const_iterator iter=_listOfInGate.begin();iter!=_listOfInGate.end() && !ret;iter++) + for(set::const_iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end() && !ret;iter++) if((*iter)==inGate) ret=true; return ret; @@ -63,5 +76,5 @@ bool OutGate::isAlreadyInList(InGate *inGate) const int OutGate::getNbOfInGatesConnected() const { - return _listOfInGate.size(); + return _setOfInGate.size(); } diff --git a/src/engine/OutGate.hxx b/src/engine/OutGate.hxx index 03fd339d0..05f430fd4 100644 --- a/src/engine/OutGate.hxx +++ b/src/engine/OutGate.hxx @@ -4,18 +4,20 @@ #include "Port.hxx" #include "Exception.hxx" -#include +#include namespace YACS { namespace ENGINE { class InGate; + class ElementaryNode; class OutGate : public Port { + friend class ElementaryNode; protected: - std::list _listOfInGate; + std::set _setOfInGate; public: static const char NAME[]; public: @@ -23,11 +25,12 @@ namespace YACS std::string getNameOfTypeOfCurrentInstance() const; void exNotifyDone(); bool edAddInGate(InGate *inGate); - std::list edListInGate() const; + std::set edSetInGate() const; void edRemoveInGate(InGate *inGate) throw(Exception); int getNbOfInGatesConnected() const; protected: - bool isAlreadyInList(InGate *inGate) const; + void edRemoveInGateOneWay(InGate *inGate); + bool isAlreadyInSet(InGate *inGate) const; }; } } diff --git a/src/engine/OutputDataStreamPort.cxx b/src/engine/OutputDataStreamPort.cxx index 2facea4b8..9f4f59614 100644 --- a/src/engine/OutputDataStreamPort.cxx +++ b/src/engine/OutputDataStreamPort.cxx @@ -1,37 +1,46 @@ #include "OutputDataStreamPort.hxx" #include "InputDataStreamPort.hxx" -#include "TypeCheckerDataStream.hxx" +//#include "TypeCheckerDataStream.hxx" using namespace YACS::ENGINE; +using namespace std; const char OutputDataStreamPort::NAME[]="OutputDataStreamPort"; -OutputDataStreamPort::OutputDataStreamPort(const std::string& name, Node *node, StreamType type):DataStreamPort(name,node,type),OutPort(node),Port(node) +OutputDataStreamPort::OutputDataStreamPort(const string& name, Node *node, TypeCode* type):DataStreamPort(name,node,type),OutPort(node),Port(node) { } -std::string OutputDataStreamPort::getNameOfTypeOfCurrentInstance() const +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)) +// if(!TypeCheckerDataStream::areStaticallyCompatible(edGetType(),port->edGetType())) +// throw ConversionException(TypeCheckerDataStream::edGetTypeInPrintableForm(edGetType()),TypeCheckerDataStream::edGetTypeInPrintableForm(port-> throw ConversionException(TypeCheckerDataStream::edGetTypeInPrintableForm(edGetType()),TypeCheckerDataStream::edGetTypeInPrintableForm(port->edGetType())); + if(!isAlreadyInSet(port)) { - _listOfInputDataStreamPort.push_back(port); + _setOfInputDataStreamPort.insert(port); return true; } else return false; } -void OutputDataStreamPort::edRemoveInputDataStreamPort(InputDataStreamPort *inputPort) +void OutputDataStreamPort::edRemoveInputDataStreamPort(InputDataStreamPort *inputPort) throw(Exception) { - if(isAlreadyInList(inputPort)) - _listOfInputDataStreamPort.remove(inputPort); + if(isAlreadyInSet(inputPort)) + _setOfInputDataStreamPort.erase(inputPort); +// else +// throw Exception("OutputDataStreamPort::edRemoveInputDataStreamPort : link does not exist, unable to remove it"); +} + +//Idem OutputDataStreamPort::edRemoveInputDataStreamPort but no exception thrown if inputPort is not known +void OutputDataStreamPort::edRemoveInputDataStreamPortOneWay(InputDataStreamPort *inputPort) +{ + _setOfInputDataStreamPort.erase(inputPort); } bool OutputDataStreamPort::addInPort(InPort *inPort) throw(Exception) @@ -44,13 +53,13 @@ void OutputDataStreamPort::removeInPort(InPort *inPort) throw(Exception) bool OutputDataStreamPort::isLinked() { - return _listOfInputDataStreamPort.empty(); + return _setOfInputDataStreamPort.empty(); } -bool OutputDataStreamPort::isAlreadyInList(InputDataStreamPort *inputPort) const +bool OutputDataStreamPort::isAlreadyInSet(InputDataStreamPort *inputPort) const { bool ret=false; - for(std::list::const_iterator iter=_listOfInputDataStreamPort.begin();iter!=_listOfInputDataStreamPort.end();iter++) + for(set::const_iterator iter=_setOfInputDataStreamPort.begin();iter!=_setOfInputDataStreamPort.end();iter++) if((*iter)==inputPort) ret=true; return ret; diff --git a/src/engine/OutputDataStreamPort.hxx b/src/engine/OutputDataStreamPort.hxx index e4c8af69f..163f56793 100644 --- a/src/engine/OutputDataStreamPort.hxx +++ b/src/engine/OutputDataStreamPort.hxx @@ -5,30 +5,34 @@ #include "DataStreamPort.hxx" #include "ConversionException.hxx" -#include +#include namespace YACS { namespace ENGINE { + class ElementaryNode; class InputDataStreamPort; class OutputDataStreamPort : public DataStreamPort, public OutPort { + friend class ElementaryNode; protected: - std::list _listOfInputDataStreamPort; + std::set _setOfInputDataStreamPort; public: static const char NAME[]; public: - OutputDataStreamPort(const std::string& name, Node *node, StreamType type); + OutputDataStreamPort(const std::string& name, Node *node, TypeCode* type); std::string getNameOfTypeOfCurrentInstance() const; bool edAddInputDataStreamPort(InputDataStreamPort *port) throw(ConversionException); - void edRemoveInputDataStreamPort(InputDataStreamPort *inputPort); + void edRemoveInputDataStreamPort(InputDataStreamPort *inputPort) throw(Exception); bool addInPort(InPort *inPort) throw(Exception); void removeInPort(InPort *inPort) throw(Exception); bool isLinked(); + protected: + void edRemoveInputDataStreamPortOneWay(InputDataStreamPort *inputPort); private: - bool isAlreadyInList(InputDataStreamPort *inputPort) const; + bool isAlreadyInSet(InputDataStreamPort *inputPort) const; }; } } diff --git a/src/engine/OutputPort.cxx b/src/engine/OutputPort.cxx index c17dfc1f1..36db4f2cc 100644 --- a/src/engine/OutputPort.cxx +++ b/src/engine/OutputPort.cxx @@ -1,82 +1,110 @@ #include "OutputPort.hxx" #include "InputPort.hxx" +#include "Runtime.hxx" + +#include +#include 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) +OutputPort::OutputPort(const string& name, Node *node, TypeCode* type):DataFlowPort(name,node,type),OutPort(node),Port(node) { } -std::string OutputPort::getNameOfTypeOfCurrentInstance() const +string OutputPort::getNameOfTypeOfCurrentInstance() const { return NAME; } -Data OutputPort::foGet() const -{ - return _data; -} - void OutputPort::exInit() { - _data.exInit(); +// _data.exInit(); } -void OutputPort::exPut(Data data) throw(ConversionException) + +void OutputPort::put(const void *data) throw(ConversionException) { - _data=data; - for(list::iterator iter=_listOfInputPort.begin();iter!=_listOfInputPort.end();iter++) - (*iter)->exAccept(data); -} +// _data = (void *)data; + cerr << _name << endl; + cerr << _impl << endl; + stringstream msg; + msg << "Not implemented (" << __FILE__ << ":" << __LINE__ << ")"; + throw Exception(msg.str()); + } + + +/** + * check if output type is an input type and if a data converter exists before link + */ 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)) + InputPort *pwrap = getRuntime()->adapt(inputPort->getImpl(), + inputPort, + this->getImpl(), + this->type()); + + if(!isAlreadyInSet(pwrap)) { - _listOfInputPort.push_back(inputPort); + _setOfInputPort.insert(pwrap); inputPort->edNotifyReferenced(); return true; } else - return false; + { + if ( dynamic_cast (pwrap) ) + { + cerr << "ProxyPort destruction, while creating the same link twice..." << endl; + delete pwrap; + } + return false; + } } -list OutputPort::edListInputPort() +set OutputPort::edSetInputPort() { - return _listOfInputPort; + return _setOfInputPort; } void OutputPort::edRemoveInputPort(InputPort *inputPort) throw(Exception) { - if(isAlreadyInList(inputPort)) - _listOfInputPort.remove(inputPort); + if(isAlreadyInSet(inputPort)) + _setOfInputPort.erase(inputPort); else throw Exception("OutputPort::edRemoveInputPort : link does not exist, unable to remove it"); } +//Idem OutputPort::edRemoveInputPort but without any check. +void OutputPort::edRemoveInputPortOneWay(InputPort *inputPort) +{ + _setOfInputPort.erase(inputPort); +} + OutputPort::~OutputPort() { } -bool OutputPort::isAlreadyInList(InputPort *inputPort) const +bool OutputPort::isAlreadyInSet(InputPort *inputPort) const { bool ret=false; - for(list::const_iterator iter=_listOfInputPort.begin();iter!=_listOfInputPort.end() && !ret;iter++) + for(set::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end() && !ret;iter++) if((*iter)==inputPort) ret=true; return ret; } +/** + * check compatibility of port class ( an inputPort) before trying to create the link + */ + 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 "; + string what="not compatible type of port requested during building of link FROM "; what+=NAME; what+=" TO "; what+=inPort->getNameOfTypeOfCurrentInstance(); throw Exception(what); } @@ -87,7 +115,7 @@ 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 "; + string what="not compatible type of port requested during destruction of for link FROM "; what+=NAME; what+=" TO "; what+=inPort->getNameOfTypeOfCurrentInstance(); throw Exception(what); } @@ -96,5 +124,5 @@ void OutputPort::removeInPort(InPort *inPort) throw(Exception) bool OutputPort::isLinked() { - return _listOfInputPort.empty(); + return _setOfInputPort.empty(); } diff --git a/src/engine/OutputPort.hxx b/src/engine/OutputPort.hxx index 7f6c3dfe2..1f878a985 100644 --- a/src/engine/OutputPort.hxx +++ b/src/engine/OutputPort.hxx @@ -1,38 +1,51 @@ #ifndef __OUTPUTPORT_HXX__ #define __OUTPUTPORT_HXX__ +//#include +//#include + +#include "TypeCode.hxx" #include "OutPort.hxx" #include "DataFlowPort.hxx" #include "ConversionException.hxx" -#include +#include namespace YACS { namespace ENGINE { class InputPort; + class ElementaryNode; + class Runtime; class OutputPort : public DataFlowPort, public OutPort { - protected: - std::list _listOfInputPort; - public: - static const char NAME[]; + friend class ElementaryNode; // for disconnect... + friend class Runtime; // for port creation 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); + std::set edSetInputPort(); + bool isLinked(); + bool isAlreadyInSet(InputPort *inputPort) const; + + virtual bool addInPort(InPort *inPort) throw(Exception); bool edAddInputPort(InputPort *inputPort) throw(ConversionException); - std::list edListInputPort(); + virtual void removeInPort(InPort *inPort) throw(Exception); 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; + + void exInit(); + + virtual void put(const void *data) throw(ConversionException); + + static const char NAME[]; + + protected: + OutputPort(const std::string& name, Node *node, TypeCode* type); + void edRemoveInputPortOneWay(InputPort *inputPort); + std::set _setOfInputPort; }; } } diff --git a/src/engine/Port.cxx b/src/engine/Port.cxx index 1fc59200e..9604bdb7f 100644 --- a/src/engine/Port.cxx +++ b/src/engine/Port.cxx @@ -1,18 +1,28 @@ #include "Port.hxx" using namespace YACS::ENGINE; +using namespace std; const char Port::NAME[]="Port"; -Port::Port(Node *node):_node(node) +int Port::total_ = 0; + +Port::Port(Node *node) + : _node(node) { + id_ = total_++; } Port::~Port() { } -std::string Port::getNameOfTypeOfCurrentInstance() const +string Port::getNameOfTypeOfCurrentInstance() const { return NAME; } + +// TypeCode * Port::type() +// { +// return _type; +// } diff --git a/src/engine/Port.hxx b/src/engine/Port.hxx index 69ce0bfd7..53ef31a19 100644 --- a/src/engine/Port.hxx +++ b/src/engine/Port.hxx @@ -1,38 +1,44 @@ #ifndef __PORT_HXX__ #define __PORT_HXX__ +#include "TypeCode.hxx" #include -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. - * + * Not instanciable class that factorizes all basic data and behaviours relative + * to the in and out interfaces of all nodes. + * End-user should neither instanciate a sub-class of 'Port' + * nore call other methods than accessor. */ + namespace YACS { namespace ENGINE { + class Node; + class Port { - protected: - Node *_node;//NOT OWNERED - public: - static const char NAME[]; - protected: - Port(Node *node); public: virtual ~Port(); + Node *getNode() const { return _node; } + std::string getImpl() const {return _impl; } + virtual std::string getNameOfTypeOfCurrentInstance() const; + // virtual TypeCode * type(); + + static const char NAME[]; + + protected: + Port(Node *node); + + Node *_node; + std::string _impl; + TypeCode *_type; + int id_; + static int total_; }; } } diff --git a/src/engine/Runtime.cxx b/src/engine/Runtime.cxx new file mode 100644 index 000000000..a9c423a04 --- /dev/null +++ b/src/engine/Runtime.cxx @@ -0,0 +1,53 @@ +#include "Runtime.hxx" + +#include + +using namespace YACS::ENGINE; +using namespace std; + + +Runtime* Runtime::_singleton = 0; + +void Runtime::setRuntime() // singleton creation (not thread safe!) +{ + if (! Runtime::_singleton) Runtime::_singleton = new Runtime(); +} + +// singleton creation must be done before by a derived class + +Runtime* YACS::ENGINE::getRuntime() throw(Exception) +{ + if ( ! Runtime::_singleton ) + throw Exception("Runtime is not yet initialized"); + return Runtime::_singleton; +} + +ElementaryNode* Runtime::createNode(string implementation, + string name) throw(Exception) +{ + return new TestElemNode(name); +} + +InputPort* Runtime::createInputPort(const string& name, + const string& impl, + Node * node, + TypeCode * type) +{ + return new InputPort(name, node, type); +} + +OutputPort* Runtime::createOutputPort(const string& name, + const string& impl, + Node * node, + TypeCode * type) +{ + return new OutputPort(name, node, type); +} + +InputPort* Runtime::adapt(const string& imp_source, + InputPort* source, + const string& impl,TypeCode * type) + throw (ConversionException) +{ + return source; +} diff --git a/src/engine/Runtime.hxx b/src/engine/Runtime.hxx new file mode 100644 index 000000000..9aa146757 --- /dev/null +++ b/src/engine/Runtime.hxx @@ -0,0 +1,70 @@ + +#ifndef _RUNTIME_HXX_ +#define _RUNTIME_HXX_ + +#include "TypeCode.hxx" +#include "ElementaryNode.hxx" +#include "OutputPort.hxx" +#include "InputPort.hxx" + +#include +#include +//#include +#include + + + +namespace YACS +{ + namespace ENGINE + { + class Runtime; + + Runtime* getRuntime() throw(Exception); + //! For unit testing purpose + + class TestElemNode: public ElementaryNode + { + public: + TestElemNode(const std::string& s): ElementaryNode(s) {}; + void execute() {}; + }; + + + + class Runtime + { + public: + static void setRuntime(); // singleton creation + + friend Runtime* getRuntime() throw(Exception); // singleton creation + + virtual void init(){}; + virtual void fini(){}; + + virtual ElementaryNode* createNode(std::string implementation, + std::string name) throw(Exception); + + virtual InputPort* createInputPort(const std::string& name, + const std::string& impl, + Node * node, + TypeCode * type); + + virtual OutputPort* createOutputPort(const std::string& name, + const std::string& impl, + Node * node, + TypeCode * type); + + virtual InputPort* adapt(const std::string& imp_source, + InputPort* source, + const std::string& impl,TypeCode * type) + throw (ConversionException); + + protected: + static Runtime* _singleton; + Runtime() {}; + std::set _setOfImplementation; + }; + } +} +#endif diff --git a/src/engine/Switch.cxx b/src/engine/Switch.cxx index 93779d626..4d4ad76f7 100644 --- a/src/engine/Switch.cxx +++ b/src/engine/Switch.cxx @@ -1,8 +1,9 @@ #include "Switch.hxx" using namespace YACS::ENGINE; +using namespace std; -Switch::Switch(const std::string& name):ComposedNode(name) +Switch::Switch(const string& name):ComposedNode(name) { } diff --git a/src/engine/Test/Makefile.am b/src/engine/Test/Makefile.am index c79eed9b4..7877fbddd 100644 --- a/src/engine/Test/Makefile.am +++ b/src/engine/Test/Makefile.am @@ -1,36 +1,26 @@ include $(top_srcdir)/adm/unix/make_begin.am -check_PROGRAMS = testPorts testBloc +check_PROGRAMS = TestEngine -testPorts_SOURCES = testPorts.cxx ToyNode.cxx +TestEngine_SOURCES = \ + TestEngine.cxx \ + engineTest.cxx -testPorts_LDADD = ../libYACSEngine.la \ - ../../bases/libYACSBases.la \ - ../../basicData/libYACSBasicData.la +TestEngine_LDADD = \ + ../libYACSEngine.la \ + ../../bases/libYACSBases.la -testPorts_LDFLAGS = $(CPPUNIT_LIBS) -pthread -ldl +TestEngine_LDFLAGS = $(CPPUNIT_LIBS) -pthread -ldl -testPorts_CXXFLAGS = $(CPPUNIT_INCLUDES) \ - -I$(srcdir)/.. \ - -I$(srcdir)/../../bases \ - -I$(srcdir)/../../basicData +TestEngine_CXXFLAGS = \ + $(CPPUNIT_INCLUDES) \ + -I$(srcdir)/.. \ + -I$(srcdir)/../../bases \ + -I$(srcdir)/../../bases/Test -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 +TESTS = TestEngine include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/engine/Test/TestEngine.cxx b/src/engine/Test/TestEngine.cxx new file mode 100644 index 000000000..447f014c5 --- /dev/null +++ b/src/engine/Test/TestEngine.cxx @@ -0,0 +1,13 @@ + +#include "engineTest.hxx" + +using namespace YACS; +using namespace std; + +// --- Registers the fixture into the 'registry' + +CPPUNIT_TEST_SUITE_REGISTRATION( EngineTest ); + +// --- generic Main program from bases/Test + +#include "BasicMainTest.hxx" diff --git a/src/engine/Test/ToyNode.cxx b/src/engine/Test/ToyNode.cxx deleted file mode 100644 index e18210954..000000000 --- a/src/engine/Test/ToyNode.cxx +++ /dev/null @@ -1,72 +0,0 @@ -#include "ToyNode.hxx" -#include "InputPort.hxx" -#include "OutputPort.hxx" - -#include - -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::iterator iter; - double sum=0.; - for(iter=_listOfInputPort.begin();iter!=_listOfInputPort.end();iter++) - sum+=(*iter)->exGet().exGet(); - 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::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 deleted file mode 100644 index 173f802b3..000000000 --- a/src/engine/Test/ToyNode.hxx +++ /dev/null @@ -1,28 +0,0 @@ -#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/engineTest.cxx b/src/engine/Test/engineTest.cxx new file mode 100644 index 000000000..25a91deed --- /dev/null +++ b/src/engine/Test/engineTest.cxx @@ -0,0 +1,338 @@ + +// --- include from engine first, to avoid redifinition warning _POSIX_C_SOURCE + +#include "Bloc.hxx" +#include "ElementaryNode.hxx" +#include "Loop.hxx" +#include "Switch.hxx" +#include "Runtime.hxx" + +#include "engineTest.hxx" + +#include +#include +#include +#include +#include + +using namespace YACS::ENGINE; +using namespace YACS; +using namespace std; + +#define _DEVDEBUG_ +#ifdef _DEVDEBUG_ +#define MYDEBTRACE {std::cerr << __FILE__ << " [" << __LINE__ << "] : ";} +#define DEBTRACE(msg) {MYDEBTRACE; std::cerr< EngineTest::_nodeMap; +map EngineTest::_compoMap; + +// --- init typecodes + +TypeCode *EngineTest::_tc_bool = new TypeCode(Bool); +TypeCode *EngineTest::_tc_int = new TypeCode(Int); +TypeCode *EngineTest::_tc_double = new TypeCode(Double); + + +void EngineTest::setUp() +{ +} + +void EngineTest::tearDown() +{ +} + +void EngineTest::checkGetRuntime() +{ + CPPUNIT_ASSERT_THROW(Runtime *myrun = getRuntime(), YACS::Exception); + Runtime::setRuntime(); + Runtime *myrun1 = getRuntime(); + CPPUNIT_ASSERT(myrun1); + Runtime *myrun2 = getRuntime(); + CPPUNIT_ASSERT_EQUAL(myrun1, myrun2); + } + +void EngineTest::checkInGateOutGate() +{ + string nodeName = "Node1"; + ElementaryNode* node1 = new TestElemNode(nodeName); + _nodeMap[nodeName] = node1; + + nodeName = "Node2"; + ElementaryNode* node2 = new TestElemNode(nodeName); + _nodeMap[nodeName] = node2; + + DEBTRACE(" --- check InGate OK after node creation" ); + { + InGate *node1Ingate = node1->getInGate(); + CPPUNIT_ASSERT(node1Ingate); + string name=node1Ingate->getNameOfTypeOfCurrentInstance(); + string expected="InGate"; + CPPUNIT_ASSERT_EQUAL(name,expected); + } + + DEBTRACE(" --- check OutGate OK after node creation" ); + { + OutGate *node1Outgate = node1->getOutGate(); + CPPUNIT_ASSERT(node1Outgate); + string name=node1Outgate->getNameOfTypeOfCurrentInstance(); + string expected="OutGate"; + CPPUNIT_ASSERT_EQUAL(name,expected); + } +} + +void EngineTest::checkNodePortNumber() +{ + ElementaryNode* node1 = (ElementaryNode*) _nodeMap["Node1"]; + + DEBTRACE(" --- check number of ports = 0 after node creation" ); + CPPUNIT_ASSERT(node1->getNumberOfInputPorts() == 0); + CPPUNIT_ASSERT(node1->getNumberOfOutputPorts() == 0); + + InputPort *in1 = node1->edAddInputPort("ib1",_tc_bool); + InputPort *in2 = node1->edAddInputPort("ii1",_tc_int); + InputPort *in3 = node1->edAddInputPort("ii2",_tc_int); + InputPort *in4 = node1->edAddInputPort("id1",_tc_double); + + OutputPort *ou1 = node1->edAddOutputPort("ob1",_tc_bool); + OutputPort *ou2 = node1->edAddOutputPort("oi1",_tc_int); + OutputPort *ou3 = node1->edAddOutputPort("od1",_tc_double); + + DEBTRACE(" --- check number of ports after ports creation" ); +// DEBTRACE(" node1->getNumberOfInputPorts(): " +// << node1->getNumberOfInputPorts()); +// DEBTRACE(" node1->getNumberOfOutputPorts(): " +// << node1->getNumberOfOutputPorts()); + CPPUNIT_ASSERT(node1->getNumberOfInputPorts() == 4); + CPPUNIT_ASSERT(node1->getNumberOfOutputPorts() == 3); +} + +void EngineTest::checkPortTypeName() +{ + ElementaryNode* node1 = (ElementaryNode*) _nodeMap["Node1"]; + + DEBTRACE(" --- check InputPort name OK" ); + { + string name=node1->getInputPort("ib1")->NAME; + string expected="InputPort"; + CPPUNIT_ASSERT_EQUAL(name,expected); + } + + DEBTRACE(" --- check OutputPort name OK" ); + { + string name=node1->getOutputPort("ob1")->NAME; + string expected="OutputPort"; + CPPUNIT_ASSERT_EQUAL(name,expected); + } +} + +void EngineTest::checkDuplicatePortName() +{ + ElementaryNode* node1 = (ElementaryNode*) _nodeMap["Node1"]; + DEBTRACE(" --- check duplicated name throws exception" ); + CPPUNIT_ASSERT_THROW(InputPort *in5=node1->edAddInputPort("ii2",_tc_int), + YACS::Exception); +} + +void EngineTest::checkRemovePort() +{ + ElementaryNode* node1 = (ElementaryNode*) _nodeMap["Node1"]; + ElementaryNode* node2 = (ElementaryNode*) _nodeMap["Node2"]; + + DEBTRACE(" --- check remove port" ); + { + node1->edRemovePort(node1->getInputPort("ib1")); + CPPUNIT_ASSERT(node1->getNumberOfInputPorts() == 3); + CPPUNIT_ASSERT(node1->getNumberOfOutputPorts() == 3); + } + + DEBTRACE(" --- check remove wrong port throws exception" ) + { + CPPUNIT_ASSERT_THROW(node1->edRemovePort(node1->getInputPort("ib1")), + YACS::Exception); + } +} + +void EngineTest::checkAddNodesToBloc() +{ + DEBTRACE(" --- delete node; // ====== NOT OK : done by bloc" ); + + for (int i=0; i<10; i++) + { + ostringstream ss; + ss << "Node_" << i; + string s = ss.str(); + ElementaryNode* node = new TestElemNode(s); + _nodeMap[s] = node; + InputPort *i1 = node->edAddInputPort("ib1",_tc_bool); + InputPort *i2 = node->edAddInputPort("ii1",_tc_int); + InputPort *i3 = node->edAddInputPort("ii2",_tc_int); + InputPort *i4 = node->edAddInputPort("id1",_tc_double); + OutputPort *o1 = node->edAddOutputPort("ob1",_tc_bool); + OutputPort *o2 = node->edAddOutputPort("oi1",_tc_int); + OutputPort *o3 = node->edAddOutputPort("od1",_tc_double); + } + + DEBTRACE(" --- create bloc, add two nodes, check constituants" ); + + Bloc* bloc1 = new Bloc("bloc1"); + _nodeMap["bloc1"] = bloc1; + _compoMap["bloc1"] = bloc1; + bloc1->edAddChild(_nodeMap["Node_1"]); + bloc1->edAddChild(_nodeMap["Node_2"]); + { + set setelem = bloc1->getRecursiveConstituents(); + CPPUNIT_ASSERT(setelem.size() == 2); + } +} + +void EngineTest::checkAddingTwiceSameNodeInSameBloc() +{ + DEBTRACE(" --- add the same node two times does nothing: return false" ); + + CPPUNIT_ASSERT(! ((Bloc*)_compoMap["bloc1"])->edAddChild(_nodeMap["Node_1"])); +} + +void EngineTest::checkAddingTwiceSameNodeInTwoBlocs() +{ + DEBTRACE(" --- add a node already used elsewhere raises exception" ); + + Bloc* bloc2 = new Bloc("bloc2"); + _nodeMap["bloc2"] = bloc2; + _compoMap["bloc2"] = bloc2; + bloc2->edAddChild(_nodeMap["Node_3"]); + + CPPUNIT_ASSERT_THROW(bloc2->edAddChild(_nodeMap["Node_1"]), + YACS::Exception); +} + +void EngineTest::checkRecursiveBlocs_NumberOfNodes() +{ + Bloc *bloc1 = (Bloc*)_compoMap["bloc1"]; + Bloc *bloc2 = (Bloc*)_compoMap["bloc2"]; + + DEBTRACE(" --- recursive blocs, check constituants" ); + + Bloc* bloc3 = new Bloc("bloc3"); + _nodeMap["bloc3"] = bloc3; + _compoMap["bloc3"] = bloc3; + bloc3->edAddChild((bloc1)); // 2 elementary nodes + bloc3->edAddChild((bloc2)); // 1 elementary node + bloc3->edAddChild(_nodeMap["Node_4"]); // 1 elementary node + { + set setelem = bloc3->getRecursiveConstituents(); + CPPUNIT_ASSERT(setelem.size() == 4); + for (set::iterator it=setelem.begin(); it!=setelem.end(); it++) + { + DEBTRACE(" elem name = " << (*it)->getName()); + } + } +} + +void EngineTest::checkRecursiveBlocs_NumberOfPorts() +{ + Bloc *bloc3 = (Bloc*)_compoMap["bloc3"]; + + DEBTRACE(" --- recursive blocs, check input & output ports // COMPLETER" ); + CPPUNIT_ASSERT(bloc3->getNumberOfInputPorts() == 4*4); + DEBTRACE(" number of input ports: " << bloc3->getNumberOfInputPorts()); + DEBTRACE(" number of output ports: " << bloc3->getNumberOfOutputPorts()); + { + set inset = bloc3->getSetOfInputPort(); + set outset = bloc3->getSetOfOutputPort(); + for (set::iterator it=inset.begin(); it!=inset.end(); it++) + { + DEBTRACE(" input port name = " << bloc3->getInputPortName(*it)); + } + for (set::iterator it=outset.begin(); it!=outset.end(); it++) + { + DEBTRACE(" output port name = " << (*it)->getName()); + } + } +} + +void EngineTest::checkPortNameInBloc() +{ + + DEBTRACE(" --- recursive blocs, check port names" ); + + InputPort *inport = _nodeMap["Node_1"]->getInputPort("id1"); + CPPUNIT_ASSERT(_nodeMap["bloc3"]->getInputPortName(inport) == "bloc1.Node_1.id1"); +} + +void EngineTest::checkGetNameOfPortNotInBloc() +{ + InputPort *inport = _nodeMap["Node_5"]->getInputPort("id1"); + CPPUNIT_ASSERT_THROW(string name = _nodeMap["bloc3"]->getInputPortName(inport), + YACS::Exception); +} + +void EngineTest::RecursiveBlocs_multipleRecursion() +{ + { + Bloc* bloc = new Bloc("bloc4"); + _nodeMap["bloc4"] = bloc; + _compoMap["bloc4"] = bloc; + bloc->edAddChild(_nodeMap["Node_5"]); + bloc->edAddChild(_nodeMap["Node_6"]); + } + + { + Bloc* bloc = new Bloc("bloc5"); + _nodeMap["bloc5"] = bloc; + _compoMap["bloc5"] = bloc; + bloc->edAddChild(_nodeMap["Node_7"]); + bloc->edAddChild(_nodeMap["Node_8"]); + } + + { + Bloc* bloc = new Bloc("bloc6"); + _nodeMap["bloc6"] = bloc; + _compoMap["bloc6"] = bloc; + bloc->edAddChild(_nodeMap["bloc4"]); + bloc->edAddChild(_nodeMap["bloc5"]); + } + + { + Bloc* bloc = new Bloc("bloc7"); + _nodeMap["bloc7"] = bloc; + _compoMap["bloc7"] = bloc; + bloc->edAddChild(_nodeMap["bloc3"]); + bloc->edAddChild(_nodeMap["bloc6"]); + } + + { + Bloc* bloc = new Bloc("graphe"); + _nodeMap["graphe"] = bloc; + _compoMap["graphe"] = bloc; + bloc->edAddChild(_nodeMap["bloc7"]); + bloc->edAddChild(_nodeMap["Node_9"]); + } + + { + set setelem = _nodeMap["graphe"]->getRecursiveConstituents(); + CPPUNIT_ASSERT(setelem.size() == 9); + for (set::iterator it=setelem.begin(); it!=setelem.end(); it++) + { + DEBTRACE(" elem name = " << (*it)->getName()); + } + } + + { + set inset = _nodeMap["bloc7"]->getSetOfInputPort(); + set outset = _nodeMap["bloc7"]->getSetOfOutputPort(); + for (set::iterator it=inset.begin(); it!=inset.end(); it++) + { + DEBTRACE(" input port name for bloc7 = " << _nodeMap["bloc7"]->getInputPortName(*it)); + DEBTRACE(" input port name for graphe = " << _nodeMap["graphe"]->getInputPortName(*it)); + } + for (set::iterator it=outset.begin(); it!=outset.end(); it++) + { + DEBTRACE(" output port name = " << (*it)->getName()); + } + } +} diff --git a/src/engine/Test/engineTest.hxx b/src/engine/Test/engineTest.hxx new file mode 100644 index 000000000..667b85397 --- /dev/null +++ b/src/engine/Test/engineTest.hxx @@ -0,0 +1,66 @@ + +#ifndef _ENGINETEST_HXX_ +#define _ENGINETEST_HXX_ + +#include "ComposedNode.hxx" +#include "TypeCode.hxx" + +#include +#include +#include + +namespace YACS +{ + class EngineTest: public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( EngineTest ); + CPPUNIT_TEST(checkGetRuntime ); + CPPUNIT_TEST(checkInGateOutGate ); + CPPUNIT_TEST(checkNodePortNumber ); + CPPUNIT_TEST(checkPortTypeName ); + CPPUNIT_TEST(checkDuplicatePortName ); + CPPUNIT_TEST(checkRemovePort ); + CPPUNIT_TEST(checkAddNodesToBloc ); + CPPUNIT_TEST(checkAddingTwiceSameNodeInSameBloc ); + CPPUNIT_TEST(checkAddingTwiceSameNodeInTwoBlocs ); + CPPUNIT_TEST(checkRecursiveBlocs_NumberOfNodes ); + CPPUNIT_TEST(checkRecursiveBlocs_NumberOfPorts ); + CPPUNIT_TEST(checkPortNameInBloc ); + CPPUNIT_TEST(checkGetNameOfPortNotInBloc ); + CPPUNIT_TEST(RecursiveBlocs_multipleRecursion ); + CPPUNIT_TEST_SUITE_END(); + + public: + + void setUp(); + void tearDown(); + + void checkGetRuntime(); + void checkInGateOutGate(); + void checkNodePortNumber(); + void checkPortTypeName(); + void checkDuplicatePortName(); + void checkRemovePort(); + void checkAddNodesToBloc(); + void checkAddingTwiceSameNodeInSameBloc(); + void checkAddingTwiceSameNodeInTwoBlocs(); + void checkRecursiveBlocs_NumberOfNodes(); + void checkRecursiveBlocs_NumberOfPorts(); + void checkPortNameInBloc(); + void checkGetNameOfPortNotInBloc(); + void RecursiveBlocs_multipleRecursion(); + + protected: + static std::map _nodeMap; + static std::map _compoMap; + + static YACS::ENGINE::TypeCode *_tc_bool; + static YACS::ENGINE::TypeCode *_tc_int; + static YACS::ENGINE::TypeCode *_tc_double; + private: + + }; + +} + +#endif diff --git a/src/engine/Test/testBloc.cxx b/src/engine/Test/testBloc.cxx deleted file mode 100644 index eabd4ce49..000000000 --- a/src/engine/Test/testBloc.cxx +++ /dev/null @@ -1,153 +0,0 @@ -#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 -#include -#include -#include -// - -#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(),8.45,DBL_PRECISION_COMPARE ); - OutputPort *o2=n1->edAddOutputPort("c"); - exe.RunW(graph); - CPPUNIT_ASSERT_DOUBLES_EQUAL( o1->foGet().exGet(),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(),10.45,DBL_PRECISION_COMPARE ); - n2->setTime(0); n3->setTime(0); - exe.RunW(graph); - CPPUNIT_ASSERT_DOUBLES_EQUAL( o4_i->foGet().exGet(),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(),7.3,DBL_PRECISION_COMPARE ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( o4_a->foGet().exGet(),3.8,DBL_PRECISION_COMPARE ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( o8_a->foGet().exGet(),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 deleted file mode 100644 index 11f90800f..000000000 --- a/src/engine/Test/testPorts.cxx +++ /dev/null @@ -1,103 +0,0 @@ -#include "Node.hxx" -#include "Data.hxx" -#include "InGate.hxx" -#include "OutGate.hxx" -#include "InputPort.hxx" -#include "OutputPort.hxx" -// -#include -#include -#include -// - -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; -} diff --git a/src/engine/TypeCode.cxx b/src/engine/TypeCode.cxx new file mode 100644 index 000000000..93e0f31b2 --- /dev/null +++ b/src/engine/TypeCode.cxx @@ -0,0 +1,181 @@ + +#include "TypeCode.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +// --- TypeCode + +TypeCode::TypeCode(DynType kind) +{ + _kind=kind; +} + +TypeCode::~TypeCode() +{ +} + +DynType TypeCode::kind() const +{ + return _kind; +} + +const char * TypeCode::name() const throw(Exception) +{ + throw Exception("No name"); +} + + +const char * TypeCode::id() const throw(Exception) +{ + switch(_kind) + { + case Double: + return "Double"; + case Int: + return "Int"; + case String: + return "String"; + default: + return ""; + } +} + +int TypeCode::is_a(const char* id) +{ + throw Exception("Not implemented for this type"); +} + +int TypeCode::is_a(TypeCode* tc) +{ + if(_kind == tc->kind()) return 1; + return 0; +} + +TypeCode * TypeCode::content_type() const throw(Exception) +{ + throw Exception("No content type"); +}; + +/** + * static factory of object reference types + */ + +TypeCode * TypeCode::interface_tc(const char* id, + const char* name) +{ + return new TypeCode_objref(id, name); +}; + +TypeCode * TypeCode::interface_tc(const char* id, + const char* name, + list ltc) +{ + return new TypeCode_objref(id, name,ltc); +} + + +/** + * static factory of sequence types + */ + +TypeCode * TypeCode::sequence_tc(const char* id, + const char* name, + TypeCode *content) +{ + return new TypeCode_seq(id, name,content); +}; + + +// --- TypeCode_objref + + +TypeCode_objref::TypeCode_objref(const char* repositoryId, + const char* name) + : TypeCode(Objref) +{ + _repoId = repositoryId; + _name = name; +} + + +TypeCode_objref::~TypeCode_objref() +{ +} + +const char * TypeCode_objref::id() const throw(Exception) +{ + return _repoId.c_str(); +}; + +const char * TypeCode_objref::name() const throw(Exception) +{ + return _name.c_str(); +} + +TypeCode_objref::TypeCode_objref(const char* repositoryId, + const char* name, + list ltc) + : TypeCode(Objref) +{ + _repoId = repositoryId; + _name = name; + _listOfBases=ltc; +} + +int TypeCode_objref::is_a(const char* id) throw(Exception) +{ + if(_repoId.c_str() == id)return 1; + list::iterator iter; + for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++) + { + if ((*iter)->is_a(id)) return 1; + } + return 0; +} + +int TypeCode_objref::is_a(TypeCode* tc) throw(Exception) +{ + return is_a(tc->id()); +} + +// --- TypeCode_seq + + +TypeCode_seq::TypeCode_seq(const char* repositoryId, + const char* name, + TypeCode *content) + : TypeCode(Sequence) +{ + _repoId = repositoryId; + _name = name; + _content= content; +} + +TypeCode_seq::~TypeCode_seq() +{ +} + +const char * TypeCode_seq::id() const throw(Exception) +{ + return _repoId.c_str(); +} + +const char * TypeCode_seq::name() const throw(Exception) +{ + return _name.c_str(); +} + +TypeCode * TypeCode_seq::content_type() const throw(Exception) +{ + return _content; +} + +int TypeCode_seq::is_a(TypeCode* tc) +{ + if(_kind == tc->kind()) + { + if(_content->is_a(tc->content_type())) return 1; + } + return 0; +} diff --git a/src/engine/TypeCode.hxx b/src/engine/TypeCode.hxx new file mode 100644 index 000000000..430320c8d --- /dev/null +++ b/src/engine/TypeCode.hxx @@ -0,0 +1,102 @@ +#ifndef __TYPECODE_HXX__ +#define __TYPECODE_HXX__ + +//#include // here, to avoid warning: "_POSIX_C_SOURCE" redefined + +#include "Exception.hxx" + +#include +#include + +namespace YACS +{ + namespace ENGINE + { + + typedef enum + { + None = 0, + Double = 1, + Int = 2, + String = 3, + Bool = 4, + Objref = 5, + Sequence = 6 + } DynType; + +// typedef enum DynType StreamType; + + class TypeCode_objref; + + class TypeCode + { + public: + TypeCode(DynType kind); + virtual ~TypeCode(); + + DynType kind() const; + + virtual const char * name() const throw(Exception); + virtual const char * id() const throw(Exception); + virtual TypeCode * content_type() const throw(Exception); + virtual int is_a(const char* repositoryId); + virtual int is_a(TypeCode* tc); + + static TypeCode * interface_tc(const char* id, const char* name); + static TypeCode * interface_tc(const char* id, const char* name, std::list ltc); + static TypeCode * sequence_tc (const char* id, const char* name, TypeCode *content); + + protected: + // --- These operators are placed here to avoid them being used externally + TypeCode(const TypeCode& tc); + TypeCode& operator=(const TypeCode& tc); + TypeCode() {} + + DynType _kind; + }; + + + class TypeCode_objref: public TypeCode + { + public: + TypeCode_objref(const char* repositoryId, const char* name); + + TypeCode_objref(const char* repositoryId, const char* name, std::list ltc); + virtual ~TypeCode_objref(); + + const char * id() const throw(Exception); + const char * name() const throw(Exception); + int is_a(const char* repositoryId) throw(Exception); + virtual int is_a(TypeCode* tc) throw(Exception); + + private: + TypeCode_objref() {} + + std::string _name; + std::string _repoId; + std::list _listOfBases; + }; + + + class TypeCode_seq: public TypeCode + { + public: + TypeCode_seq(const char* repositoryId, const char* name, TypeCode *content); + virtual ~TypeCode_seq(); + + const char * id() const throw(Exception); + const char * name() const throw(Exception); + + virtual TypeCode * content_type() const throw(Exception); + virtual int is_a(TypeCode* tc); + + private: + TypeCode_seq() {} + + std::string _name; + std::string _repoId; + TypeCode * _content; + }; + } +} +#endif diff --git a/src/runtime/CORBACORBAConv.cxx b/src/runtime/CORBACORBAConv.cxx new file mode 100644 index 000000000..c8440ef3c --- /dev/null +++ b/src/runtime/CORBACORBAConv.cxx @@ -0,0 +1,29 @@ + +#include "CORBACORBAConv.hxx" +#include "TypeConversions.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +CorbaCorba::CorbaCorba(InputCorbaPort* p) + : ProxyPort(p), Port(p->getNode()) +{ +} + +//!Convertit un Any convertible en CORBA::Any +/*! + * \param data : CORBA::Any object + */ + +void CorbaCorba::put(const void *data) throw(ConversionException) +{ + put((CORBA::Any *)data); +} + +void CorbaCorba::put(CORBA::Any *data) throw(ConversionException) +{ + //conversion du Any data en any attendu (de type type()) + + CORBA::Any *a = convertCorbaCorba(type(),data); + _port->put(a); +} diff --git a/src/runtime/CORBACORBAConv.hxx b/src/runtime/CORBACORBAConv.hxx new file mode 100644 index 000000000..f9b47bd16 --- /dev/null +++ b/src/runtime/CORBACORBAConv.hxx @@ -0,0 +1,23 @@ +#ifndef __CORBACORBACONV_HXX__ +#define __CORBACORBACONV_HXX__ + +#include "RuntimeSALOME.hxx" + +namespace YACS +{ + namespace ENGINE + { + + // Ports adaptateurs Corba->Corba pour les différents types + + class CorbaCorba : public ProxyPort + { + public: + CorbaCorba(InputCorbaPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(CORBA::Any *data) throw(ConversionException); + }; + + } +} +#endif diff --git a/src/runtime/CORBANode.cxx b/src/runtime/CORBANode.cxx new file mode 100644 index 000000000..49469e470 --- /dev/null +++ b/src/runtime/CORBANode.cxx @@ -0,0 +1,158 @@ + +#include "CORBANode.hxx" +#include "RuntimeSALOME.hxx" + +#include +#include + +using namespace YACS::ENGINE; +using namespace std; + +CORBANode::CORBANode(const std::string& name): ElementaryNode(name) +{ + _implementation = "CORBA"; + cerr << "CORBANode::CORBANode " << name << endl; +} + +void CORBANode::set_ref(const string& ref) +{ + _ref = ref; +} + +void CORBANode::set_method(const string& method) +{ + _method = method; +} + +void CORBANode::execute() +{ + cerr << "+++++++++++++++++CorbaNode::run+++++++++++++++++" << endl; + //recupération de l'objet CORBA dont l'IOR est _ref + int argc=0; + CORBA::ORB_var orb = CORBA::ORB_init(argc,0); + //CORBA::Object_var obj = getObjectReference(orb); + CORBA::Object_var obj = orb->string_to_object(_ref.c_str()); + if( CORBA::is_nil(obj) ) + { + cerr << "Can't get reference to object (or it was nil)." << endl; + return ; + } + { + //construction de la requete DII : ATTENTION aux restrictions et approximations + // on suppose qu'un service recoit tous ses parametres in en premier + // puis tous ses parametres out + // pas de parametre inout + // pas de valeur de retour + // pas encore d'exception utilisateur + // seulement des exceptions CORBA + // + CORBA::Request_var req = obj->_request(_method.c_str()); + CORBA::NVList_ptr arguments = req->arguments() ; + + cerr << "+++++++++++++++++CorbaNode::inputs+++++++++++++++++" << endl; + int in_param=0; + //les parametres in + set::iterator iter2; + for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++) + { + InputCorbaPort *p=(InputCorbaPort *)*iter2; + cerr << "port name: " << p->getName() << endl; + cerr << "port kind: " << p->type()->kind() << endl; + CORBA::Any* ob=p->getAny(); + CORBA::TypeCode_var typcod= ob->type(); + switch(p->type()->kind()) + { + case Double: + CORBA::Double d; + *ob >>= d; + cerr << d << endl; + break; + case Int: + CORBA::Long l; + *ob >>= l; + cerr << l << endl; + break; + case String: + char *s; + *ob >>= s; + cerr << s << endl; + break; + case Objref: + cerr << typcod->id() << endl; + break; + default: + break; + } + //add_value fait une copie du any. La copie sera détruite avec la requete + arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_IN ) ; + in_param=in_param+1; + } + + //les parametres out + cerr << "+++++++++++++++++CorbaNode::outputs+++++++++++++++++" << endl; + set::iterator iter; + for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++) + { + OutputCorbaPort *p=(OutputCorbaPort *)*iter; + cerr << "port name: " << p->getName() << endl; + cerr << "port kind: " << p->type()->kind() << endl; + CORBA::Any* ob=p->getAnyOut(); + //add_value fait une copie du any. La copie sera détruite avec la requete + arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_OUT ); + } + + //valeur de retour + req->set_return_type(CORBA::_tc_void); + //autres exceptions + //req->exceptions()->add(eo::_tc_SALOME_Exception); + + cerr << "+++++++++++++++++CorbaNode::calculation+++++++++++++++++" << _method << endl; + req->invoke(); + CORBA::Exception *exc =req->env()->exception(); + if( exc ) + { + cerr << "An exception was thrown!" << endl; + cerr << "The raised exception is of Type:" << exc->_name() << endl; + return ; + } + + cerr << "++++++++++++CorbaNode::outputs++++++++++++" << endl; + int out_param=in_param; + for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++) + { + OutputCorbaPort *p=(OutputCorbaPort *)*iter; + cerr << "port name: " << p->getName() << endl; + cerr << "port kind: " << p->type()->kind() << endl; + cerr << "port number: " << out_param << endl; + CORBA::Any *ob=arguments->item(out_param)->value(); + switch(p->type()->kind()) + { + case Double: + CORBA::Double d; + *ob >>= d; + cerr << d << endl; + break; + case Int: + CORBA::Long l; + *ob >>= l; + cerr << l << endl; + break; + case String: + char *s; + *ob >>= s; + cerr << s << endl; + break; + default: + break; + } + //L'OutputPort doit copier l'Any car il sera détruit avec la requete + //La copie est faite dans la methode put. + p->put(ob); + out_param=out_param+1; + } + + cerr << "++++++++++++++++++++++++++++++++++++++++++" << endl; + } + //La requete n'existe plus ici (_var oblige) + //Tous les any passés a la requete sont détruits : il faut les copier +} diff --git a/src/runtime/CORBANode.hxx b/src/runtime/CORBANode.hxx new file mode 100644 index 000000000..9d9253064 --- /dev/null +++ b/src/runtime/CORBANode.hxx @@ -0,0 +1,28 @@ + +#ifndef _CORBANODE_HXX_ +#define _CORBANODE_HXX_ + +#include "ElementaryNode.hxx" + +namespace YACS +{ + namespace ENGINE + { + + class CORBANode: public ENGINE::ElementaryNode + { + public: + CORBANode(const std::string& name); + virtual void execute(); + virtual void set_ref(const std::string& ref); + virtual void set_method(const std::string& method); + protected: + std::string _ref; + std::string _method; + + protected: + }; + } +} + +#endif diff --git a/src/runtime/CORBAPorts.cxx b/src/runtime/CORBAPorts.cxx new file mode 100644 index 000000000..1610e536d --- /dev/null +++ b/src/runtime/CORBAPorts.cxx @@ -0,0 +1,167 @@ + +#include "CORBAPorts.hxx" +#include "RuntimeSALOME.hxx" +#include "TypeConversions.hxx" + +#include +#include + + +using namespace YACS::ENGINE; +using namespace std; + + +InputCorbaPort::InputCorbaPort(const string& name, + Node *node, + TypeCode * type) + : InputPort(name, node, type), Port(node) +{ + _impl="CORBA"; + _orb = getSALOMERuntime()->getOrb(); +} + +void InputCorbaPort::put(const void *data) throw (ConversionException) +{ + put((CORBA::Any *)data); + _empty = false; +} + +void InputCorbaPort::put(CORBA::Any *data) throw (ConversionException) +{ + cerr << "InputCorbaPort::put" << endl; + // cerr << "addr data: " << data << endl; + // cerr << "addr data.value(): " << data->value() << endl; + switch(type()->kind()) + { + case Double: + CORBA::Double d; + *data >>= d; + cerr << "Double: " << d << endl; + break; + case Int: + CORBA::Long l; + *data >>= l; + cerr << "Int: " << l << endl; + break; + case Sequence: + break; + default: + break; + } + // on fait une copie du any (protection contre la destruction du any source) + // la gestion des destructions est correctement faite par omniorb + _data=*data; + // cerr << "addr _data: " << &_data << endl; + // cerr << "addr _data.value(): " << _data.value() << endl; +} + +CORBA::Any * InputCorbaPort::getAny() +{ + // cerr << "_data: " << &_data << endl; + // cerr << "_data.value(): " << _data.value() << endl; + // cerr << "_data.NP_pd(): " << _data.NP_pd() << endl; + // --- on retourne un pointeur sur le any interne + return &_data; +} + + +OutputCorbaPort::OutputCorbaPort(const string& name, + Node *node, + TypeCode * type) + : OutputPort(name, node, type), Port(node) +{ + _impl="CORBA"; + _orb = getSALOMERuntime()->getOrb(); +} + +void OutputCorbaPort::put(const void *data) throw (ConversionException) +{ + put((CORBA::Any *)data); +} + +void OutputCorbaPort::put(CORBA::Any *data) throw (ConversionException) +{ + cerr << "OutputCorbaPort::put" << endl; + // cerr << "addr data: " << data << endl; + InputPort *p; + // on fait une copie du any source + // (protection contre la destruction de la source) + _data=*data; + set::iterator iter; + for(iter=_setOfInputPort.begin(); iter!=_setOfInputPort.end(); iter++) + { + p=*iter; + // on pousse le pointeur mais put fait normalement une copie + p->put(&_data); + } +} + +CORBA::Any * OutputCorbaPort::getAny() +{ + // cerr << "_data: " << &_data << endl; + // cerr << "_data.value(): " << _data.value() << endl; + // cerr << "_data.NP_pd(): " << _data.NP_pd() << endl; + // on retourne un pointeur sur le any interne + return &_data; +} + +CORBA::Any * OutputCorbaPort::getAnyOut() +{ + CORBA::Any* a=&_data; + DynType kind=type()->kind(); + + if(kind == Int) + { + a->replace(CORBA::_tc_long, (void*) 0); + } + else if(kind == String) + { + a->replace(CORBA::_tc_string, (void*) 0); + } + else if(kind == Double) + { + a->replace(CORBA::_tc_double, (void*) 0); + } + else if(kind == Objref) + { + a->replace(CORBA::_tc_Object, (void*) 0); + } + else if(kind == Sequence) + { + CORBA::TypeCode_var t; + t = getCorbaTC(type()); + a->replace(t, (void*) 0); + } + else if(kind == Bool) + { + stringstream msg; + msg << "Cannot set Any Out for Bool" << __FILE__ << ":" << __LINE__; + throw Exception(msg.str()); + } + else if(kind == None) + { + stringstream msg; + msg << "Cannot set Any Out for None" << __FILE__ << ":" << __LINE__; + throw Exception(msg.str()); + } + else + { + stringstream msg; + msg << "Cannot set Any Out for unknown type" << __FILE__ + << ":" << __LINE__; + throw Exception(msg.str()); + } + + // on retourne un pointeur sur le any interne reinitialisé + // cerr << "getAnyOut::_data: " << a << endl; + return a; +} + +ostream& YACS::ENGINE::operator<<(ostream& os, const OutputCorbaPort& p) +{ + CORBA::Double l; + p._data>>=l; + os << p._name << " : " << l ; + return os; +} + diff --git a/src/runtime/CORBAPorts.hxx b/src/runtime/CORBAPorts.hxx new file mode 100644 index 000000000..c1c0d057d --- /dev/null +++ b/src/runtime/CORBAPorts.hxx @@ -0,0 +1,45 @@ +#ifndef _CORBAPORTS_HXX_ +#define _CORBAPORTS_HXX_ + +#include + +#include "InputPort.hxx" +#include "OutputPort.hxx" + +namespace YACS +{ + namespace ENGINE + { + + class InputCorbaPort : public InputPort + { + public: + InputCorbaPort(const std::string& name, Node *node, TypeCode * type); + virtual void put(const void *data) throw(ConversionException); + void put(CORBA::Any *data) throw (ConversionException); + virtual CORBA::Any * getAny(); + protected: + CORBA::Any _data; + CORBA::ORB_ptr _orb; + }; + + class OutputCorbaPort : public OutputPort + { + public: + OutputCorbaPort(const std::string& name, Node *node, TypeCode * type); + virtual void put(const void *data) throw(ConversionException); + void put(CORBA::Any *data) throw (ConversionException); + virtual CORBA::Any * getAny(); + virtual CORBA::Any * getAnyOut(); + friend std::ostream & operator<< ( std::ostream &os, + const OutputCorbaPort& p); + protected: + CORBA::Any _data; + CORBA::ORB_ptr _orb; + }; + + + } +} + +#endif diff --git a/src/runtime/CORBAPythonConv.cxx b/src/runtime/CORBAPythonConv.cxx new file mode 100644 index 000000000..48227fb3e --- /dev/null +++ b/src/runtime/CORBAPythonConv.cxx @@ -0,0 +1,113 @@ + +#include "CORBAPythonConv.hxx" +#include "TypeConversions.hxx" +#include "RuntimeSALOME.hxx" + +#include + +using namespace YACS::ENGINE; +using namespace std; + +void CorbaPyDouble::put(const void *data) throw(ConversionException) +{ + put((CORBA::Any *)data); +} + +//!Convertit un CORBA::Any de type double en PyObject de type Double +/*! + * \param data : CORBA::Any object + */ + +void CorbaPyDouble::put(CORBA::Any *data) throw(ConversionException) +{ + CORBA::Double d; + *data >>=d; + PyObject *ob=PyFloat_FromDouble(d); + cerr << "ob refcnt: " << ob->ob_refcnt << endl; + _port->put(ob); +} + + +void CorbaPyInt::put(const void *data) throw(ConversionException) +{ + put((CORBA::Any *)data); +} + +//!Convertit un CORBA::Any de type entier en PyObject de type entier +/*! + * \param data : CORBA::Any object + */ + +void CorbaPyInt::put(CORBA::Any *data) throw(ConversionException) +{ + CORBA::Long l; + *data >>=l; + PyObject *ob=PyLong_FromLong(l); + cerr << "ob refcnt: " << ob->ob_refcnt << endl; + _port->put(ob); +} + + +void CorbaPyString::put(const void *data) throw(ConversionException) +{ + put((CORBA::Any *)data); +} + +//!Convertit un CORBA::Any de type string en PyObject de type string +/*! + * \param data : CORBA::Any object + */ + +void CorbaPyString::put(CORBA::Any *data) throw(ConversionException) +{ + char *s; + *data >>=s; + PyObject *ob=PyString_FromString(s); + cerr << "ob refcnt: " << ob->ob_refcnt << endl; + _port->put(ob); +} + + +void CorbaPyObjref::put(const void *data) throw(ConversionException) +{ + put((CORBA::Any *)data); +} + +//!Convertit un CORBA::Any de type Objref en PyObject de type Objref +/*! + * \param data : CORBA::Any object + */ + +void CorbaPyObjref::put(CORBA::Any *data) throw(ConversionException) +{ + CORBA::Object_ptr ObjRef ; + *data >>= (CORBA::Any::to_object ) ObjRef ; + //hold_lock is true: caller is supposed to hold the GIL. + //omniorb will not take the GIL + PyObject *ob = getSALOMERuntime()->getApi()->cxxObjRefToPyObjRef(ObjRef, 1); + cerr << "ob refcnt: " << ob->ob_refcnt << endl; + _port->put(ob); +} + +CorbaPySequence::CorbaPySequence(InputPyPort* p) + : ProxyPort(p), Port(p->getNode()) +{ + _dynfactory = getSALOMERuntime()->getDynFactory(); +} + +void CorbaPySequence::put(const void *data) throw(ConversionException) +{ + put((CORBA::Any *)data); +} + +void CorbaPySequence::put(CORBA::Any *data) throw(ConversionException) +{ + cerr << "PyCorbaSequence::put" << endl; + PyObject *ob=convertPyObjectCorba(type(),data); + cerr << "ob refcnt: " << ob->ob_refcnt << endl; + cerr << "Sequence= "; + PyObject_Print(ob,stdout,Py_PRINT_RAW); + cerr << endl; + _port->put(ob); +} + diff --git a/src/runtime/CORBAPythonConv.hxx b/src/runtime/CORBAPythonConv.hxx new file mode 100644 index 000000000..1648910fd --- /dev/null +++ b/src/runtime/CORBAPythonConv.hxx @@ -0,0 +1,63 @@ +#ifndef __CORBAPYTHONCONV_HXX__ +#define __CORBAPYTHONCONV_HXX__ + +#include + +#include "PythonPorts.hxx" + +namespace YACS +{ + namespace ENGINE + { + + // --- convertisseurs Corba->Python pour les différents types + + class CorbaPyDouble : public ProxyPort + { + public: + CorbaPyDouble(InputPyPort* p) + : ProxyPort(p), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(CORBA::Any *data) throw(ConversionException); + }; + + class CorbaPyInt : public ProxyPort + { + public: + CorbaPyInt(InputPyPort* p) + : ProxyPort(p), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(CORBA::Any *data) throw(ConversionException); + }; + + class CorbaPyString : public ProxyPort + { + public: + CorbaPyString(InputPyPort* p) + : ProxyPort(p), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(CORBA::Any *data) throw(ConversionException); + }; + + class CorbaPyObjref : public ProxyPort + { + public: + CorbaPyObjref(InputPyPort* p) + : ProxyPort(p), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(CORBA::Any *data) throw(ConversionException); + }; + + class CorbaPySequence : public ProxyPort + { + public: + CorbaPySequence(InputPyPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(CORBA::Any *data) throw(ConversionException); + protected: + DynamicAny::DynAnyFactory_ptr _dynfactory; + }; + + } +} +#endif diff --git a/src/runtime/CORBAXMLConv.cxx b/src/runtime/CORBAXMLConv.cxx new file mode 100644 index 000000000..88ea6a742 --- /dev/null +++ b/src/runtime/CORBAXMLConv.cxx @@ -0,0 +1,37 @@ + +#include "CORBAXMLConv.hxx" +#include "TypeConversions.hxx" + +#include + +using namespace YACS::ENGINE; +using namespace std; + +CorbaXml::CorbaXml(InputXmlPort* p) + : ProxyPort(p), Port(p->getNode()) +{ + cerr << "proxy port from CORBA to XML" << endl; +} + +//!Convertit un Any convertible en Xml::char * +/*! + * \param data : CORBA::Any object + */ + +void CorbaXml::put(const void *data) throw(ConversionException) +{ + put((CORBA::Any *)data); +} + +void CorbaXml::put(CORBA::Any *data) throw(ConversionException) +{ + //conversion du Any data en any attendu (de type type()) + + cerr << "CorbaXml::put" << endl; + char *a = convertXmlCorba(type(),data); + cerr << a << endl; + cerr << _port->getName() << endl; + cerr << _port->getImpl() << endl; + _port->put((const char*)a); + cerr << "Fin CorbaXml::put" << endl; +} diff --git a/src/runtime/CORBAXMLConv.hxx b/src/runtime/CORBAXMLConv.hxx new file mode 100644 index 000000000..409bc7d39 --- /dev/null +++ b/src/runtime/CORBAXMLConv.hxx @@ -0,0 +1,23 @@ +#ifndef __CORBAXMLCONV_HXX__ +#define __CORBAXMLCONV_HXX__ + +#include + +#include "XMLPorts.hxx" + +namespace YACS +{ + namespace ENGINE + { + // Ports adaptateurs Corba->Xml pour les différents types + + class CorbaXml : public ProxyPort + { + public: + CorbaXml(InputXmlPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(CORBA::Any *data) throw(ConversionException); + }; + } +} +#endif diff --git a/src/runtime/CppNode.cxx b/src/runtime/CppNode.cxx new file mode 100644 index 000000000..d351ca7b4 --- /dev/null +++ b/src/runtime/CppNode.cxx @@ -0,0 +1,48 @@ + +#include "CppNode.hxx" +#include "InputPort.hxx" +#include "OutputPort.hxx" + +#include +#include + +using namespace YACS::ENGINE; +using namespace std; + +CppNode::CppNode(const string name): ElementaryNode(name) +{ + _implementation = "Cpp"; + cerr << "CppNode::CppNode: " << name << endl; +} + +void CppNode::execute() +{ +// // --- Input Ports ready, read data + +// int nbin = _setOfInputPort.size(); +// int nbout = _setOfOutputPort.size(); +// void **input = new (void *)[nbin]; +// void **output = new (void *)[nbout]; + +// int i=0; +// for (std::set::iterator it = _setOfInputPort.begin(); it != _setOfInputPort.end(); it++) +// { +// Data container = (*it)->exGet(); +// void *content = container.get(); +// input[i++] = content; +// } + +// // --- invoke service (in a thread) + +// bool ret = (_run)(nbin, nbout, input, output); + +// // --- get results, fill OutputPort with copy, then put converted data in linked InputPort + +// i=0; +// for (std::set::iterator it = _setOfOutputPort.begin(); it != _setOfOutputPort.end(); it++) +// { +// Data container((*it)->edGetType()); +// container.put(output[i++]); +// (*it)->put(container); +// } +} diff --git a/src/runtime/CppNode.hxx b/src/runtime/CppNode.hxx new file mode 100644 index 000000000..56ec4c3aa --- /dev/null +++ b/src/runtime/CppNode.hxx @@ -0,0 +1,29 @@ + +#ifndef _CPPNODE_HXX_ +#define _CPPNODE_HXX_ + +#include "ElementaryNode.hxx" + +namespace YACS +{ + namespace ENGINE + { + // local C++ implementation - single process + + typedef bool (*MYRUN)(int nbin, int nbout, void **in, void** out); + + class CppNode: public ENGINE::ElementaryNode + { + public: + CppNode(const std::string name); + virtual void execute(); + void setfunc(MYRUN fonc) { _run = fonc;} + + protected: + MYRUN _run; + + }; + } +} + +#endif diff --git a/src/runtime/Makefile.am b/src/runtime/Makefile.am new file mode 100644 index 000000000..8b34bb667 --- /dev/null +++ b/src/runtime/Makefile.am @@ -0,0 +1,38 @@ + +include $(top_srcdir)/adm/unix/make_begin.am + +SUBDIRS = Test + +lib_LTLIBRARIES = libYACSRuntimeSALOME.la + +libYACSRuntimeSALOME_la_SOURCES = \ + CORBACORBAConv.cxx \ + CORBANode.cxx \ + CORBAPorts.cxx \ + CORBAPythonConv.cxx \ + CORBAXMLConv.cxx \ + CppNode.cxx \ + PythonCORBAConv.cxx \ + PythonNode.cxx \ + PythonPorts.cxx \ + RuntimeSALOME.cxx \ + TypeConversions.cxx \ + XMLCORBAConv.cxx \ + XMLNode.cxx \ + XMLPorts.cxx \ + $(__dummy__) + +EXTRA_libYACSRuntimeSALOME_la_SOURCES = \ + $(__dummy__) + +libYACSRuntimeSALOME_la_LIBADD = ../bases/libYACSBases.la + +AM_CXXFLAGS = $(THREAD_DEF) \ + $(PYTHON_CPPFLAGS) \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CCXFLAGS) \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + -I/usr/include/libxml2 + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/runtime/PythonCORBAConv.cxx b/src/runtime/PythonCORBAConv.cxx new file mode 100644 index 000000000..ce08d4626 --- /dev/null +++ b/src/runtime/PythonCORBAConv.cxx @@ -0,0 +1,152 @@ + +#include "PythonCORBAConv.hxx" +#include "TypeConversions.hxx" +#include "RuntimeSALOME.hxx" + +#include + +using namespace YACS::ENGINE; +using namespace std; + + +void PyCorbaInt::put(const void *data) throw(ConversionException) +{ + put((PyObject *)data); +} + +//!Convertit un PyObject de type entier en CORBA::Any entier +/*! + * \param data : python object + */ + +void PyCorbaInt::put(PyObject *data) throw(ConversionException) +{ + CORBA::Long l= PyLong_AsLong(data); + CORBA::Any a; + a <<= l; + _port->put(&a); +} + + +void PyCorbaString::put(const void *data) throw(ConversionException) +{ + put((PyObject *)data); +} + +//!Convertit un PyObject de type string en CORBA::Any string +/*! + * \param data : python object + */ + +void PyCorbaString::put(PyObject *data) throw(ConversionException) +{ + char * s=PyString_AsString(data); + CORBA::Any a; + a <<= s; + _port->put(&a); +} + + +void PyCorbaDouble::put(const void *data) throw(ConversionException) +{ + put((PyObject *)data); +} + +//!Convertit un PyObject de type double en CORBA::Any Double +/*! + * \param data : python object + */ + +void PyCorbaDouble::put(PyObject *data) throw(ConversionException) +{ + CORBA::Double d = 0; + if (PyFloat_Check(data)) + d = (CORBA::Double)PyFloat_AS_DOUBLE(data); + else if (PyInt_Check(data)) + d = (CORBA::Double)PyInt_AS_LONG(data); + else + d = (CORBA::Double)PyLong_AsDouble(data); + CORBA::Any a; + a <<= d; + _port->put(&a); +} + +PyCorbaSequence::PyCorbaSequence(InputCorbaPort* p) + : ProxyPort(p), Port(p->getNode()) +{ + cerr << "CorbaPySequence" << endl; +} + +//!Convertit un PyObject de type Sequence en CORBA::Any Sequence +/*! + * \param data : python object + */ + +void PyCorbaSequence::put(const void *data) throw(ConversionException) +{ + put((PyObject *)data); +} + +void PyCorbaSequence::put(PyObject *data) throw(ConversionException) +{ + cerr << "PyCorbaSequence::put" << endl; + cerr << "data refcnt: " << data->ob_refcnt << endl; + PyObject_Print(data,stdout,Py_PRINT_RAW); + cerr << endl; + int length=PySequence_Size(data); + cerr <<"length: " << length << endl; + CORBA::Any *a= convertCorbaPyObject(_port->type(),data); + _port->put(a); +} + + +PyCorbaObjref::PyCorbaObjref(InputCorbaPort* p) + : ProxyPort(p), Port(p->getNode()) +{ + _pyorb = getSALOMERuntime()->getPyOrb(); + _orb = getSALOMERuntime()->getOrb(); + // _dynFactory = getSALOMERuntime()->getDynFactory(); +} + +//!Convertit un PyObject de type Objref en CORBA::Any Objref +/*! + * \param data : python object + */ + +void PyCorbaObjref::put(const void *data) throw(ConversionException) +{ + put((PyObject *)data); +} + +void PyCorbaObjref::put(PyObject *data) throw(ConversionException) +{ + cerr << "PyCorbaObjref::put" << endl; + cerr << "data refcnt: " << data->ob_refcnt << endl; + PyObject_Print(data,stdout,Py_PRINT_RAW); + cerr << endl; + + //ne marche pas ??? + //hold_lock is true: caller is supposed to hold the GIL. + //omniorb will not take the GIL + //CORBA::Object_ptr ob=api->pyObjRefToCxxObjRef(data,(CORBA::Boolean)1); + + PyObject_Print(_pyorb,stdout,Py_PRINT_RAW); + cerr << endl; + PyObject *pystring = PyObject_CallMethod(_pyorb, "object_to_string", "O", data); + if(pystring == NULL) + { + PyErr_Print(); + throw Exception("not possible to get objref"); + } + + PyObject_Print(pystring,stdout,Py_PRINT_RAW); + cerr << endl; + CORBA::Object_ptr ob= _orb->string_to_object(PyString_AsString(pystring)); + Py_DECREF(pystring); + cerr << "data refcnt: " << data->ob_refcnt << endl; + + CORBA::Any a; + a <<= ob; + _port->put(&a); +} + diff --git a/src/runtime/PythonCORBAConv.hxx b/src/runtime/PythonCORBAConv.hxx new file mode 100644 index 000000000..180e170be --- /dev/null +++ b/src/runtime/PythonCORBAConv.hxx @@ -0,0 +1,63 @@ +#ifndef __PYTHONCORBACONV_HXX__ +#define __PYTHONCORBACONV_HXX__ + +#include + +#include "CORBAPorts.hxx" + +namespace YACS +{ + namespace ENGINE + { + + // --- convertisseurs Python->Corba pour les différents types + + class PyCorbaInt : public ProxyPort + { + public: + PyCorbaInt(InputCorbaPort* p) + : ProxyPort(p), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(PyObject *data) throw(ConversionException); + }; + + class PyCorbaDouble : public ProxyPort + { + public: + PyCorbaDouble(InputCorbaPort* p) + : ProxyPort(p), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(PyObject *data) throw(ConversionException); + }; + + class PyCorbaString : public ProxyPort + { + public: + PyCorbaString(InputCorbaPort* p) + : ProxyPort(p), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(PyObject *data) throw(ConversionException); + }; + + class PyCorbaObjref : public ProxyPort + { + public: + PyCorbaObjref(InputCorbaPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(PyObject *data) throw(ConversionException); + protected: + PyObject * _pyorb; + CORBA::ORB_var _orb; + }; + + class PyCorbaSequence : public ProxyPort + { + public: + PyCorbaSequence(InputCorbaPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(PyObject *data) throw(ConversionException); + }; + + } +} +#endif diff --git a/src/runtime/PythonNode.cxx b/src/runtime/PythonNode.cxx new file mode 100644 index 000000000..913346b17 --- /dev/null +++ b/src/runtime/PythonNode.cxx @@ -0,0 +1,79 @@ + +#include "PythonNode.hxx" +#include "RuntimeSALOME.hxx" + +#include +#include + +using namespace YACS::ENGINE; +using namespace std; + +PythonNode::PythonNode(const string& name): ElementaryNode(name) +{ + _implementation = "Python"; + cerr << "PythonNode::PythonNode " << name << endl; +} + +void PythonNode::set_script(const string& script) +{ + _script = script; +} + +void PythonNode::execute() +{ + cerr << "PyNode::run" << endl; + PyObject* context=PyDict_New(); + if( PyDict_SetItemString( context, "__builtins__", getSALOMERuntime()->getBuiltins() )) + { + stringstream msg; + msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__; + throw Exception(msg.str()); + } + + cerr << "---------------PyNode::inputs---------------" << endl; + set::iterator iter2; + for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++) + { + InputPyPort *p=(InputPyPort *)*iter2; + cerr << "port name: " << p->getName() << endl; + cerr << "port kind: " << p->type()->kind() << endl; + PyObject* ob=p->getPyObj(); + cerr << "ob refcnt: " << ob->ob_refcnt << endl; + PyObject_Print(ob,stdout,Py_PRINT_RAW); + cerr << endl; + int ier=PyDict_SetItemString(context,p->getName().c_str(),ob); + cerr << "ob refcnt: " << ob->ob_refcnt << endl; + } + + cerr << "---------------End PyNode::inputs---------------" << endl; + + //calculation + cerr << "PyNode::calculation " << _script << endl; + PyObject *res=PyRun_String(_script.c_str(),Py_file_input,context,context); + if(res == NULL) + { + PyErr_Print(); + return; + } + Py_DECREF(res); + + cerr << "-----------------PyNode::outputs-----------------" << endl; + set::iterator iter; + for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++) + { + OutputPyPort *p=(OutputPyPort *)*iter; + cerr << "port name: " << p->getName() << endl; + cerr << "port kind: " << p->type()->kind() << endl; + PyObject *ob=PyDict_GetItemString(context,p->getName().c_str()); + cerr << "ob refcnt: " << ob->ob_refcnt << endl; + PyObject_Print(ob,stdout,Py_PRINT_RAW); + cerr << endl; + //Faut-il incrémenter ici ? + Py_INCREF(ob); + cerr << "ob refcnt: " << ob->ob_refcnt << endl; + p->put(ob); + } + + cerr << "-----------------End PyNode::outputs-----------------" << endl; + Py_DECREF(context); +} diff --git a/src/runtime/PythonNode.hxx b/src/runtime/PythonNode.hxx new file mode 100644 index 000000000..a972f3933 --- /dev/null +++ b/src/runtime/PythonNode.hxx @@ -0,0 +1,25 @@ + +#ifndef _PYTHONNODE_HXX_ +#define _PYTHONNODE_HXX_ + +#include "ElementaryNode.hxx" + +namespace YACS +{ + namespace ENGINE + { + + class PythonNode: public ElementaryNode + { + public: + PythonNode(const std::string& name); + virtual void execute(); + virtual void set_script(const std::string& script); + + protected: + std::string _script; + }; + } +} + +#endif diff --git a/src/runtime/PythonPorts.cxx b/src/runtime/PythonPorts.cxx new file mode 100644 index 000000000..cc2ebbeba --- /dev/null +++ b/src/runtime/PythonPorts.cxx @@ -0,0 +1,65 @@ + +#include "PythonPorts.hxx" + +#include + +using namespace YACS::ENGINE; +using namespace std; + +InputPyPort::InputPyPort(const string& name, Node *node, TypeCode * type) + : InputPort(name, node, type), Port(node) +{ + _impl = "Python"; +} + +void InputPyPort::put(const void *data) throw(ConversionException) +{ + put((PyObject *)data); + _empty = false; +} + +void InputPyPort::put(PyObject *data) throw(ConversionException) +{ + cerr << "InputPyPort::put" << endl; + _data = data; +} + +PyObject * InputPyPort::getPyObj() const +{ + return _data; +} + + + +OutputPyPort::OutputPyPort(const string& name, Node *node, TypeCode * type) + : OutputPort(name, node, type), Port(node) +{ + _impl = "Python"; +} + +void OutputPyPort::put(const void *data) throw(ConversionException) +{ + put((PyObject *)data); +} + +void OutputPyPort::put(PyObject *data) throw(ConversionException) +{ + cerr << "OutputPyPort::put" << endl; + InputPort *p; + cerr << "ob refcnt: " << data->ob_refcnt << endl; + PyObject_Print(data,stdout,Py_PRINT_RAW); + cerr << endl; + _data = data; + set::iterator iter; + for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++) + { + p = *iter; + p->put(data); + } +} + +PyObject * OutputPyPort:: get() const +{ + return _data; +} + diff --git a/src/runtime/PythonPorts.hxx b/src/runtime/PythonPorts.hxx new file mode 100644 index 000000000..4aa08499a --- /dev/null +++ b/src/runtime/PythonPorts.hxx @@ -0,0 +1,42 @@ + +#ifndef _PYTHONPORTS_HXX_ +#define _PYTHONPORTS_HXX_ + +#include + +#include "InputPort.hxx" +#include "OutputPort.hxx" + +namespace YACS +{ + namespace ENGINE + { + + class InputPyPort : public InputPort + { + public: + InputPyPort(const std::string& name, Node * node, TypeCode * type); + virtual void put(const void *data) throw(ConversionException); + void put(PyObject *data) throw(ConversionException); + virtual PyObject * getPyObj() const; + protected: + PyObject* _data; + }; + + class OutputPyPort : public OutputPort + { + public: + OutputPyPort(const std::string& name, Node * node, TypeCode * type); + virtual void put(const void *data) throw(ConversionException); + void put(PyObject *data) throw(ConversionException); + virtual PyObject * get() const; + protected: + PyObject* _data; + }; + + + + } +} + +#endif diff --git a/src/runtime/RuntimeSALOME.cxx b/src/runtime/RuntimeSALOME.cxx new file mode 100644 index 000000000..2980487b2 --- /dev/null +++ b/src/runtime/RuntimeSALOME.cxx @@ -0,0 +1,592 @@ + +#include "RuntimeSALOME.hxx" +#include "PythonNode.hxx" +#include "CORBANode.hxx" +#include "XMLNode.hxx" +#include "CppNode.hxx" +#include "TypeConversions.hxx" +#include "CORBACORBAConv.hxx" +#include "PythonCORBAConv.hxx" +#include "CORBAPythonConv.hxx" +#include "XMLCORBAConv.hxx" + +#include +#include +#include +#include + +using namespace std; +using namespace YACS::ENGINE; + + + +void RuntimeSALOME::setRuntime() // singleton creation (not thread safe!) +{ + if (! Runtime::_singleton) Runtime::_singleton = new RuntimeSALOME(); +} + +RuntimeSALOME* YACS::ENGINE::getSALOMERuntime() +{ + assert(Runtime::_singleton); + return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton); +} + +/** + * Singleton creation, initialize converter map + */ + +RuntimeSALOME::RuntimeSALOME() +{ + _setOfImplementation.insert("Cpp"); + _setOfImplementation.insert("Python"); + _setOfImplementation.insert("CORBA"); + init(); +} + + +void RuntimeSALOME::init() +{ + int nbargs = 0; char **args = 0; + _orb = CORBA::ORB_init (nbargs, args); + CORBA::Object_var obj = _orb->resolve_initial_references("DynAnyFactory"); + _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj); + + PyObject *mainmod ; + cerr << "RuntimeSALOME::init" << endl; + Py_Initialize(); + + mainmod = PyImport_AddModule("__main__"); + PyObject *globals; + globals = PyModule_GetDict(mainmod); + + /* globals is a borrowed reference */ + Py_INCREF(globals); + /* globals is a new reference */ + + _bltins = PyEval_GetBuiltins(); /* borrowed ref */ + + //init section + PyObject* omnipy = PyImport_ImportModule((char*)"_omnipy"); + if (!omnipy) + { + PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy"); + return; + } + PyObject* pyapi = PyObject_GetAttrString(omnipy, (char*)"API"); + _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi); + Py_DECREF(pyapi); + PyObject *res=PyRun_String("\n" + "import sys\n" + "sys.path.insert(0,'.')\n" + "import CORBA\n" + "from omniORB import any\n" + "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n" + "print sys.getrefcount(orb)\n" + "\n", + Py_file_input,globals,globals ); + if(res == NULL) + { + PyErr_Print(); + return; + } + Py_DECREF(res); + _pyorb = PyDict_GetItemString(globals,"orb"); + cerr << "refcnt: " << _pyorb->ob_refcnt << endl; + PyObject_Print(_pyorb,stdout,Py_PRINT_RAW); + cerr << endl; + /* pyorb is a borrowed reference */ + //Py_INCREF(pyorb); pas nécessaire + + PyObject *pyany; + pyany = PyDict_GetItemString(globals,"any"); + cerr << "pyany refcnt: " << pyany->ob_refcnt << endl; + /* pyany is a borrowed reference */ +} + + +void RuntimeSALOME::fini() +{ + cerr << "RuntimeSALOME::fini" << endl; + Py_Finalize(); +} + + +ElementaryNode* RuntimeSALOME::createNode(string implementation, + string name) throw(Exception) +{ + ElementaryNode* node = 0; + if (implementation == "Python") + node = new PythonNode(name); + else if (implementation == "CORBA") + node = new CORBANode(name); + else if (implementation == "XML") + node = new XmlNode(name); + else if (implementation == "Cpp") + node = new CppNode(name); + else + { + string what ="RuntimeSALOME does not handle this implementation: " + implementation; + throw Exception(what); + } + return node; +} + +InputPort * RuntimeSALOME::createInputPort(const string& name, + const string& impl, + Node * node, + TypeCode * type) +{ + if(impl == "CPP") + { + throw Exception("Cannot create InputCppPort "); + } + else if(impl == "Python") + { + return new InputPyPort(name, node, type); + } + else if(impl == "CORBA") + { + return new InputCorbaPort(name, node, type); + } + else if(impl == "XML") + { + return new InputXmlPort(name, node, type); + } + else + { + stringstream msg; + msg << "Cannot create " << impl << " InputPort" ; + msg << " ("__FILE__ << ":" << __LINE__ << ")"; + throw Exception(msg.str()); + } +} + +OutputPort * RuntimeSALOME::createOutputPort(const string& name, + const string& impl, + Node * node, + TypeCode * type) +{ + if(impl == "CPP") + { + throw Exception("Cannot create OutputCppPort "); + } + else if(impl == "Python") + { + return new OutputPyPort(name, node, type); + } + else if(impl == "CORBA") + { + return new OutputCorbaPort(name, node, type); + } + else if(impl == "XML") + { + return new OutputXmlPort(name, node, type); + } + else + { + stringstream msg; + msg << "Cannot create " << impl << " OutputPort" ; + msg << " ("__FILE__ << ":" << __LINE__ << ")"; + throw Exception(msg.str()); + } +} + +InputPort* RuntimeSALOME::adapt(const string& imp_source, + InputPort* source, + const string& impl, + TypeCode * type) throw (ConversionException) +{ + cerr<<"RuntimeSALOME::adapt(InputPort* source" << endl; + if(imp_source == "Python") + { + return adapt((InputPyPort*)source,impl,type); + } + else if(imp_source == "CORBA") + { + return adapt((InputCorbaPort*)source,impl,type); + } + else if(imp_source == "XML") + { + return adapt((InputXmlPort*)source,impl,type); + } + else + { + stringstream msg; + msg << "Cannot adapt " << imp_source << " InputPort to " << impl; + msg << " ("__FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } +} + +//! Retourne un adaptateur d'un port entrant Xml pour un port sortant dont l'implémentation est donnée par impl +/*! + * \param source : input port to adapt to implementation impl and type type + * \param impl : output port implementation (C++, Python or Corba) + * \param type : le type supporté par le port sortant + * \return input port adapté à l'implémentation + */ + +InputPort* RuntimeSALOME::adapt(InputXmlPort* source, + const string& impl, + TypeCode * type) throw (ConversionException) +{ + cerr<<"RuntimeSALOME::adapt(InputXmlPort* source" << endl; + if(impl == "CORBA") + { + return adaptXmlToCorba(source,type); + } + else + { + stringstream msg; + msg << "Cannot connect InputXmlPort to " << impl << " implementation"; + msg << " ("__FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } +} + +//! Retourne un adaptateur d'un port entrant XML pour un port sortant CORBA +/*! + * \param inport : input port to adapt to CORBA type type + * \param type : le type supporté par le port sortant + * \return a InputCorbaPort port + */ + +InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport, + TypeCode * type) throw (ConversionException) +{ + cerr <<"RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport" << endl; + if(isAdaptableXmlCorba(type,inport->type())) + { + //les types sont convertibles + return new CorbaXml(inport); + } + //les types sont non convertibles + stringstream msg; + msg << "Cannot connect InputXmlPort to Corba output port " ; + msg << type->id() << " != " << inport->type()->id(); + msg << " ("__FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); +} + +//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant Xml +/*! + * \param inport : input port to adapt to Xml type type + * \param type : le type supporté par le port sortant + * \return an input port of Python type InputXmlPort + */ + +InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport, + TypeCode * type) throw (ConversionException) +{ + //ATTENTION : on utilise isAdaptableCorbaPyObject (meme fonction) + cerr << "RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport" << endl; + if(isAdaptableCorbaPyObject(type,inport->type())) + { + //les types sont convertibles + return new XmlCorba(inport); + } + //les types sont non convertibles + stringstream msg; + msg << "Cannot connect InputCorbaPort with OutputXmlPort : " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); +} + + +//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant CORBA +/*! + * \param inport : input port to adapt to CORBA type type + * \param type : le type supporté par le port sortant + */ + +InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport, + TypeCode * type) throw (ConversionException) +{ + if(type->is_a(inport->type())) + { + //les types sont compatibles : pas de conversion + return inport; + } + else if(isAdaptableCorbaCorba(type,inport->type())) + { + //les types sont convertibles + return new CorbaCorba(inport); + } + //les types sont non convertibles + stringstream msg; + msg << "Cannot connect 2 CorbaPort with non convertible types: " ; + msg << type->id() << " != " << inport->type()->id(); + throw ConversionException(msg.str()); +} + +//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant Python +/*! + * \param inport : input port to adapt to Python type type + * \param type : le type supporté par le port sortant + * \return an input port of Python type InputPyPort + */ + +InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport, + TypeCode * type) throw (ConversionException) +{ + if(inport->type()->kind() == Double) + { + if(isAdaptableCorbaPyObject(type,inport->type()))return new PyCorbaDouble(inport); + } + else if(inport->type()->kind() == Int) + { + if(isAdaptableCorbaPyObject(type,inport->type()))return new PyCorbaInt(inport); + } + else if(inport->type()->kind() == String) + { + if(isAdaptableCorbaPyObject(type,inport->type()))return new PyCorbaString(inport); + } + else if(inport->type()->kind() == Objref ) + { + if(isAdaptableCorbaPyObject(type,inport->type())) + { + return new PyCorbaObjref(inport); + } + else + { + stringstream msg; + msg << "Cannot connect InputPyPort : incompatible objref types "; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); + } + } + else if(inport->type()->kind() == Sequence) + { + if(isAdaptableCorbaPyObject(type,inport->type())) + { + return new PyCorbaSequence(inport); + } + else + { + stringstream msg; + msg << "Cannot convert this sequence type " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); + } + } + // Adaptation not found + stringstream msg; + msg << "Cannot connect InputCorbaPort to Python output " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); +} + +//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant C++ +/*! + * \param inport : input port to adapt to C++ type type + * \param type : le type supporté par le port sortant + */ + +InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport, + TypeCode * type) throw (ConversionException) +{ + throw ConversionException("Cannot connect InputCorbaPort to C++ "); +} + +//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant dont l'implémentation est donnée par impl +/*! + * \param source : input port to adapt to implementation impl and type type + * \param impl : output port implementation (C++, Python or Corba) + * \param type : le type supporté par le port sortant + */ + +InputPort* RuntimeSALOME::adapt(InputCorbaPort* source, + const string& impl, + TypeCode * type) throw (ConversionException) +{ + cerr<<"RuntimeSALOME::adapt(InputPyPort* source" << endl; + if(impl == "CPP") + { + return adaptCorbaToCpp(source,type); + } + else if(impl == "Python") + { + return adaptCorbaToPython(source,type); + } + else if(impl == "CORBA") + { + return adaptCorbaToCorba(source,type); + } + else if(impl == "XML") + { + return adaptCorbaToXml(source,type); + } + else + { + stringstream msg; + msg << "Cannot connect InputCorbaPort : unknown implementation " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); + } + return source; +} + +//! Retourne un adaptateur d'un port entrant Python pour un port sortant Python +/*! + * Dans ce cas, on ne fait pas de conversion ni de cast (int->double, par ex). + * On vérifie simplement que la connexion est autorisée. + * \param inport : InputPort to adapt to Python type type + * \param type : le TypeCode supporté par le port sortant + * \return InputPort de type Python (InputPyPort) + */ + +InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport, + TypeCode * type) throw (ConversionException) +{ + if(isAdaptablePyObjectPyObject(type,inport->type())) + { + //les types sont convertibles + //En Python, il n'est pas nécessaire de convertir. La conversion + //sera faite à la volée dans l'interpréteur + return inport; + } + //les types sont non convertibles + stringstream msg; + msg << "Cannot connect 2 Python Port with non convertible types: " ; + msg << type->id() << " != " << inport->type()->id(); + throw ConversionException(msg.str()); +} + +//! Retourne un adaptateur d'un port entrant Python pour un port sortant C++ +/*! + * Pas encore implémenté + * \param inport : InputPort to adapt to C++ type type + * \param type : le TypeCode supporté par le port sortant + * \return InputPort de type C++ (InputCppPort) + */ + +InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport, + TypeCode * type) throw (ConversionException) +{ + throw ConversionException("Cannot connect InputPyPort to C++ "); +} + +//! Retourne un adaptateur d'un port entrant Python pour un port sortant Corba +/*! + * On convertit dans tous les cas + * \param inport : InputPort to adapt to Corba type type + * \param type : le TypeCode supporté par le port sortant + * \return InputPort de type Corba (InputCorbaPort) + */ + +InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport, + TypeCode * type) throw (ConversionException) +{ + cerr << "RuntimeSALOME::adaptPythonToCorba:" ; + cerr << inport->type()->kind() << ":" << type->kind()<< endl; + + if(inport->type()->kind() == Double) + { + if(isAdaptablePyObjectCorba(type,inport->type()))return new CorbaPyDouble(inport); + } + else if(inport->type()->kind() == Int) + { + if(isAdaptablePyObjectCorba(type,inport->type()))return new CorbaPyInt(inport); + } + else if(inport->type()->kind() == String) + { + if(isAdaptablePyObjectCorba(type,inport->type()))return new CorbaPyString(inport); + } + else if(inport->type()->kind() == Objref) + { + if(isAdaptablePyObjectCorba(type,inport->type())) + { + return new CorbaPyObjref(inport); + } + else + { + stringstream msg; + msg << "Cannot connect InputCorbaPort : incompatible objref types "; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); + } + } + else if(inport->type()->kind() == Sequence) + { + if(isAdaptablePyObjectCorba(type,inport->type())) + { + return new CorbaPySequence(inport); + } + else + { + stringstream msg; + msg << "Cannot convert this sequence type " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); + } + } + // Adaptation not found + stringstream msg; + msg << "Cannot connect InputPyPort to Corba output " ; + msg << __FILE__ << ":" << __LINE__; + throw ConversionException(msg.str()); +} + +//! Retourne un adaptateur d'un port entrant Python pour un port sortant dont l'implémentation est donnée par impl +/*! + * \param source : input port to adapt to implementation impl and type type + * \param impl : output port implementation (C++, Python or Corba) + * \param type : le type supporté par le port sortant + * \return input port adapté à l'implémentation + */ + +InputPort* RuntimeSALOME::adapt(InputPyPort* source, + const string& impl, + TypeCode * type) throw (ConversionException) +{ + cerr<<"RuntimeSALOME::adapt(InputPyPort* source" << endl; + if(impl == "CPP") + { + return adaptPythonToCpp(source,type); + } + else if(impl == "Python") + { + return adaptPythonToPython(source,type); + } + else if(impl == "CORBA") + { + return adaptPythonToCorba(source,type); + } + else + { + throw ConversionException("Cannot connect InputPyPort : unknown implementation "); + } +} + +// bool RuntimeSALOME::isCompatible(const OutputPort* outputPort, +// const InputPort* inputPort) +// { +// bool result=true; +// return result; +// } + +CORBA::ORB_ptr RuntimeSALOME::getOrb() +{ + return _orb; +} + +PyObject * RuntimeSALOME::getPyOrb() +{ + return _pyorb; +} + +PyObject * RuntimeSALOME::getBuiltins() +{ + return _bltins; +} + +DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory() +{ + return _dynFactory; +} + +omniORBpyAPI* RuntimeSALOME::getApi() +{ + return _api; +} + diff --git a/src/runtime/RuntimeSALOME.hxx b/src/runtime/RuntimeSALOME.hxx new file mode 100644 index 000000000..c92e08706 --- /dev/null +++ b/src/runtime/RuntimeSALOME.hxx @@ -0,0 +1,124 @@ + +#ifndef _RUNTIMESALOME_HXX_ +#define _RUNTIMESALOME_HXX_ + +#include "Runtime.hxx" +#include "CORBAPorts.hxx" +#include "PythonPorts.hxx" +#include "XMLPorts.hxx" +#include "CORBAXMLConv.hxx" + +#include +#include + +namespace YACS +{ + namespace ENGINE + { + + //--- from omniORBpy.h (not present on Debian Sarge packages) + + struct omniORBpyAPI + { + + PyObject* (*cxxObjRefToPyObjRef)(const CORBA::Object_ptr cxx_obj, + CORBA::Boolean hold_lock); + // Convert a C++ object reference to a Python object reference. + // If is true, caller holds the Python interpreter lock. + + CORBA::Object_ptr (*pyObjRefToCxxObjRef)(PyObject* py_obj, + CORBA::Boolean hold_lock); + // Convert a Python object reference to a C++ object reference. + // Raises BAD_PARAM if the Python object is not an object reference. + // If is true, caller holds the Python interpreter lock. + + + omniORBpyAPI(); + // Constructor for the singleton. Sets up the function pointers. + }; + class RuntimeSALOME; + RuntimeSALOME* getSALOMERuntime(); + + class RuntimeSALOME: public Runtime + { + public: + + static void setRuntime(); // singleton creation + + friend RuntimeSALOME* getSALOMERuntime(); + + virtual void init(); + virtual void fini(); + + virtual InputPort* createInputPort(const std::string& name, + const std::string& impl, + Node * node, + TypeCode * type); + + virtual OutputPort* createOutputPort(const std::string& name, + const std::string& impl, + Node * node, + TypeCode * type); + + virtual ElementaryNode* createNode(std::string implementation, + std::string name ) throw(Exception); + + virtual InputPort* adapt(const std::string& imp_source, + InputPort* source, + const std::string& impl, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adapt(InputCorbaPort* source, + const std::string& impl, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptCorbaToCorba(InputCorbaPort* source, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptCorbaToPython(InputCorbaPort* source, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptCorbaToCpp(InputCorbaPort* source, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptCorbaToXml(InputCorbaPort* source, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adapt(InputPyPort* source, + const std::string& impl, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptPythonToCorba(InputPyPort* source, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptPythonToPython(InputPyPort* source, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptPythonToCpp(InputPyPort* source, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adapt(InputXmlPort* source, + const std::string& impl, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptXmlToCorba(InputXmlPort* source, + TypeCode * type) throw (ConversionException); + + CORBA::ORB_ptr getOrb(); + PyObject * getPyOrb(); + PyObject * getBuiltins(); + DynamicAny::DynAnyFactory_ptr getDynFactory(); + omniORBpyAPI* getApi(); + + protected: + RuntimeSALOME(); // singleton + CORBA::ORB_var _orb; + PyObject * _pyorb; + PyObject * _bltins; + DynamicAny::DynAnyFactory_var _dynFactory; + omniORBpyAPI* _api; + }; + } +} + +#endif diff --git a/src/runtime/Test/Makefile.am b/src/runtime/Test/Makefile.am new file mode 100644 index 000000000..0a29ddbe8 --- /dev/null +++ b/src/runtime/Test/Makefile.am @@ -0,0 +1,52 @@ + +include $(top_srcdir)/adm/unix/make_begin.am + +check_SCRIPTS = runtimeTest.sh + +check_PROGRAMS = TestRuntime echoSrv + +IDL_FILES = echo.idl +IDL_SOURCES = echoSK.cc +BUILT_SOURCES = $(IDL_SOURCES) echo_idl.py + +TESTS = runtimeTest.sh +TESTS_ENVIRONMENT=$(SHELL) -x + +TestRuntime_SOURCES = \ + TestRuntime.cxx \ + runtimeTest.cxx + +TestRuntime_LDADD = \ + $(OMNIORB_LIBS) \ + $(PYTHON_LDFLAGS) \ + $(PYTHON_EXTRA_LIBS) \ + ../libYACSRuntimeSALOME.la \ + ../../engine/libYACSEngine.la \ + ../../bases/libYACSBases.la + + +TestRuntime_LDFLAGS = \ + @CPPUNIT_LIBS@ -pthread -ldl -lxml2 + +TestRuntime_CXXFLAGS = \ + $(CPPUNIT_INCLUDES) \ + $(PYTHON_CPPFLAGS) \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CCXFLAGS) \ + -I$(srcdir)/.. \ + -I$(srcdir)/../../bases \ + -I$(srcdir)/../../bases/Test \ + -I$(srcdir)/../../engine \ + -I/usr/include/libxml2 + + +echoSrv_SOURCES = echoSrv.cxx $(IDL_SOURCES) + +echoSrv_CXXFLAGS = \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CXXFLAGS) + +echoSrv_LDFLAGS = \ + $(OMNIORB_LIBS) + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/runtime/Test/TestRuntime.cxx b/src/runtime/Test/TestRuntime.cxx new file mode 100644 index 000000000..c3de92282 --- /dev/null +++ b/src/runtime/Test/TestRuntime.cxx @@ -0,0 +1,13 @@ + +#include "runtimeTest.hxx" + +using namespace YACS; +using namespace std; + +// --- Registers the fixture into the 'registry' + +CPPUNIT_TEST_SUITE_REGISTRATION( RuntimeTest ); + +// --- generic Main program from bases/Test + +#include "BasicMainTest.hxx" diff --git a/src/runtime/Test/echo.idl b/src/runtime/Test/echo.idl new file mode 100644 index 000000000..dacf1c44c --- /dev/null +++ b/src/runtime/Test/echo.idl @@ -0,0 +1,70 @@ +#ifndef __ECHO_IDL__ +#define __ECHO_IDL__ + +module eo{ + enum ExceptionType + { + COMM, /*!< Communication problem */ + BAD_PARAM, /*!< Bad User parameters */ + INTERNAL_ERROR /*!< Application level problem, irrecoverable */ + }; + + struct ExceptionStruct + { + ExceptionType type; /*! DoubleVec ; + typedef sequence IntVec; + typedef sequence StrVec; + typedef sequence ObjectVec; + typedef sequence DoubleVecVec; + typedef sequence ObjectVecVec; + + interface Obj + { + long echoLong(in long i); + }; + interface C:Obj + { + }; + interface D + { + long echoLong2(in long i); + }; + interface E:C,D + { + }; + + typedef sequence ObjVec ; + + interface Echo + { + string echoString(in string mesg); + long echoLong(in long i) raises (SALOME_Exception); + void echoDouble(in double i,out double j) ; + void echoDoubleVec(in DoubleVec i,out DoubleVec j) ; + void echoDoubleVecVec(in DoubleVecVec i,out DoubleVecVec j) ; + void echoIntVec(in IntVec i,out IntVec j) ; + void echoStrVec(in StrVec i,out StrVec j) ; + void echoObjectVec(in ObjectVec i,out ObjectVec j) ; + void echoObjectVecVec(in ObjectVecVec i,out ObjectVecVec j) ; + Obj echoObj(in long i,in Obj o,in long k,out Obj p); + void createObj(in long i,out Obj p); + void createC(out C p); + void echoAll(in double d,in long l,in string m,in Obj o,out double dd,out long ll,out string s,out Obj p); + }; + interface SubEcho:Echo + { + }; +}; + +#endif diff --git a/src/runtime/Test/echoSrv.cxx b/src/runtime/Test/echoSrv.cxx new file mode 100644 index 000000000..f7fdda4fb --- /dev/null +++ b/src/runtime/Test/echoSrv.cxx @@ -0,0 +1,394 @@ +#include + +#include + +#include +using namespace std; + +static CORBA::Boolean bindObjectToName(CORBA::ORB_ptr, CORBA::Object_ptr); + +static ostream& operator<<(ostream& os, const CORBA::Exception& e) +{ + CORBA::Any tmp; + tmp<<= e; + CORBA::TypeCode_var tc = tmp.type(); + const char *p = tc->name(); + if ( *p != '\0' ) { + os<id(); + } + return os; +} + +class Obj_i : public POA_eo::Obj, public PortableServer::RefCountServantBase +{ +public: + inline Obj_i() {} + virtual ~Obj_i() {} + CORBA::Long echoLong(CORBA::Long i); +}; + +class C_i : public POA_eo::C, public PortableServer::RefCountServantBase +{ +public: + inline C_i() {} + virtual ~C_i() {} + CORBA::Long echoLong(CORBA::Long i); +}; + +class D_i : public POA_eo::D, public PortableServer::RefCountServantBase +{ +public: + inline D_i() {} + virtual ~D_i() {} + CORBA::Long echoLong2(CORBA::Long i); +}; + +class E_i : public POA_eo::E, public PortableServer::RefCountServantBase +{ +public: + inline E_i() {} + virtual ~E_i() {} + CORBA::Long echoLong(CORBA::Long i); + CORBA::Long echoLong2(CORBA::Long i); +}; + +class Echo_i : public POA_eo::Echo, + public PortableServer::RefCountServantBase +{ +public: + inline Echo_i() {} + virtual ~Echo_i() {} + virtual char* echoString(const char* mesg); + CORBA::Long echoLong(CORBA::Long i) throw(eo::SALOME_Exception); + void echoDouble(CORBA::Double i,CORBA::Double& j) ; + void echoDoubleVec(const eo::DoubleVec& i,eo::DoubleVec_out j) ; + void echoDoubleVecVec(const eo::DoubleVecVec&, eo::DoubleVecVec_out); + void echoIntVec(const eo::IntVec&, eo::IntVec_out); + void echoStrVec(const eo::StrVec&, eo::StrVec_out); + void echoObjectVec(const eo::ObjectVec&, eo::ObjectVec_out); + void echoObjectVecVec(const eo::ObjectVecVec&, eo::ObjectVecVec_out); + + eo::Obj_ptr echoObj(CORBA::Long i, eo::Obj_ptr o, CORBA::Long j, eo::Obj_out oo); + void createObj(CORBA::Long i, eo::Obj_out oo); + void createC(eo::C_out oo); + void echoAll(CORBA::Double d,CORBA::Long l,const char * m,eo::Obj_ptr o,CORBA::Double& dd,CORBA::Long& ll,CORBA::String_out s,eo::Obj_out oo); + virtual PortableServer::POA_ptr _default_POA(); +}; + +//Implementation Echo +PortableServer::POA_ptr Echo_i::_default_POA() +{ + PortableServer::POA_var root_poa=PortableServer::POA::_the_root_poa(); + try{ + return PortableServer::POA::_duplicate(root_poa->find_POA("shortcut",0)); + } + catch(...){ + //return PortableServer::POA::_duplicate(root_poa); + return root_poa._retn(); + } +} + +char* Echo_i::echoString(const char* mesg) +{ + cout << "Echo_i::echoString " << mesg << endl; + return CORBA::string_dup(mesg); +} + +void Echo_i::echoDouble(CORBA::Double i,CORBA::Double& j ) { + cout << "Echo_i::echoDouble " << i << endl; + j=i+1; +} + +void Echo_i::echoIntVec(const eo::IntVec& in, eo::IntVec_out out) +{ + cout << "Echo_i::echoIntVec " << in.length() << endl; + for(int i=0;i_PD_repoId << endl; + }; + out=new eo::ObjectVec(in); +} + +void Echo_i::echoObjectVecVec(const eo::ObjectVecVec& in, eo::ObjectVecVec_out out) +{ + cout << "Echo_i::echoObjectVecVec " << in.length() << endl; + for(int i=0;i< in.length(); i++){ + for(int j=0;j< in[i].length(); j++){ + cout << in[i][j]->_PD_repoId << endl; + }; + }; + out=new eo::ObjectVecVec(in); +} + +void Echo_i::echoDoubleVec(const eo::DoubleVec& in,eo::DoubleVec_out out ) +{ + cout << "Echo_i::echoDoubleVec " << in.length() << endl; + for(int i=0;i_this(); + oo = eo::Obj::_narrow(myref); + myobj->_remove_ref(); +} + +void Echo_i::createC(eo::C_out oo){ + cout << "Echo_i::createC " << endl; + C_i* myobj = new C_i(); + CORBA::Object_var myref = myobj->_this(); + oo = eo::C::_narrow(myref); + myobj->_remove_ref(); +} + +void Echo_i::echoAll(CORBA::Double d,CORBA::Long l,const char * m,eo::Obj_ptr o,CORBA::Double& dd,CORBA::Long& ll,CORBA::String_out s,eo::Obj_out oo) +{ + cout << "Echo_i::echoAll " << d << "," << l << "," << m << endl; + dd=d; + ll=l; + s=CORBA::string_dup(m); + oo=eo::Obj::_duplicate(o); +}; + +//Implementation Obj +CORBA::Long Obj_i::echoLong(CORBA::Long i ){ + cout << "Obj_i::echoLong " << i << endl; + CORBA::Long j=i+1; + return j; +} + +//Implementation C +CORBA::Long C_i::echoLong(CORBA::Long i ){ + cout << "C_i::echoLong " << i << endl; + CORBA::Long j=i+5; + return j; +} + +//Implementation D +CORBA::Long D_i::echoLong2(CORBA::Long i ){ + cout << "D_i::echoLong " << i << endl; + CORBA::Long j=i+10; + return j; +} + +//Implementation E +CORBA::Long E_i::echoLong2(CORBA::Long i ){ + cout << "E_i::echoLong " << i << endl; + CORBA::Long j=i+20; + return j; +} +CORBA::Long E_i::echoLong(CORBA::Long i ){ + cout << "E_i::echoLong " << i << endl; + CORBA::Long j=i+15; + return j; +} + +CORBA::ORB_ptr orb; +eo::Echo_var myechoref; + +int main(int argc, char** argv) +{ + try { + orb = CORBA::ORB_init(argc, argv); + + { + CORBA::Object_var obj = orb->resolve_initial_references("RootPOA"); + PortableServer::POA_var root_poa = PortableServer::POA::_narrow(obj); + // POA manager + PortableServer::POAManager_var poa_man = root_poa->the_POAManager(); + poa_man->activate(); + + // Create a new POA with the shortcut policy + CORBA::PolicyList pl2; + pl2.length(2); + CORBA::Any v; + v <<= omniPolicy::LOCAL_CALLS_SHORTCUT; + pl2[0] = orb->create_policy(omniPolicy::LOCAL_SHORTCUT_POLICY_TYPE, v); + pl2[1] = root_poa->create_implicit_activation_policy(PortableServer::IMPLICIT_ACTIVATION); + PortableServer::POA_ptr shortcut_poa = root_poa->create_POA("shortcut", poa_man, pl2); + + // Create and activate servant + Echo_i* myecho = new Echo_i(); + // Obtain a reference to the object, and print it out as a + // stringified IOR. + obj = myecho->_this(); + CORBA::String_var sior(orb->object_to_string(obj)); + cerr << "'" << (char*)sior << "'" << endl; + myechoref = eo::Echo::_narrow(obj); + + if( !bindObjectToName(orb, myechoref) ) + return 1; + + // Decrement the reference count of the object implementation, so + // that it will be properly cleaned up when the POA has determined + // that it is no longer needed. + myecho->_remove_ref(); + } + orb->run(); + } + catch(CORBA::SystemException&) { + cerr << "Caught CORBA::SystemException." << endl; + } + catch(CORBA::Exception& ex) { + cerr << "Caught CORBA::Exception." << ex << endl; + } + catch(omniORB::fatalException& fe) { + cerr << "Caught omniORB::fatalException:" << endl; + cerr << " file: " << fe.file() << endl; + cerr << " line: " << fe.line() << endl; + cerr << " mesg: " << fe.errmsg() << endl; + } + catch(...) { + cerr << "Caught unknown exception." << endl; + } + + return 0; +} + + +////////////////////////////////////////////////////////////////////// + +static CORBA::Boolean +bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref) +{ + CosNaming::NamingContext_var rootContext; + + try { + // Obtain a reference to the root context of the Name service: + CORBA::Object_var obj; + obj = orb->resolve_initial_references("NameService"); + + // Narrow the reference returned. + rootContext = CosNaming::NamingContext::_narrow(obj); + if( CORBA::is_nil(rootContext) ) { + cerr << "Failed to narrow the root naming context." << endl; + return 0; + } + } + catch(CORBA::ORB::InvalidName& ex) { + // This should not happen! + cerr << "Service required is invalid [does not exist]." << endl; + return 0; + } + + try { + // Bind a context called "test" to the root context: + + CosNaming::Name contextName; + contextName.length(1); + contextName[0].id = (const char*) "test"; // string copied + contextName[0].kind = (const char*) "my_context"; // string copied + // Note on kind: The kind field is used to indicate the type + // of the object. This is to avoid conventions such as that used + // by files (name.type -- e.g. test.ps = postscript etc.) + + CosNaming::NamingContext_var testContext; + try { + // Bind the context to root. + testContext = rootContext->bind_new_context(contextName); + } + catch(CosNaming::NamingContext::AlreadyBound& ex) { + // If the context already exists, this exception will be raised. + // In this case, just resolve the name and assign testContext + // to the object returned: + CORBA::Object_var obj; + obj = rootContext->resolve(contextName); + testContext = CosNaming::NamingContext::_narrow(obj); + if( CORBA::is_nil(testContext) ) { + cerr << "Failed to narrow naming context." << endl; + return 0; + } + } + + // Bind objref with name Echo to the testContext: + CosNaming::Name objectName; + objectName.length(1); + objectName[0].id = (const char*) "Echo"; // string copied + objectName[0].kind = (const char*) "Object"; // string copied + + try { + testContext->bind(objectName, objref); + } + catch(CosNaming::NamingContext::AlreadyBound& ex) { + testContext->rebind(objectName, objref); + } + // Note: Using rebind() will overwrite any Object previously bound + // to /test/Echo with obj. + // Alternatively, bind() can be used, which will raise a + // CosNaming::NamingContext::AlreadyBound exception if the name + // supplied is already bound to an object. + + // Amendment: When using OrbixNames, it is necessary to first try bind + // and then rebind, as rebind on it's own will throw a NotFoundexception if + // the Name has not already been bound. [This is incorrect behaviour - + // it should just bind]. + } + catch(CORBA::COMM_FAILURE& ex) { + cerr << "Caught system exception COMM_FAILURE -- unable to contact the " + << "naming service." << endl; + return 0; + } + catch(CORBA::SystemException&) { + cerr << "Caught a CORBA::SystemException while using the naming service." + << endl; + return 0; + } + + return 1; +} + diff --git a/src/runtime/Test/runtimeTest.cxx b/src/runtime/Test/runtimeTest.cxx new file mode 100644 index 000000000..b780fd169 --- /dev/null +++ b/src/runtime/Test/runtimeTest.cxx @@ -0,0 +1,971 @@ +// --- include from engine first, to avoid redifinition warning _POSIX_C_SOURCE + +#include "Bloc.hxx" +#include "ElementaryNode.hxx" +#include "Loop.hxx" +#include "Switch.hxx" +#include "RuntimeSALOME.hxx" +#include "CppNode.hxx" +#include "PythonNode.hxx" +#include "CORBANode.hxx" +#include "XMLNode.hxx" +#include "TypeConversions.hxx" +#include "CORBACORBAConv.hxx" +#include "PythonCORBAConv.hxx" +#include "CORBAPythonConv.hxx" +#include "CORBAXMLConv.hxx" + +#include "runtimeTest.hxx" + +#include + +#include +#include +#include +#include +#include +#include + +using namespace YACS::ENGINE; +using namespace YACS; +using namespace std; + +#define _DEVDEBUG_ +#ifdef _DEVDEBUG_ +#define MYDEBTRACE {std::cerr << __FILE__ << " [" << __LINE__ << "] : ";} +#define DEBTRACE(msg) {MYDEBTRACE; std::cerr<id() << " " << tc->name() ); + TypeCode *tc_seqdble = TypeCode::sequence_tc("eo:seqdouble","seqdouble",tc_double); + TypeCode *tc_seqstr = TypeCode::sequence_tc("eo:seqstring","seqstring",tc_string); + TypeCode *tc_seqlong = TypeCode::sequence_tc("eo:seqlong","seqlong",tc_int); + TypeCode *tc_seqobj = TypeCode::sequence_tc("eo:seqobj","seqobj",tc_obj); + TypeCode *tc_seqseqdble= TypeCode::sequence_tc("eo:seqseqdble","seqseqdble",tc_seqdble); + TypeCode *tc_seqseqobj = TypeCode::sequence_tc("eo:seqseqobj","seqseqobj",tc_seqobj); + std::list ltc; + ltc.push_back((TypeCode_objref *)tc_obj); + TypeCode *tc_C = TypeCode::interface_tc("eo:C","C",ltc); + TypeCode *tc_seqC = TypeCode::sequence_tc("eo:seqC","seqC",tc_C); + + DEBTRACE("int is a int: "); CPPUNIT_ASSERT( tc_int->is_a(tc_int)); + DEBTRACE("seqdble is not a seqlong: "); CPPUNIT_ASSERT(!tc_seqdble->is_a(tc_seqlong)); + DEBTRACE("seqdble is a seqdble: "); CPPUNIT_ASSERT( tc_seqdble->is_a(tc_seqdble)); + DEBTRACE("seqlong is not a seqdble: "); CPPUNIT_ASSERT(!tc_seqlong->is_a(tc_seqdble)); + DEBTRACE("C is a Obj: "); CPPUNIT_ASSERT( tc_C->is_a(tc_obj)); + DEBTRACE("Obj is not a C: " ); CPPUNIT_ASSERT(!tc_obj->is_a(tc_C)); + DEBTRACE("seqC is a seqObj: "); CPPUNIT_ASSERT( tc_seqC->is_a(tc_seqobj)); + DEBTRACE( "seqObj is not a seqC: "); CPPUNIT_ASSERT(!tc_seqobj->is_a(tc_seqC)); + + map nodeMap; + int inode = 0; + + // --- Nodes 0 a 4 : Python + + for (int i=0; i<5; i++) + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("Python",s); + nodeMap[s] = node; + InputPort *i1 = node->edAddInputPort("id1", tc_double); + InputPort *i2 = node->edAddInputPort("ii2", tc_int); + InputPort *i3 = node->edAddInputPort("is3", tc_string); + InputPort *i4 = node->edAddInputPort("io4", tc_obj); + InputPort *i5 = node->edAddInputPort("isd5", tc_seqdble); + InputPort *i6 = node->edAddInputPort("isl6", tc_seqlong); + InputPort *i7 = node->edAddInputPort("iso7", tc_seqobj); + InputPort *i8 = node->edAddInputPort("issd8",tc_seqseqdble); + InputPort *i9 = node->edAddInputPort("isso9",tc_seqseqobj); + InputPort *i10 = node->edAddInputPort("iC10", tc_C); + InputPort *i11 = node->edAddInputPort("isC11",tc_seqC); + + OutputPort *o1 = node->edAddOutputPort("od1", tc_double); + OutputPort *o2 = node->edAddOutputPort("oi2", tc_int); + OutputPort *o3 = node->edAddOutputPort("os3", tc_string); + OutputPort *o4 = node->edAddOutputPort("oo4", tc_obj); + OutputPort *o5 = node->edAddOutputPort("osd5", tc_seqdble); + OutputPort *o6 = node->edAddOutputPort("osl6", tc_seqlong); + OutputPort *o7 = node->edAddOutputPort("oso7", tc_seqobj); + OutputPort *o8 = node->edAddOutputPort("ossd8",tc_seqseqdble); + OutputPort *o9 = node->edAddOutputPort("osso9",tc_seqseqobj); + OutputPort *o10 = node->edAddOutputPort("oC10", tc_C); + OutputPort *o11 = node->edAddOutputPort("osC11",tc_seqC); + } + + // --- Nodes 5 a 9 : CORBA + + for (int i=5; i<10; i++) + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + InputPort *i1 = node->edAddInputPort("id1", tc_double); + InputPort *i2 = node->edAddInputPort("ii2", tc_int); + InputPort *i3 = node->edAddInputPort("is3", tc_string); + InputPort *i4 = node->edAddInputPort("io4", tc_obj); + InputPort *i5 = node->edAddInputPort("isd5", tc_seqdble); + InputPort *i6 = node->edAddInputPort("isl6", tc_seqlong); + InputPort *i7 = node->edAddInputPort("iso7", tc_seqobj); + InputPort *i8 = node->edAddInputPort("issd8",tc_seqseqdble); + InputPort *i9 = node->edAddInputPort("isso9",tc_seqseqobj); + InputPort *i10 = node->edAddInputPort("iC10", tc_C); + InputPort *i11 = node->edAddInputPort("isC11",tc_seqC); + + OutputPort *o1 = node->edAddOutputPort("od1", tc_double); + OutputPort *o2 = node->edAddOutputPort("oi2", tc_int); + OutputPort *o3 = node->edAddOutputPort("os3", tc_string); + OutputPort *o4 = node->edAddOutputPort("oo4", tc_obj); + OutputPort *o5 = node->edAddOutputPort("osd5", tc_seqdble); + OutputPort *o6 = node->edAddOutputPort("osl6", tc_seqlong); + OutputPort *o7 = node->edAddOutputPort("oso7", tc_seqobj); + OutputPort *o8 = node->edAddOutputPort("ossd8",tc_seqseqdble); + OutputPort *o9 = node->edAddOutputPort("osso9",tc_seqseqobj); + OutputPort *o10 = node->edAddOutputPort("oC10", tc_C); + OutputPort *o11 = node->edAddOutputPort("osC11",tc_seqC); + } + + DEBTRACE(" --- create bloc, add two nodes, check constituants" ); + + map blocMap; + int ibloc = 0; + + // --- Bloc_0 with Node_0 and Node_1 + { + ostringstream ss; + ss << "Bloc_" << ibloc++; + string s = ss.str(); + Bloc* bloc = new Bloc(s); + nodeMap[s] = bloc; + blocMap[s] = bloc; + bloc->edAddChild(nodeMap["Node_0"]); + bloc->edAddChild(nodeMap["Node_1"]); + { + set setelem = bloc->getRecursiveConstituents(); + CPPUNIT_ASSERT(setelem.size() == 2); + } + } + + // --- Bloc_1 with Node_2 + { + ostringstream ss; + ss << "Bloc_" << ibloc++; + string s = ss.str(); + Bloc* bloc = new Bloc(s); + nodeMap[s] = bloc; + blocMap[s] = bloc; + bloc->edAddChild(nodeMap["Node_2"]); + } + + DEBTRACE(" --- add a node already used in the bloc does nothing (return false)" ); + CPPUNIT_ASSERT( ! blocMap["Bloc_0"]->edAddChild(nodeMap["Node_1"])); + + DEBTRACE(" --- add a node already used elsewhere raises exception " ); + CPPUNIT_ASSERT_THROW(blocMap["Bloc_1"]->edAddChild(nodeMap["Node_1"]), + YACS::Exception); + + + DEBTRACE(" --- recursive blocs, check constituants" ); + + // --- Bloc_2 with Bloc_1 and Bloc_2 + { + ostringstream ss; + ss << "Bloc_" << ibloc++; + string s = ss.str(); + Bloc* bloc = new Bloc(s); + nodeMap[s] = bloc; + blocMap[s] = bloc; + bloc->edAddChild(nodeMap["Bloc_0"]); // 2 elementary nodes + bloc->edAddChild(nodeMap["Bloc_1"]); // 1 elementary node + bloc->edAddChild(nodeMap["Node_3"]); // 1 elementary node + } + + { + set setelem = blocMap["Bloc_2"]->getRecursiveConstituents(); + CPPUNIT_ASSERT(setelem.size() == 4); + for (set::iterator it=setelem.begin(); it!=setelem.end(); it++) + { + DEBTRACE(" elem name = " << (*it)->getName()); + } + } + + + DEBTRACE(" --- create and delete data links" ); + + CPPUNIT_ASSERT(blocMap["Bloc_0"]->getNumberOfInputPorts() == 22); + CPPUNIT_ASSERT_THROW(blocMap["Bloc_0"]->edAddLink(nodeMap["Node_0"]->getOutputPort("od1"), + nodeMap["Node_1"]->getInputPort("is3")), + YACS::ENGINE::ConversionException); + CPPUNIT_ASSERT(blocMap["Bloc_0"]->getNumberOfInputPorts() == 22); + + blocMap["Bloc_0"]->edAddLink(nodeMap["Node_0"]->getOutputPort("oi2"), + nodeMap["Node_1"]->getInputPort("ii2")); + CPPUNIT_ASSERT(blocMap["Bloc_0"]->getNumberOfInputPorts() == 21); + + blocMap["Bloc_0"]->edRemoveLink(nodeMap["Node_0"]->getOutputPort("oi2"), + nodeMap["Node_1"]->getInputPort("ii2")); + CPPUNIT_ASSERT(blocMap["Bloc_0"]->getNumberOfInputPorts() == 22); + + + DEBTRACE(" --- create python nodes with scripts" ); + + // --- Node 10 : Python + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("Python",s); + nodeMap[s] = node; + ((PythonNode*) node)->set_script("a=a+1\n"); + InputPort *i1 = node->edAddInputPort("a", tc_double); + OutputPort *o1 = node->edAddOutputPort("a", tc_double); + } + + // --- Node 11 : Python + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("Python",s); + nodeMap[s] = node; + ((PythonNode*) node)->set_script("a=b+1\n" + "c=2*a\n" + "i=10\n" + "s='aaaaaaa'\n" + "seqdble=[1.5,2.4]\n" + "lngvec=[1,2]\n" + "dblevecvec=[[1.5,2.4],[6.7,7.8]]\n" + ); + InputPort *i1 = node->edAddInputPort("b", tc_double); + OutputPort *o1 = node->edAddOutputPort("c", tc_double); + OutputPort *o2 = node->edAddOutputPort("i", tc_int); + OutputPort *o3 = node->edAddOutputPort("s", tc_string); + OutputPort *o4 = node->edAddOutputPort("seqdble", tc_seqdble); + OutputPort *o5 = node->edAddOutputPort("dblevecvec", tc_seqseqdble); + OutputPort *o6 = node->edAddOutputPort("lngvec", tc_seqlong); + } + + // --- Node 12 : Python + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("Python",s); + nodeMap[s] = node; + ((PythonNode*) node)->set_script("a=dble+1\n" + "dble=2*a\n" + ); + InputPort *i1 = node->edAddInputPort("dble", tc_double); + OutputPort *o1 = node->edAddOutputPort("dble", tc_double); + } + + // --- Node 13 : Python + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("Python",s); + nodeMap[s] = node; + ((PythonNode*) node)->set_script("print 'node 13'\n" + "import eo\n" + "print ob\n" + "o=ob._narrow(eo.Obj)\n" + "print o\n" + "print o.echoLong(13)\n" + "a=dble+1\n" + "dble=2*a\n" + "print lng\n" + "print '++++++++',s,'+++++++++++++'\n" + "ob=o\n" + "seqstr=['aaa','bbb']\n" + "seqobj=[o,o,o,o]\n" + "seqseqobj=[[o,o],[o,o]]\n" + ); + + InputPort *i1 = node->edAddInputPort("dble", tc_double); + InputPort *i2 = node->edAddInputPort("lng", tc_int); + InputPort *i3 = node->edAddInputPort("s", tc_string); + InputPort *i4 = node->edAddInputPort("ob", tc_obj); + OutputPort *o1 = node->edAddOutputPort("dble", tc_double); + OutputPort *o2 = node->edAddOutputPort("s", tc_string); + OutputPort *o3 = node->edAddOutputPort("lng", tc_int); + OutputPort *o4 = node->edAddOutputPort("ob", tc_obj); + OutputPort *o5 = node->edAddOutputPort("seqstr", tc_seqstr); + OutputPort *o6 = node->edAddOutputPort("seqobj", tc_seqobj); + OutputPort *o7 = node->edAddOutputPort("seqseqobj", tc_seqseqobj); + } + + // --- Node 14 : Python + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("Python",s); + nodeMap[s] = node; + ((PythonNode*) node)->set_script("print li\n" + "print 'lili=',lili\n" + "print 'lstr=',lstr\n" + "print 'lobj=',lobj\n" + "print 'llobj=',llobj\n" + "print 'objc=',objc\n" + "li=2*li\n" + ); + InputPort *i1 = node->edAddInputPort("li", tc_seqdble); + InputPort *i2 = node->edAddInputPort("lili", tc_seqseqdble); + InputPort *i3 = node->edAddInputPort("lstr", tc_seqstr); + InputPort *i4 = node->edAddInputPort("lobj", tc_seqobj); + InputPort *i5 = node->edAddInputPort("llobj", tc_seqseqobj); + InputPort *i6 = node->edAddInputPort("objc", tc_C); + OutputPort *o1 = node->edAddOutputPort("li", tc_seqdble); + OutputPort *o2 = node->edAddOutputPort("objc", tc_C); + } + + // --- Node 15 : Python + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("Python",s); + nodeMap[s] = node; + ((PythonNode*) node)->set_script("print li\n" + "li=[2*e for e in li]\n" + "print 'obj=',obj\n" + "print li\n" + "print lngvec\n" + "print dblevec\n" + ); + InputPort *i1 = node->edAddInputPort("li", tc_seqdble); + InputPort *i2 = node->edAddInputPort("obj", tc_obj); + InputPort *i3 = node->edAddInputPort("lngvec", tc_seqlong); + InputPort *i4 = node->edAddInputPort("dblevec", tc_seqdble); + OutputPort *o1 = node->edAddOutputPort("li", tc_seqdble); + } + + DEBTRACE(" --- create CORBA nodes" ); + + // --- Node 16 : CORBA + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("echoDouble"); + InputPort *i1 = node->edAddInputPort("a", tc_double); + OutputPort *o1 = node->edAddOutputPort("c", tc_double); + } + + // --- Node 17 - 18 : CORBA + + for (int i =0; i <2; i++) + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("echoDouble"); + InputPort *i1 = node->edAddInputPort("b", tc_double); + OutputPort *o1 = node->edAddOutputPort("c", tc_double); + } + + // --- Node 19 : CORBA + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("createObj"); + InputPort *i1 = node->edAddInputPort("long", tc_int); + OutputPort *o1 = node->edAddOutputPort("obj", tc_obj); + } + + // --- Node 20, 21, 22 : CORBA + + for (int i =0; i <3; i++) + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("echoAll"); + InputPort *i1 = node->edAddInputPort("double", tc_double); + InputPort *i2 = node->edAddInputPort("long", tc_int); + InputPort *i3 = node->edAddInputPort("str", tc_string); + InputPort *i4 = node->edAddInputPort("obj", tc_obj); + OutputPort *o1 = node->edAddOutputPort("double", tc_double); + OutputPort *o2 = node->edAddOutputPort("long", tc_int); + OutputPort *o3 = node->edAddOutputPort("str", tc_string); + OutputPort *o4 = node->edAddOutputPort("obj", tc_obj); + } + + // --- Node 23 a 26 : CORBA + + for (int i =0; i <4; i++) + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("echoDoubleVec"); + InputPort *i1 = node->edAddInputPort("dblevec", tc_seqdble); + OutputPort *o1 = node->edAddOutputPort("dblevec", tc_seqdble); + } + + // --- Node 27 : CORBA + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("echoStrVec"); + InputPort *i1 = node->edAddInputPort("strvec", tc_seqstr); + OutputPort *o1 = node->edAddOutputPort("strvec", tc_seqstr); + } + + // --- Node 28 : CORBA + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("echoObjectVec"); + InputPort *i1 = node->edAddInputPort("objvec", tc_seqobj); + OutputPort *o1 = node->edAddOutputPort("objvec", tc_seqobj); + } + + // --- Node 29 : CORBA + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("echoDoubleVecVec"); + InputPort *i1 = node->edAddInputPort("dblevecvec", tc_seqseqdble); + OutputPort *o1 = node->edAddOutputPort("dblevecvec", tc_seqseqdble); + } + + // --- Node 30 : CORBA + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("echoObjectVecVec"); + InputPort *i1 = node->edAddInputPort("objvecvec", tc_seqseqobj); + OutputPort *o1 = node->edAddOutputPort("objvecvec", tc_seqseqobj); + } + + // --- Node 31 : CORBA + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("echoIntVec"); + InputPort *i1 = node->edAddInputPort("lngvec", tc_seqlong); + OutputPort *o1 = node->edAddOutputPort("lngvec", tc_seqlong); + } + + // --- Node 32 : CORBA + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("createC"); + OutputPort *o1 = node->edAddOutputPort("objc", tc_C); + } + + // --- Node 33 : CORBA + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("echoDouble"); + InputPort *i1 = node->edAddInputPort("dble", tc_double); + OutputPort *o1 = node->edAddOutputPort("dble", tc_double); + } + + // --- Node 34 : CORBA + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("echoDoubleVec"); + InputPort *i1 = node->edAddInputPort("dblevec", tc_seqdble); + OutputPort *o1 = node->edAddOutputPort("dblevec", tc_seqdble); + } + + // --- Node 35 : CORBA + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("CORBA",s); + nodeMap[s] = node; + ((CORBANode *) node)->set_ref("corbaname:rir:#test.my_context/Echo.Object"); + ((CORBANode *) node)->set_method("echoDoubleVecVec"); + InputPort *i1 = node->edAddInputPort("dblevecvec", tc_seqseqdble); + OutputPort *o1 = node->edAddOutputPort("dblevecvec", tc_seqseqdble); + } + + DEBTRACE(" --- create XML nodes" ); + + // --- Node 36 : XML + + { + ostringstream ss; + ss << "Node_" << inode++; + string s = ss.str(); + ElementaryNode* node = myRuntime->createNode("XML",s); + nodeMap[s] = node; + ((XmlNode *) node)->set_script("./xmlrun.sh"); + InputPort *i1 = node->edAddInputPort("dble", tc_double); + InputPort *i2 = node->edAddInputPort("dblevec", tc_seqdble); + InputPort *i3 = node->edAddInputPort("dblevecvec", tc_seqseqdble); + OutputPort *o1 = node->edAddOutputPort("dble", tc_double); + OutputPort *o2 = node->edAddOutputPort("dblevec", tc_seqdble); + OutputPort *o3 = node->edAddOutputPort("dblevecvec", tc_seqseqdble); + } + + DEBTRACE(" --- create Bloc with all nodes" ); + + // --- Bloc_3 with Node_10 and following + + { + ostringstream ss; + ss << "Bloc_" << ibloc++; + string s = ss.str(); + Bloc* bloc = new Bloc(s); + nodeMap[s] = bloc; + blocMap[s] = bloc; + for (int i=10; iedAddChild(nodeMap[sn]); + } + } + + DEBTRACE(" --- create data links, python to python" ); + + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_10"]->getOutputPort("a"), + nodeMap["Node_11"]->getInputPort("b")); + + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_10"]->getOutputPort("a"), + nodeMap["Node_12"]->getInputPort("dble")); + + // Python sequence -> Python sequence + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_14"]->getOutputPort("li"), + nodeMap["Node_15"]->getInputPort("li")); + + // Python obj C -> Python obj Obj : OK bon sens + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_14"]->getOutputPort("objc"), + nodeMap["Node_15"]->getInputPort("obj")); + + // Python Obj -> Python C (dérivé de Obj) : interdit + CPPUNIT_ASSERT_THROW(blocMap["Bloc_3"]->edAddLink(nodeMap["Node_13"]->getOutputPort("ob"), + nodeMap["Node_14"]->getInputPort("objc")), + YACS::ENGINE::ConversionException); + + CPPUNIT_ASSERT_THROW(blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("s"), + nodeMap["Node_12"]->getInputPort("dble")), + YACS::ENGINE::ConversionException); + + CPPUNIT_ASSERT_THROW(blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("seqdble"), + nodeMap["Node_12"]->getInputPort("dble")), + YACS::ENGINE::ConversionException); + + DEBTRACE(" --- create data links, python to CORBA" ); + + // double->double + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("c"), + nodeMap["Node_16"]->getInputPort("a")); + + // int->int + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("i"), + nodeMap["Node_19"]->getInputPort("long")); + + // str->str + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("s"), + nodeMap["Node_20"]->getInputPort("str")); + + // seq -> seq + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("lngvec"), + nodeMap["Node_23"]->getInputPort("dblevec")); + + // seq -> seq + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("lngvec"), + nodeMap["Node_31"]->getInputPort("lngvec")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_13"]->getOutputPort("ob"), + nodeMap["Node_22"]->getInputPort("obj")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("seqdble"), + nodeMap["Node_26"]->getInputPort("dblevec")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_13"]->getOutputPort("seqstr"), + nodeMap["Node_27"]->getInputPort("strvec")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_13"]->getOutputPort("seqobj"), + nodeMap["Node_28"]->getInputPort("objvec")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("dblevecvec"), + nodeMap["Node_29"]->getInputPort("dblevecvec")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_13"]->getOutputPort("seqseqobj"), + nodeMap["Node_30"]->getInputPort("objvecvec")); + + CPPUNIT_ASSERT_THROW(blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("seqdble"), + nodeMap["Node_27"]->getInputPort("strvec")), + YACS::ENGINE::ConversionException); + + CPPUNIT_ASSERT_THROW(blocMap["Bloc_3"]->edAddLink(nodeMap["Node_13"]->getOutputPort("ob"), + nodeMap["Node_22"]->getInputPort("str")), + YACS::ENGINE::ConversionException); + + CPPUNIT_ASSERT_THROW(blocMap["Bloc_3"]->edAddLink(nodeMap["Node_13"]->getOutputPort("dble"), + nodeMap["Node_22"]->getInputPort("str")), + YACS::ENGINE::ConversionException); + + CPPUNIT_ASSERT_THROW(blocMap["Bloc_3"]->edAddLink(nodeMap["Node_13"]->getOutputPort("lng"), + nodeMap["Node_22"]->getInputPort("str")), + YACS::ENGINE::ConversionException); + + CPPUNIT_ASSERT_THROW(blocMap["Bloc_3"]->edAddLink(nodeMap["Node_13"]->getOutputPort("dble"), + nodeMap["Node_22"]->getInputPort("long")), + YACS::ENGINE::ConversionException); + + CPPUNIT_ASSERT_THROW(blocMap["Bloc_3"]->edAddLink(nodeMap["Node_13"]->getOutputPort("dble"), + nodeMap["Node_24"]->getInputPort("dblevec")), + YACS::ENGINE::ConversionException); + + CPPUNIT_ASSERT_THROW(blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("dblevecvec"), + nodeMap["Node_24"]->getInputPort("dblevec")), + YACS::ENGINE::ConversionException); + + CPPUNIT_ASSERT_THROW(blocMap["Bloc_3"]->edAddLink(nodeMap["Node_13"]->getOutputPort("seqstr"), + nodeMap["Node_24"]->getInputPort("dblevec")), + YACS::ENGINE::ConversionException); + + DEBTRACE(" --- create data links, CORBA to CORBA" ); + + // double->double + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_16"]->getOutputPort("c"), + nodeMap["Node_17"]->getInputPort("b")); + + // double->double + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_16"]->getOutputPort("c"), + nodeMap["Node_18"]->getInputPort("b")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_19"]->getOutputPort("obj"), + nodeMap["Node_20"]->getInputPort("obj")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_18"]->getOutputPort("c"), + nodeMap["Node_20"]->getInputPort("double")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_20"]->getOutputPort("long"), + nodeMap["Node_21"]->getInputPort("double")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_20"]->getOutputPort("long"), + nodeMap["Node_21"]->getInputPort("long")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_20"]->getOutputPort("str"), + nodeMap["Node_21"]->getInputPort("str")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_20"]->getOutputPort("obj"), + nodeMap["Node_21"]->getInputPort("obj")); + + // Corba sequence -> Corba sequence + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_23"]->getOutputPort("dblevec"), + nodeMap["Node_24"]->getInputPort("dblevec")); + + // Corba sequence -> Corba sequence + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_31"]->getOutputPort("lngvec"), + nodeMap["Node_25"]->getInputPort("dblevec")); + + + DEBTRACE(" --- create data links, CORBA to Python" ); + + + // Corba C -> Python C (dérivé de Obj):OK + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_32"]->getOutputPort("objc"), + nodeMap["Node_14"]->getInputPort("objc")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_21"]->getOutputPort("double"), + nodeMap["Node_13"]->getInputPort("dble")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_21"]->getOutputPort("long"), + nodeMap["Node_13"]->getInputPort("lng")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_21"]->getOutputPort("str"), + nodeMap["Node_13"]->getInputPort("s")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_21"]->getOutputPort("obj"), + nodeMap["Node_13"]->getInputPort("ob")); + + // Corba sequence -> Python sequence + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_23"]->getOutputPort("dblevec"), + nodeMap["Node_14"]->getInputPort("li")); + + // Corba sequence> -> Python sequence> + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_29"]->getOutputPort("dblevecvec"), + nodeMap["Node_14"]->getInputPort("lili")); + + // Corba sequence -> Python sequence + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_28"]->getOutputPort("objvec"), + nodeMap["Node_14"]->getInputPort("lobj")); + + // Corba sequence -> Python sequence + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_27"]->getOutputPort("strvec"), + nodeMap["Node_14"]->getInputPort("lstr")); + + // Corba sequence -> Python sequence + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_30"]->getOutputPort("objvecvec"), + nodeMap["Node_14"]->getInputPort("llobj")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_31"]->getOutputPort("lngvec"), + nodeMap["Node_15"]->getInputPort("lngvec")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_31"]->getOutputPort("lngvec"), + nodeMap["Node_15"]->getInputPort("dblevec")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_20"]->getOutputPort("long"), + nodeMap["Node_22"]->getInputPort("double")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_20"]->getOutputPort("long"), + nodeMap["Node_22"]->getInputPort("long")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_20"]->getOutputPort("str"), + nodeMap["Node_22"]->getInputPort("str")); + + DEBTRACE(" --- create data links, xml nodes" ); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_16"]->getOutputPort("c"), + nodeMap["Node_36"]->getInputPort("dble")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_26"]->getOutputPort("dblevec"), + nodeMap["Node_36"]->getInputPort("dblevec")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_29"]->getOutputPort("dblevecvec"), + nodeMap["Node_36"]->getInputPort("dblevecvec")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_36"]->getOutputPort("dble"), + nodeMap["Node_33"]->getInputPort("dble")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_36"]->getOutputPort("dblevec"), + nodeMap["Node_34"]->getInputPort("dblevec")); + + blocMap["Bloc_3"]->edAddLink(nodeMap["Node_36"]->getOutputPort("dblevecvec"), + nodeMap["Node_35"]->getInputPort("dblevecvec")); + + DEBTRACE(" --- initialization" ); + + PyObject *pyDouble = PyFloat_FromDouble(10.51); + nodeMap["Node_10"]->getInputPort("a")->put(pyDouble); + + CORBA::Any a; + a <<= (CORBA::Double) 3.14; + + CORBA::Any anyLong; + anyLong <<= (CORBA::Long) 1; + + CORBA::Any anyLong2; + anyLong2 <<= (CORBA::Long) 1; + nodeMap["Node_20"]->getInputPort("long")->put(&anyLong2); + + CORBA::Any aString; + aString <<= (const char *)"texte"; + nodeMap["Node_20"]->getInputPort("str")->put(&aString); + + + DEBTRACE(" --- execution Python Node_10" ); + ((ElementaryNode*)nodeMap["Node_10"])->execute(); + + DEBTRACE(" --- execution Python Node_11" ); + ((ElementaryNode*)nodeMap["Node_11"])->execute(); + + DEBTRACE(" --- execution Python Node_12" ); + ((ElementaryNode*)nodeMap["Node_12"])->execute(); + + DEBTRACE(" --- execution CORBA Node_16" ); + ((ElementaryNode*)nodeMap["Node_16"])->execute(); + + DEBTRACE(" --- execution CORBA Node_17" ); + ((ElementaryNode*)nodeMap["Node_17"])->execute(); + + DEBTRACE(" --- execution CORBA Node_18" ); + ((ElementaryNode*)nodeMap["Node_18"])->execute(); + + DEBTRACE(" --- execution CORBA Node_19" ); + ((ElementaryNode*)nodeMap["Node_19"])->execute(); + + DEBTRACE(" --- execution CORBA Node_20" ); + ((ElementaryNode*)nodeMap["Node_20"])->execute(); + + DEBTRACE(" --- execution CORBA Node_21" ); + ((ElementaryNode*)nodeMap["Node_21"])->execute(); + + DEBTRACE(" --- execution CORBA Node_29" ); + ((ElementaryNode*)nodeMap["Node_29"])->execute(); + + DEBTRACE(" --- execution Python Node_13" ); + ((ElementaryNode*)nodeMap["Node_13"])->execute(); + + DEBTRACE(" --- execution CORBA Node_22" ); + ((ElementaryNode*)nodeMap["Node_22"])->execute(); + + DEBTRACE(" --- execution CORBA Node_23" ); + ((ElementaryNode*)nodeMap["Node_23"])->execute(); + + DEBTRACE(" --- execution CORBA Node_24" ); + ((ElementaryNode*)nodeMap["Node_24"])->execute(); + + DEBTRACE(" --- execution CORBA Node_27" ); + ((ElementaryNode*)nodeMap["Node_27"])->execute(); + + DEBTRACE(" --- execution CORBA Node_28" ); + ((ElementaryNode*)nodeMap["Node_28"])->execute(); + + DEBTRACE(" --- execution CORBA Node_30" ); + ((ElementaryNode*)nodeMap["Node_30"])->execute(); + + DEBTRACE(" --- execution CORBA Node_32" ); + ((ElementaryNode*)nodeMap["Node_32"])->execute(); + + DEBTRACE(" --- execution CORBA Node_26" ); + ((ElementaryNode*)nodeMap["Node_26"])->execute(); + + DEBTRACE(" --- execution CORBA Node_31" ); + ((ElementaryNode*)nodeMap["Node_31"])->execute(); + + DEBTRACE(" --- execution Python Node_14" ); + ((ElementaryNode*)nodeMap["Node_14"])->execute(); + + DEBTRACE(" --- execution Python Node_15" ); + ((ElementaryNode*)nodeMap["Node_15"])->execute(); + + DEBTRACE(" --- execution XML Node_36" ); + ((ElementaryNode*)nodeMap["Node_36"])->execute(); + + DEBTRACE(" --- execution CORBA Node_33" ); + ((ElementaryNode*)nodeMap["Node_33"])->execute(); + + DEBTRACE(" --- execution CORBA Node_34" ); + ((ElementaryNode*)nodeMap["Node_34"])->execute(); + + DEBTRACE(" --- execution CORBA Node_35" ); + ((ElementaryNode*)nodeMap["Node_35"])->execute(); + + DEBTRACE(" --- end of execution" ); + + CORBA::Double l; + CORBA::Any* x; + + PyObject *ob=((OutputPyPort*)nodeMap["Node_11"]->getOutputPort("c"))->get(); + DEBTRACE("ob refcnt: " << ob->ob_refcnt); + PyObject_Print(ob,stdout,Py_PRINT_RAW); + + DEBTRACE("a: " << &a); + DEBTRACE("a.value(): " << a.value()); + + x= ((InputCorbaPort*)nodeMap["Node_16"]->getInputPort("a"))->getAny(); + DEBTRACE("CORBA Node_16 input a any: " << x); + *x >>= l; + DEBTRACE("CORBA Node_16 input a double: " << l); + + *((InputCorbaPort*)nodeMap["Node_17"]->getInputPort("b"))->getAny() >>= l; + DEBTRACE("CORBA Node_17 input b double: " << l); + + *((InputCorbaPort*)nodeMap["Node_18"]->getInputPort("b"))->getAny() >>= l; + DEBTRACE("CORBA Node_18 input a double: " << l); + + *((OutputCorbaPort*)nodeMap["Node_16"]->getOutputPort("c"))->getAny() >>= l; + DEBTRACE("CORBA Node_16 output c double: " << l); + + *((OutputCorbaPort*)nodeMap["Node_17"]->getOutputPort("c"))->getAny() >>= l; + DEBTRACE("CORBA Node_17 output c double: " << l); + + *((OutputCorbaPort*)nodeMap["Node_18"]->getOutputPort("c"))->getAny() >>= l; + DEBTRACE("CORBA Node_18 output c double: " << l); + + DEBTRACE(" --- fini" ); +} diff --git a/src/runtime/Test/runtimeTest.hxx b/src/runtime/Test/runtimeTest.hxx new file mode 100644 index 000000000..5caaa39ad --- /dev/null +++ b/src/runtime/Test/runtimeTest.hxx @@ -0,0 +1,30 @@ + +#ifndef _RUNTIMETEST_HXX_ +#define _RUNTIMETEST_HXX_ + +#include + +namespace YACS +{ + class RuntimeTest: public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( RuntimeTest ); + CPPUNIT_TEST(test1 ); + CPPUNIT_TEST_SUITE_END(); + + public: + + void setUp(); + void tearDown(); + + void test1(); + + protected: + + private: + + }; + +} + +#endif diff --git a/src/runtime/Test/runtimeTest.sh b/src/runtime/Test/runtimeTest.sh new file mode 100644 index 000000000..cbb79edf9 --- /dev/null +++ b/src/runtime/Test/runtimeTest.sh @@ -0,0 +1,31 @@ + +BASEREP=`pwd` +OMNIORB_CONFIG=${BASEREP}/omniorb.cfg +OMNINAMES_LOGDIR=${BASEREP}/omnilog + +export BASEREP +export OMNIORB_CONFIG +export OMNINAMES_LOGDIR + +echo ${BASEREP} +echo ${OMNIORB_CONFIG} + +# do not use the default port 2810 for omninames (to improve, cf. SALOME) +echo "InitRef = NameService=corbaname::localhost:2910" > ${OMNIORB_CONFIG} + +rm -rf ${OMNINAMES_LOGDIR} +mkdir ${OMNINAMES_LOGDIR} + +echo $$ + +omniNames -start 2910 & +pidomni=$! +echo $pidomni + +./echoSrv & +pidecho=$! +echo $pidecho + +./TestRuntime + +kill -9 $pidecho $pidomni diff --git a/src/runtime/TypeConversions.cxx b/src/runtime/TypeConversions.cxx new file mode 100644 index 000000000..58f3903b5 --- /dev/null +++ b/src/runtime/TypeConversions.cxx @@ -0,0 +1,1053 @@ + +#include "TypeConversions.hxx" +#include "Exception.hxx" +#include "RuntimeSALOME.hxx" + +#include +#include + +using namespace std; + +namespace YACS +{ + namespace ENGINE + { + + /* + * Fonctions qui retournent un TypeCode CORBA equivalent a un TypeCode Superviseur + */ + + CORBA::TypeCode_ptr getCorbaTCNull(TypeCode *t) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " : " << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + + CORBA::TypeCode_ptr getCorbaTCDouble(TypeCode *t) + { + return CORBA::_tc_double; + } + + CORBA::TypeCode_ptr getCorbaTCInt(TypeCode *t) + { + return CORBA::_tc_long; + } + + CORBA::TypeCode_ptr getCorbaTCString(TypeCode *t) + { + return CORBA::_tc_string; + } + + CORBA::TypeCode_ptr getCorbaTCObjref(TypeCode *t) + { + return CORBA::_tc_Object; + } + + CORBA::TypeCode_ptr getCorbaTCSequence(TypeCode *t) + { + return getSALOMERuntime()->getOrb()->create_sequence_tc(0,getCorbaTC(t->content_type())); + } + + getCorbaTCFn getCorbaTCFns[]= + { + getCorbaTCNull, + getCorbaTCDouble, + getCorbaTCInt, + getCorbaTCString, + getCorbaTCNull, + getCorbaTCObjref, + getCorbaTCSequence, + getCorbaTCNull, + }; + + CORBA::TypeCode_ptr getCorbaTC(TypeCode *t) + { + int tk=t->kind(); + return getCorbaTCFns[tk](t); + } + + /* + * Fin des Fonctions qui retournent un TypeCode CORBA equivalent a un TypeCode Superviseur + */ + + /* + * Fonctions de conversion d'un PyObject * quelconque en CORBA::Any * + * du type donné par le TypeCode passé en argument + */ + + //Le TypeCode passé en argument est celui du port qui recoit la donnée : InputCorbaPort + + //CORBA::Any *convertCorbaPyObject(TypeCode* t,PyObject* ob); + + CORBA::Any *convertCorbaPyObjectNull(TypeCode *t,PyObject *ob) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " : " << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + + //kind = 1 + //Conversion d'un objet Python "equivalent double" en CORBA::Any double + + CORBA::Any *convertCorbaPyObjectDouble(TypeCode *t,PyObject *ob) + { + PyObject_Print(ob,stdout,Py_PRINT_RAW); + cerr << endl; + CORBA::Double d = 0; + if (PyFloat_Check(ob)) + d = (CORBA::Double)PyFloat_AS_DOUBLE(ob); + else if (PyInt_Check(ob)) + d = (CORBA::Double)PyInt_AS_LONG(ob); + else + d = (CORBA::Double)PyLong_AsDouble(ob); + CORBA::Any *any = new CORBA::Any(); + *any <<= d; + return any; + } + + //kind = 2 + + CORBA::Any *convertCorbaPyObjectInt(TypeCode *t,PyObject *ob) + { + PyObject_Print(ob,stdout,Py_PRINT_RAW); + cerr << endl; + CORBA::Long l; + if (PyInt_Check(ob)) + l = PyInt_AS_LONG(ob); + else + l = PyLong_AsLong(ob); + CORBA::Any *any = new CORBA::Any(); + *any <<= l; + return any; + } + + //kind = 3 + + CORBA::Any *convertCorbaPyObjectString(TypeCode *t,PyObject *ob) + { + PyObject_Print(ob,stdout,Py_PRINT_RAW); + cerr << endl; + char * s=PyString_AsString(ob); + CORBA::Any *any = new CORBA::Any(); + *any <<= s; + return any; + } + + //kind = 5 + + CORBA::Any *convertCorbaPyObjectObjref(TypeCode *t,PyObject *ob) + { + PyObject_Print(ob,stdout,Py_PRINT_RAW); + cerr << endl; + PyObject *pystring=PyObject_CallMethod(getSALOMERuntime()->getPyOrb(), + "object_to_string", "O", ob); + CORBA::Object_ptr obref = + getSALOMERuntime()->getOrb()->string_to_object(PyString_AsString(pystring)); + Py_DECREF(pystring); + CORBA::Any *any = new CORBA::Any(); + *any <<= obref; + cerr << "typecode: " << any->type()->id() << endl; + return any; + }; + + //kind = 6 + + CORBA::Any *convertCorbaPyObjectSequence(TypeCode *t,PyObject *ob) + { + PyObject_Print(ob,stdout,Py_PRINT_RAW); + cerr << endl; + int length=PySequence_Size(ob); + cerr <<"length: " << length << endl; + CORBA::TypeCode_var tc_content; + DynamicAny::AnySeq as ; + as.length(length); + for(int i=0;iob_refcnt << endl; + CORBA::Any *a= convertCorbaPyObject(t->content_type(),o); + //ici on fait une copie. Peut-on l'éviter ? + as[i]=*a; + tc_content=a->type(); + //delete a; + Py_DECREF(o); + } + + CORBA::TypeCode_var tc = + getSALOMERuntime()->getOrb()->create_sequence_tc(0,tc_content); + DynamicAny::DynAny_var dynany = + getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc); + DynamicAny::DynSequence_var ds = + DynamicAny::DynSequence::_narrow(dynany); + + try + { + ds->set_elements(as); + } + catch(DynamicAny::DynAny::TypeMismatch& ex) + { + throw YACS::Exception("type mismatch"); + } + catch(DynamicAny::DynAny::InvalidValue& ex) + { + throw YACS::Exception("invalid value"); + } + CORBA::Any *any=ds->to_any(); + return any; + } + + convertCorbaPyObjectFn convertCorbaPyObjectFns[] = + { + convertCorbaPyObjectNull, + convertCorbaPyObjectDouble, + convertCorbaPyObjectInt, + convertCorbaPyObjectString, + convertCorbaPyObjectNull, + convertCorbaPyObjectObjref, + convertCorbaPyObjectSequence, + }; + + CORBA::Any *convertCorbaPyObject(TypeCode *t,PyObject *ob) + { + int tk=t->kind(); + return convertCorbaPyObjectFns[tk](t,ob); + } + + /* + * Fin des fonctions de conversion PyObject * -> CORBA::Any * + */ + + /* + * Fonctions de test d'adaptation pour conversion PyObject * (t1) -> CORBA::Any * (t2) + */ + //t1 est le type du port output Python + //t2 est le type du port input Corba + + int isAdaptableCorbaPyObjectNull(TypeCode *t1,TypeCode* t2) + { + return 0; + } + + int isAdaptableCorbaPyObjectDouble(TypeCode *t1,TypeCode* t2) + { + if (t1->kind() == Double) return 1; + if (t1->kind() == Int) return 1; + return 0; + } + + int isAdaptableCorbaPyObjectInt(TypeCode *t1,TypeCode* t2) + { + if (t1->kind() == Int) return 1; + return 0; + } + + int isAdaptableCorbaPyObjectString(TypeCode *t1,TypeCode* t2) + { + if (t1->kind() == String)return 1; + return 0; + } + + int isAdaptableCorbaPyObjectObjref(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Objref) + { + //Il faut que le type du inport soit plus général que celui du outport + if ( t1->is_a(t2->id()) ) return 1; + } + return 0; + } + + int isAdaptableCorbaPyObjectSequence(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Sequence) + { + if(isAdaptableCorbaPyObject(t1->content_type(),t2->content_type())) + { + return 1; + } + } + return 0; + } + + isAdaptableCorbaPyObjectFn isAdaptableCorbaPyObjectFns[]= + { + isAdaptableCorbaPyObjectNull, + isAdaptableCorbaPyObjectDouble, + isAdaptableCorbaPyObjectInt, + isAdaptableCorbaPyObjectString, + isAdaptableCorbaPyObjectNull, + isAdaptableCorbaPyObjectObjref, + isAdaptableCorbaPyObjectSequence, + }; + + int isAdaptableCorbaPyObject(TypeCode *t1,TypeCode *t2) + { + int tk=t2->kind(); + return isAdaptableCorbaPyObjectFns[tk](t1,t2); + } + + /* + * Fin des fonctions d'adaptation pour conversion PyObject * -> CORBA::Any * + */ + + /* + * Fonctions de test d'adaptation pour conversion CORBA::Any * (t1) -> Xml::char * (t2) + */ + //t1 est le type du port output Corba + //t2 est le type du port input Xml + + int isAdaptableXmlCorbaNull(TypeCode *t1,TypeCode* t2) + { + return 0; + } + + int isAdaptableXmlCorbaDouble(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Double)return 1; + if(t1->kind() == Int)return 1; + return 0; + } + + int isAdaptableXmlCorbaInt(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Int)return 1; + return 0; + } + + int isAdaptableXmlCorbaString(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == String)return 1; + return 0; + } + + int isAdaptableXmlCorbaObjref(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Objref) + { + //Il faut que le type du inport soit plus général que celui du outport + if( t1->is_a(t2->id()) )return 1; + } + return 0; + } + + int isAdaptableXmlCorbaSequence(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Sequence) + { + if(isAdaptableXmlCorba(t1->content_type(),t2->content_type())) + { + return 1; + } + } + return 0; + } + + isAdaptableXmlCorbaFn isAdaptableXmlCorbaFns[]= + { + isAdaptableXmlCorbaNull, + isAdaptableXmlCorbaDouble, + isAdaptableXmlCorbaInt, + isAdaptableXmlCorbaString, + isAdaptableXmlCorbaNull, + isAdaptableXmlCorbaObjref, + isAdaptableXmlCorbaSequence, + }; + + int isAdaptableXmlCorba(TypeCode *t1,TypeCode *t2) + { + int tk=t2->kind(); + return isAdaptableXmlCorbaFns[tk](t1,t2); + } + + /* + * Fin des fonctions d'adaptation pour conversion CORBA::Any * (t1) -> Xml::char * (t2) + */ + + /* + * Fonctions de test d'adaptation pour conversion CORBA::Any * (t1) -> CORBA::Any * (t2) + */ + //t1 est le type du port output Corba + //t2 est le type du port input Corba + + int isAdaptableCorbaCorbaNull(TypeCode *t1,TypeCode* t2) + { + return 0; + } + + int isAdaptableCorbaCorbaDouble(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Double)return 1; + if(t1->kind() == Int)return 1; + return 0; + } + + int isAdaptableCorbaCorbaInt(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Int)return 1; + return 0; + } + + int isAdaptableCorbaCorbaString(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == String)return 1; + return 0; + } + + int isAdaptableCorbaCorbaObjref(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Objref){ + //Il faut que le type du inport soit plus général que celui du outport + if( t1->is_a(t2->id()) )return 1; + } + return 0; + } + + int isAdaptableCorbaCorbaSequence(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Sequence) + { + if(isAdaptableCorbaCorba(t1->content_type(),t2->content_type())) + { + return 1; + } + } + return 0; + } + + isAdaptableCorbaCorbaFn isAdaptableCorbaCorbaFns[]= + { + isAdaptableCorbaCorbaNull, + isAdaptableCorbaCorbaDouble, + isAdaptableCorbaCorbaInt, + isAdaptableCorbaCorbaString, + isAdaptableCorbaCorbaNull, + isAdaptableCorbaCorbaObjref, + isAdaptableCorbaCorbaSequence, + }; + + int isAdaptableCorbaCorba(TypeCode *t1,TypeCode *t2) + { + int tk=t2->kind(); + return isAdaptableCorbaCorbaFns[tk](t1,t2); + } + + /* + * Fin des fonctions d'adaptation pour conversion CORBA::Any * -> CORBA::Any * + */ + + /* + * Fonctions de test d'adaptation pour conversion PyObject * (t1) -> PyObject * (t2) + */ + //t1 est le type du port output Python + //t2 est le type du port input Python + + int isAdaptablePyObjectPyObjectNull(TypeCode *t1,TypeCode* t2) + { + return 0; + } + + int isAdaptablePyObjectPyObjectDouble(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Double)return 1; + if(t1->kind() == Int)return 1; + return 0; + } + + int isAdaptablePyObjectPyObjectInt(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Int)return 1; + return 0; + } + + int isAdaptablePyObjectPyObjectString(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == String)return 1; + return 0; + } + + int isAdaptablePyObjectPyObjectObjref(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Objref) + { + //Il faut que le type du inport soit plus général que celui du outport + if( t1->is_a(t2->id()) )return 1; + } + return 0; + } + + int isAdaptablePyObjectPyObjectSequence(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Sequence) + { + if(isAdaptablePyObjectPyObject(t1->content_type(),t2->content_type())) + { + return 1; + } + } + return 0; + } + + isAdaptablePyObjectPyObjectFn isAdaptablePyObjectPyObjectFns[]= + { + isAdaptablePyObjectPyObjectNull, + isAdaptablePyObjectPyObjectDouble, + isAdaptablePyObjectPyObjectInt, + isAdaptablePyObjectPyObjectString, + isAdaptablePyObjectPyObjectNull, + isAdaptablePyObjectPyObjectObjref, + isAdaptablePyObjectPyObjectSequence, + }; + + int isAdaptablePyObjectPyObject(TypeCode *t1,TypeCode *t2) + { + int tk=t2->kind(); + return isAdaptablePyObjectPyObjectFns[tk](t1,t2); + } + + /* + * Fin des fonctions d'adaptation pour conversion PyObject * -> PyObject * + */ + + /* + * Fonctions de test d'adaptation pour conversion CORBA::Any * (t1) -> PyObject * (t2) + */ + //t1 est le type du port output Corba + //t2 est le type du port input Python + + int isAdaptablePyObjectCorbaNull(TypeCode *t1,TypeCode* t2) + { + return 0; + } + + //on peut convertir un double ou un int en CORBA double + int isAdaptablePyObjectCorbaDouble(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Double)return 1; + if(t1->kind() == Int)return 1; + return 0; + } + + int isAdaptablePyObjectCorbaInt(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Int)return 1; + return 0; + } + + int isAdaptablePyObjectCorbaString(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == String)return 1; + return 0; + } + + int isAdaptablePyObjectCorbaObjref(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Objref){ + //Il faut que le type du inport soit plus général que celui du outport + if( t1->is_a(t2->id()) )return 1; + } + return 0; + } + + int isAdaptablePyObjectCorbaSequence(TypeCode *t1,TypeCode* t2) + { + if(t1->kind() == Sequence) + { + if(isAdaptablePyObjectCorba(t1->content_type(),t2->content_type())) + { + return 1; + } + } + return 0; + } + + isAdaptablePyObjectCorbaFn isAdaptablePyObjectCorbaFns[]={ + isAdaptablePyObjectCorbaNull, + isAdaptablePyObjectCorbaDouble, + isAdaptablePyObjectCorbaInt, + isAdaptablePyObjectCorbaString, + isAdaptablePyObjectCorbaNull, + isAdaptablePyObjectCorbaObjref, + isAdaptablePyObjectCorbaSequence, + }; + + int isAdaptablePyObjectCorba(TypeCode *t1,TypeCode *t2) + { + int tk=t2->kind(); + return isAdaptablePyObjectCorbaFns[tk](t1,t2); + } + + /* + * Fin des fonctions d'adaptation pour conversion CORBA::Any * -> PyObject * + */ + + /* + * Fonctions de conversion CORBA::Any * -> PyObject * + */ + //Le TypeCode t est celui vers lequel on convertit (celui de l'InputPort) + //On a le type Corba de l'objet sortant par ob->type() + + PyObject *convertPyObjectCorbaNull(TypeCode *t,CORBA::Any *ob) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + + //kind=1 + //Convertit un CORBA::Any "equivalent double" en Python double + + PyObject *convertPyObjectCorbaDouble(TypeCode *t,CORBA::Any *ob) + { + CORBA::TypeCode_var tc = ob->type(); + if (tc->equivalent(CORBA::_tc_double)) + { + CORBA::Double d; + *ob >>= d; + PyObject *pyob=PyFloat_FromDouble(d); + cerr << "pyob refcnt: " << pyob->ob_refcnt << endl; + return pyob; + } + if (tc->equivalent(CORBA::_tc_long)) + { + CORBA::Long d; + *ob >>= d; + //Faudrait-il convertir en PyFloat ?? + PyObject *pyob=PyInt_FromLong(d); + cerr << "pyob refcnt: " << pyob->ob_refcnt << endl; + return pyob; + } + stringstream msg; + msg << "Internal error " ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + + PyObject *convertPyObjectCorbaInt(TypeCode *t,CORBA::Any *ob) + { + CORBA::Long l; + *ob >>= l; + return PyInt_FromLong(l); + } + + PyObject *convertPyObjectCorbaString(TypeCode *t,CORBA::Any *ob) + { + char *s; + *ob >>=s; + PyObject *pyob=PyString_FromString(s); + cerr << "pyob refcnt: " << pyob->ob_refcnt << endl; + return pyob; + } + + PyObject *convertPyObjectCorbaObjref(TypeCode *t,CORBA::Any *ob) + { + CORBA::Object_ptr ObjRef ; + *ob >>= (CORBA::Any::to_object ) ObjRef ; + //hold_lock is true: caller is supposed to hold the GIL. + //omniorb will not take the GIL + PyObject *pyob = getSALOMERuntime()->getApi()->cxxObjRefToPyObjRef(ObjRef, 1); + cerr << "pyob refcnt: " << pyob->ob_refcnt << endl; + return pyob; + } + + PyObject *convertPyObjectCorbaSequence(TypeCode *t,CORBA::Any *ob) + { + cerr << "convertPyObjectCorbaSequence" << endl; + DynamicAny::DynAny_var dynany= getSALOMERuntime()->getDynFactory()->create_dyn_any(*ob); + DynamicAny::DynSequence_var ds=DynamicAny::DynSequence::_narrow(dynany); + DynamicAny::AnySeq_var as=ds->get_elements(); + int len=as->length(); + PyObject *pyob = PyList_New(len); + for(int i=0;icontent_type(),&as[i]); + cerr << "e refcnt: " << e->ob_refcnt << endl; + PyList_SetItem(pyob,i,e); + cerr << "e refcnt: " << e->ob_refcnt << endl; + } + cerr << "pyob refcnt: " << pyob->ob_refcnt << endl; + cerr << "Sequence= "; + PyObject_Print(pyob,stdout,Py_PRINT_RAW); + cerr << endl; + return pyob; + } + + + convertPyObjectCorbaFn convertPyObjectCorbaFns[]= + { + convertPyObjectCorbaNull, + convertPyObjectCorbaDouble, + convertPyObjectCorbaInt, + convertPyObjectCorbaString, + convertPyObjectCorbaNull, + convertPyObjectCorbaObjref, + convertPyObjectCorbaSequence, + }; + + PyObject *convertPyObjectCorba(TypeCode *t,CORBA::Any *ob) + { + int tk=t->kind(); + return convertPyObjectCorbaFns[tk](t,ob); + } + + /* + * Fin des fonctions de conversion CORBA::Any * -> PyObject * + */ + + /* + * Fonctions de conversion CORBA::Any * -> Xml char * + */ + //Le TypeCode t est celui vers lequel on convertit (celui de l'InputPort) + //On a le type Corba de l'objet sortant par ob->type() + + char *convertXmlCorbaNull(TypeCode *t,CORBA::Any *ob) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + + //kind=1 + //Convertit un CORBA::Any "equivalent double" en Python double + + char *convertXmlCorbaDouble(TypeCode *t,CORBA::Any *ob) + { + CORBA::TypeCode_var tc = ob->type(); + if (tc->equivalent(CORBA::_tc_double)) + { + CORBA::Double d; + *ob >>= d; + stringstream msg ; + msg << "" << d << "\n"; + return (char *)msg.str().c_str(); + } + if (tc->equivalent(CORBA::_tc_long)) + { + CORBA::Long d; + *ob >>= d; + stringstream msg; + msg << "" << d << "\n"; + return (char *)msg.str().c_str(); + } + stringstream msg; + msg << "Internal error " ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + + char *convertXmlCorbaInt(TypeCode *t,CORBA::Any *ob) + { + CORBA::Long l; + *ob >>= l; + stringstream msg ; + msg << "" << l << "\n"; + return (char *)msg.str().c_str(); + } + + char *convertXmlCorbaString(TypeCode *t,CORBA::Any *ob) + { + char *s; + *ob >>=s; + stringstream msg ; + msg << "" << s << "\n"; + return (char *)msg.str().c_str(); + } + + char *convertXmlCorbaObjref(TypeCode *t,CORBA::Any *ob) + { + CORBA::Object_ptr ObjRef ; + *ob >>= (CORBA::Any::to_object ) ObjRef ; + stringstream msg ; + msg << "" << getSALOMERuntime()->getOrb()->object_to_string(ObjRef) << "\n"; + return (char *)msg.str().c_str(); + } + + char *convertXmlCorbaSequence(TypeCode *t,CORBA::Any *ob) + { + cerr << "convertXmlCorbaSequence" << endl; + DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any(*ob); + DynamicAny::DynSequence_var ds=DynamicAny::DynSequence::_narrow(dynany); + DynamicAny::AnySeq_var as=ds->get_elements(); + int len=as->length(); + stringstream xmlob; + xmlob << "\n"; + for(int i=0;icontent_type(),&as[i]); + } + xmlob << "\n"; + cerr << "Sequence= "; + cerr << xmlob; + cerr << endl; + return (char *)xmlob.str().c_str(); + } + + convertXmlCorbaFn convertXmlCorbaFns[]= + { + convertXmlCorbaNull, + convertXmlCorbaDouble, + convertXmlCorbaInt, + convertXmlCorbaString, + convertXmlCorbaNull, + convertXmlCorbaObjref, + convertXmlCorbaSequence, + }; + + char *convertXmlCorba(TypeCode *t,CORBA::Any *ob) + { + int tk=t->kind(); + return convertXmlCorbaFns[tk](t,ob); + } + + /* + * Fin des fonctions de conversion CORBA::Any * -> Xml char * + */ + + /* + * Fonctions de conversion CORBA::Any * -> CORBA::Any * + */ + //Le TypeCode t est celui vers lequel on convertit (celui de l'InputPort) + //On a le type Corba de l'objet sortant par ob->type() + + CORBA::Any *convertCorbaCorbaNull(TypeCode *t,CORBA::Any *ob) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + }; + + //kind=1 + //Convertit un CORBA::Any "equivalent double" en Python double + + CORBA::Any *convertCorbaCorbaDouble(TypeCode *t,CORBA::Any *ob) + { + CORBA::TypeCode_var tc = ob->type(); + if (tc->equivalent(CORBA::_tc_double)) + { + return ob; + } + if (tc->equivalent(CORBA::_tc_long)) + { + CORBA::Long d; + *ob >>= d; + CORBA::Any *any = new CORBA::Any(); + *any <<= (CORBA::Double)d; + return any; + } + stringstream msg; + msg << "Internal error " ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + + CORBA::Any *convertCorbaCorbaInt(TypeCode *t,CORBA::Any *ob) + { + return ob; + } + + CORBA::Any *convertCorbaCorbaString(TypeCode *t,CORBA::Any *ob) + { + return ob; + } + + CORBA::Any *convertCorbaCorbaObjref(TypeCode *t,CORBA::Any *ob) + { + return ob; + } + + CORBA::Any *convertCorbaCorbaSequence(TypeCode *t,CORBA::Any *ob) + { + cerr << "convertCorbaCorbaSequence" << endl; + DynamicAny::DynAny_var dynany= getSALOMERuntime()->getDynFactory()->create_dyn_any(*ob); + DynamicAny::DynSequence_var ds=DynamicAny::DynSequence::_narrow(dynany); + DynamicAny::AnySeq_var as=ds->get_elements(); + int length=as->length(); + CORBA::TypeCode_var tc_content; + DynamicAny::AnySeq asout ; + asout.length(length); + for(int i=0;icontent_type(),&as[i]); + //ici on fait une copie. Peut-on l'éviter ? + asout[i]=*a; + tc_content=a->type(); + //delete a; + } + CORBA::TypeCode_var tc= getSALOMERuntime()->getOrb()->create_sequence_tc(0,tc_content); + DynamicAny::DynAny_var dynanyout=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc); + DynamicAny::DynSequence_var dsout=DynamicAny::DynSequence::_narrow(dynanyout); + try + { + dsout->set_elements(asout); + } + catch(DynamicAny::DynAny::TypeMismatch& ex) + { + throw YACS::Exception("type mismatch"); + } + catch(DynamicAny::DynAny::InvalidValue& ex) + { + throw YACS::Exception("invalid value"); + } + CORBA::Any *any=dsout->to_any(); + return any; + } + + + convertCorbaCorbaFn convertCorbaCorbaFns[]= + { + convertCorbaCorbaNull, + convertCorbaCorbaDouble, + convertCorbaCorbaInt, + convertCorbaCorbaString, + convertCorbaCorbaNull, + convertCorbaCorbaObjref, + convertCorbaCorbaSequence, + }; + + CORBA::Any *convertCorbaCorba(TypeCode *t,CORBA::Any *ob) + { + int tk=t->kind(); + return convertCorbaCorbaFns[tk](t,ob); + } + + /* + * Fin des fonctions de conversion CORBA::Any * -> PyObject * + */ + + /* + * Fonctions de conversion Xml char * -> CORBA::Any * + */ + + //Le TypeCode t est celui vers lequel on convertit (celui de l'InputPort) + + CORBA::Any *convertCorbaXmlNull(TypeCode *t, xmlDocPtr doc, xmlNodePtr cur) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + + CORBA::Any *convertCorbaXmlDouble(TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) + { + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"double"))) + { + //on attend un double, on a bien un double + xmlChar * s = NULL; + s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + CORBA::Any *any = new CORBA::Any(); + cerr << "convertCorbaXmlDouble " << (const char *)s << endl; + *any <<= (CORBA::Double)atof((const char *)s); + xmlFree(s); + return any; + } + else if ((!xmlStrcmp(cur->name, (const xmlChar *)"int"))) + { + //on attend un double, on a un int + xmlChar * s = NULL; + s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + CORBA::Any *any = new CORBA::Any(); + cerr << "convertCorbaXmlDouble " << (const char *)s << endl; + *any <<= (CORBA::Double)atof((const char *)s); + xmlFree(s); + return any; + } + cur = cur->next; + } + stringstream msg; + msg << "Problem in conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + + CORBA::Any *convertCorbaXmlSequence(TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) + { + CORBA::TypeCode_var tc_content; + DynamicAny::AnySeq as ; + int len=0; + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"array"))) + { + cerr << "parse sequence " << endl; + xmlNodePtr cur1=cur->xmlChildrenNode; + while (cur1 != NULL) + { + if ((!xmlStrcmp(cur1->name, (const xmlChar *)"data"))) + { + cerr << "parse data " << endl; + xmlNodePtr cur2=cur1->xmlChildrenNode; + while (cur2 != NULL) + { + //on recupere toutes les values + if ((!xmlStrcmp(cur2->name, (const xmlChar *)"value"))) + { + cerr << "parse value " << endl; + CORBA::Any *a=convertCorbaXml(t->content_type(),doc,cur2); + as.length(len+1); + as[len++]=*a; + tc_content=a->type(); + } + cur2 = cur2->next; + } // end while value + break; + } + cur1 = cur1->next; + } // end while data + break; + } + cur = cur->next; + } // end while array + + CORBA::TypeCode_var tc=getSALOMERuntime()->getOrb()->create_sequence_tc(0,tc_content); + DynamicAny::DynAny_var dynanyout=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc); + DynamicAny::DynSequence_var dsout=DynamicAny::DynSequence::_narrow(dynanyout); + try + { + dsout->set_elements(as); + } + catch(DynamicAny::DynAny::TypeMismatch& ex) + { + throw YACS::Exception("type mismatch"); + } + catch(DynamicAny::DynAny::InvalidValue& ex) + { + throw YACS::Exception("invalid value"); + } + CORBA::Any *any=dsout->to_any(); + return any; + } + + convertCorbaXmlFn convertCorbaXmlFns[]= + { + convertCorbaXmlNull, + convertCorbaXmlDouble, + convertCorbaXmlNull, + convertCorbaXmlNull, + convertCorbaXmlNull, + convertCorbaXmlNull, + convertCorbaXmlSequence, + }; + + CORBA::Any *convertCorbaXml(TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) + { + int tk=t->kind(); + return convertCorbaXmlFns[tk](t,doc,cur); + } + + /* + * Fin des fonctions de conversion Xml char * -> CORBA::Any * + */ + + } +} diff --git a/src/runtime/TypeConversions.hxx b/src/runtime/TypeConversions.hxx new file mode 100644 index 000000000..a26496594 --- /dev/null +++ b/src/runtime/TypeConversions.hxx @@ -0,0 +1,53 @@ + +#ifndef _TYPECONVERSIONS_HXX_ +#define _TYPECONVERSIONS_HXX_ + +#include +#include +#include + +#include "TypeCode.hxx" + +namespace YACS +{ + namespace ENGINE + { + + typedef CORBA::TypeCode_ptr (*getCorbaTCFn)(TypeCode *); + CORBA::TypeCode_ptr getCorbaTC(TypeCode *t); + + typedef CORBA::Any* (*convertCorbaPyObjectFn)(TypeCode *,PyObject* ); + CORBA::Any *convertCorbaPyObject(TypeCode *t,PyObject *ob); + + typedef int (*isAdaptableCorbaPyObjectFn)(TypeCode *,TypeCode* ); + int isAdaptableCorbaPyObject(TypeCode* t1,TypeCode* t2); + + typedef int (*isAdaptableXmlCorbaFn)(TypeCode *,TypeCode* ); + int isAdaptableXmlCorba(TypeCode *t1,TypeCode *t2); + + typedef int (*isAdaptableCorbaCorbaFn)(TypeCode *,TypeCode* ); + int isAdaptableCorbaCorba(TypeCode* t1,TypeCode* t2); + + typedef int (*isAdaptablePyObjectPyObjectFn)(TypeCode *,TypeCode* ); + int isAdaptablePyObjectPyObject(TypeCode* t1,TypeCode* t2); + + typedef int (*isAdaptablePyObjectCorbaFn)(TypeCode *,TypeCode* ); + int isAdaptablePyObjectCorba(TypeCode* t1,TypeCode* t2); + + typedef PyObject* (*convertPyObjectCorbaFn)(TypeCode *,CORBA::Any* ); + PyObject *convertPyObjectCorba(TypeCode* t,CORBA::Any* ob); + + typedef char* (*convertXmlCorbaFn)(TypeCode *,CORBA::Any* ); + char *convertXmlCorba(TypeCode* t,CORBA::Any* ob); + + typedef CORBA::Any* (*convertCorbaCorbaFn)(TypeCode *,CORBA::Any* ); + CORBA::Any *convertCorbaCorba(TypeCode* t,CORBA::Any* ob); + + typedef CORBA::Any* (*convertCorbaXmlFn)(TypeCode *,xmlDocPtr doc,xmlNodePtr cur); + CORBA::Any *convertCorbaXml(TypeCode* t,xmlDocPtr doc,xmlNodePtr cur ); + + } + +} + +#endif diff --git a/src/runtime/XMLCORBAConv.cxx b/src/runtime/XMLCORBAConv.cxx new file mode 100644 index 000000000..41116c793 --- /dev/null +++ b/src/runtime/XMLCORBAConv.cxx @@ -0,0 +1,51 @@ + +#include "XMLCORBAConv.hxx" +#include "CORBAXMLConv.hxx" +#include "TypeConversions.hxx" + +#include +#include + +using namespace YACS::ENGINE; +using namespace std; + +XmlCorba::XmlCorba(InputCorbaPort* p) + : ProxyPort(p), Port(p->getNode()) +{ + cerr << "proxy port from XML to CORBA" << endl; +} + +void XmlCorba::put(const void *data) throw(ConversionException) +{ + cerr << " XmlCorba::put(const void *data)" << endl; + put((const char *)data); +} + +//!Convertit la valeur XML (char *) recue en CORBA::Any et la transmet au proxy port + /*! + * \param data : Xml::char * + */ + +void XmlCorba::put(const char *data) throw(ConversionException) +{ + cerr << "XmlCorba::put " << data << endl; + xmlDocPtr doc; + xmlNodePtr cur; + CORBA::Any *a; + + doc = xmlParseMemory(data, strlen(data)); + cur = xmlDocGetRootElement(doc); + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"value"))) + { + a=convertCorbaXml(type(),doc,cur); + break; + } + cur = cur->next; + } + xmlFreeDoc(doc); + xmlCleanupParser(); + _port->put(a); + cerr << "Fin XmlCorba" << endl; +} diff --git a/src/runtime/XMLCORBAConv.hxx b/src/runtime/XMLCORBAConv.hxx new file mode 100644 index 000000000..b909c78f7 --- /dev/null +++ b/src/runtime/XMLCORBAConv.hxx @@ -0,0 +1,22 @@ +#ifndef __XMLCORBACONV_HXX__ +#define __XMLCORBACONV_HXX__ + +#include "CORBAPorts.hxx" + +namespace YACS +{ + namespace ENGINE + { + //Ports adaptateurs Xml->Corba pour les différents types + + class XmlCorba : public ProxyPort + { + public: + XmlCorba(InputCorbaPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(const char *data) throw(ConversionException); + }; + } +} + +#endif diff --git a/src/runtime/XMLNode.cxx b/src/runtime/XMLNode.cxx new file mode 100644 index 000000000..c0f3215f6 --- /dev/null +++ b/src/runtime/XMLNode.cxx @@ -0,0 +1,39 @@ + +#include "XMLNode.hxx" +#include "XMLPorts.hxx" + +#include + +using namespace YACS::ENGINE; +using namespace std; + +XmlNode::XmlNode(const string& name) + : ElementaryNode(name) +{ + _implementation="XML"; + cerr << "XMLNode::XMLNode " << name << endl; +} + +void XmlNode::set_script(const string& script) +{ + _script=script; +} + +void XmlNode::execute() +{ + cerr << "XmlNode::run" << endl; + cerr << "---------------XmlNode::inputs---------------" << endl; + set::iterator iter; + for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++) + { + InputXmlPort *p=(InputXmlPort *)*iter; + cerr << "port name: " << p->getName() << endl; + cerr << "port kind: " << p->type()->kind() << endl; + const char* ob=p->getXml(); + cerr << "Xml: " << ob << endl; + getOutputPort(p->getName())->put(ob); // obligation meme ports en entree et sortie + } + cerr << "--------------XmlNode::calculation-----------" << _script << endl; +} + + diff --git a/src/runtime/XMLNode.hxx b/src/runtime/XMLNode.hxx new file mode 100644 index 000000000..4e35aa38d --- /dev/null +++ b/src/runtime/XMLNode.hxx @@ -0,0 +1,26 @@ + +#ifndef _XMLNODE_HXX_ +#define _XMLNODE_HXX_ + +#include "ElementaryNode.hxx" + +namespace YACS +{ + namespace ENGINE + { + + class XmlNode:public ENGINE::ElementaryNode + { + public: + XmlNode(const std::string& name); + virtual void execute(); + virtual void set_script(const std::string& script); + protected: + std::string _script; + }; + + + } +} + +#endif diff --git a/src/runtime/XMLPorts.cxx b/src/runtime/XMLPorts.cxx new file mode 100644 index 000000000..de4da977d --- /dev/null +++ b/src/runtime/XMLPorts.cxx @@ -0,0 +1,63 @@ + +#include "XMLPorts.hxx" + +#include + +using namespace YACS::ENGINE; +using namespace std; + +InputXmlPort::InputXmlPort(const string& name, Node * node, TypeCode * type) + : InputPort(name, node, type), Port(node) +{ + _impl="XML"; +} + +const char * InputXmlPort::getXml() const +{ + return _data.c_str(); +} + +void InputXmlPort::put(const void *data) throw (ConversionException) +{ + put((const char*)data); + _empty = false; +} + +void InputXmlPort::put(const char *data) throw (ConversionException) +{ + cerr << "InputXmlPort::put" << endl; + _data = data; + cerr << "data: " << data << endl; +} + + + +OutputXmlPort::OutputXmlPort(const string& name, Node* node, TypeCode * type) + : OutputPort(name, node, type), Port(node) +{ + _impl="XML"; +} + +const char * OutputXmlPort::get() const throw (ConversionException) +{ + return _data.c_str(); +} + +void OutputXmlPort::put(const void *data) throw (ConversionException) +{ + put((const char*)data); +} + +void OutputXmlPort::put(const char *data) throw (ConversionException) +{ + cerr << "OutputXmlPort::put-------" << getName() << endl; + InputPort *p; + cerr << "data: " << data << endl; + _data=data; + set::iterator iter; + for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + { + p=*iter; + p->put((void*)data); + } +} diff --git a/src/runtime/XMLPorts.hxx b/src/runtime/XMLPorts.hxx new file mode 100644 index 000000000..1a16cb7e6 --- /dev/null +++ b/src/runtime/XMLPorts.hxx @@ -0,0 +1,37 @@ + +#ifndef _XMLPORTS_HXX_ +#define _XMLPORTS_HXX_ + +#include "InputPort.hxx" +#include "OutputPort.hxx" + +namespace YACS +{ + namespace ENGINE + { + class InputXmlPort : public InputPort + { + public: + InputXmlPort(const std::string& name, Node* node, TypeCode * type); + virtual void put(const void *data) throw (ConversionException); + void put(const char *data) throw (ConversionException); + virtual const char * getXml() const; + protected: + std::string _data; + }; + + class OutputXmlPort : public OutputPort + { + public: + OutputXmlPort(const std::string& name, Node* node, TypeCode * type); + virtual void put(const void *data) throw (ConversionException); + void put(const char *data) throw (ConversionException); + virtual const char * get() const throw (ConversionException); + protected: + std::string _data; + }; + + } +} + +#endif -- 2.39.2