From a84e60a749da66dffb73297fa5082b70b9d62f7d Mon Sep 17 00:00:00 2001 From: prascle Date: Fri, 5 Oct 2007 15:21:21 +0000 Subject: [PATCH] copy tag mergefrom_BR_V0_1_CC_Salome_04oct07 --- Demo/Makefile.am | 17 + Demo/echo.idl | 73 + Demo/echoSrv.cxx | 445 +++ Demo/schema_orig.xml | 79 + Demo/xmlrpcprog_orig.py | 38 + INSTALL | 26 +- Makefile.am | 14 +- Misc/valgrind-python.supp | 216 ++ README | 48 +- adm/unix/config_files/ac_cxx_option.m4 | 46 + adm/unix/config_files/ac_linker_options.m4 | 57 + adm/unix/config_files/ac_pkg_swig.m4 | 2 + adm/unix/config_files/ac_prog_esope.m4 | 50 - adm/unix/config_files/ac_python_devel.m4 | 11 + adm/unix/config_files/check_SALOME.m4 | 349 ++ adm/unix/config_files/check_cas.m4 | 238 ++ adm/unix/config_files/check_expat.m4 | 20 + adm/unix/config_files/check_htmlgen.m4 | 112 + adm/unix/config_files/check_libxml.m4 | 41 + adm/unix/config_files/check_msg2qm.m4 | 57 + adm/unix/config_files/check_omniorb.m4 | 104 +- adm/unix/config_files/check_opengl.m4 | 195 ++ adm/unix/config_files/check_qt.m4 | 78 +- adm/unix/config_files/check_salome.m4 | 75 + adm/unix/config_files/production.m4 | 2 +- adm/unix/make_begin.am | 30 + adm/unix/make_end.am | 62 +- adm/unix/make_gui_begin.am | 7 + build_configure | 39 +- configure.in.base | 115 +- doc/Doxyfile.in | 282 ++ doc/Makefile.am | 12 + doc/bases.dox | 14 + doc/engine.dox | 222 ++ doc/python.dox | 31 + doc/runtime.dox | 40 + doc/schema.jpeg | Bin 0 -> 17860 bytes doc/yacs.dox | 102 + doc/yacsloader.dox | 641 ++++ idl/Makefile.am | 23 + idl/yacsgui.idl | 52 + root_clean | 2 + src/Makefile.am | 7 +- src/bases/Cstr2d.cxx | 27 + src/bases/Cstr2d.hxx | 7 + src/bases/DrivenCondition.cxx | 7 + src/bases/DrivenCondition.hxx | 35 + src/bases/DrivenConditionPT.cxx | 42 + src/bases/DrivenConditionPT.hxx | 29 + src/bases/DynLibLoader.cxx | 7 + src/bases/DynLibLoader.hxx | 38 + src/bases/DynLibLoaderGNU.cxx | 109 + src/bases/DynLibLoaderGNU.hxx | 36 + src/bases/DynLibLoaderWin.cxx | 78 + src/bases/DynLibLoaderWin.hxx | 31 + src/bases/Exception.hxx | 2 +- src/bases/Makefile.am | 22 + src/bases/Mutex.hxx | 29 +- src/bases/MutexPT.cxx | 31 +- src/bases/MutexPT.hxx | 15 + src/bases/Test/BasicMainTest.hxx | 12 +- src/bases/Test/DLTest.cxx | 4 + src/bases/Test/InitTests.cxx | 15 + src/bases/Test/Makefile.am | 14 +- src/bases/Test/TestBases.cxx | 2 + src/bases/Test/UnitTestsResult.hxx | 20 + src/bases/Test/basesTest.cxx | 119 +- src/bases/Test/basesTest.hxx | 21 +- src/bases/ThreadPT.cxx | 16 +- src/bases/ThreadPT.hxx | 2 + src/bases/YacsTrace.cxx | 15 + src/bases/YacsTrace.hxx | 12 + src/bases/define.hxx | 41 +- src/bases/yacsconfig.h | 13 + src/engine/Any.cxx | 764 +++++ src/engine/Any.hxx | 254 ++ src/engine/AnyInputPort.cxx | 116 + src/engine/AnyInputPort.hxx | 33 + src/engine/Bloc.cxx | 639 +++- src/engine/Bloc.hxx | 216 +- src/engine/ComponentInstance.cxx | 76 + src/engine/ComponentInstance.hxx | 72 + src/engine/ComposedNode.cxx | 1139 ++++++- src/engine/ComposedNode.hxx | 126 +- src/engine/ConditionInputPort.cxx | 106 + src/engine/ConditionInputPort.hxx | 37 + src/engine/Container.cxx | 54 + src/engine/Container.hxx | 45 + src/engine/ConversionException.cxx | 4 + src/engine/ConversionException.hxx | 1 + src/engine/DataFlowPort.cxx | 18 +- src/engine/DataFlowPort.hxx | 14 +- src/engine/DataPort.cxx | 51 + src/engine/DataPort.hxx | 34 + src/engine/DataStreamPort.cxx | 30 +- src/engine/DataStreamPort.hxx | 18 +- src/engine/DeploymentTree.cxx | 446 +++ src/engine/DeploymentTree.hxx | 85 + src/engine/Dispatcher.cxx | 77 + src/engine/Dispatcher.hxx | 69 + src/engine/DynParaLoop.cxx | 389 +++ src/engine/DynParaLoop.hxx | 97 + src/engine/ElementaryNode.cxx | 301 +- src/engine/ElementaryNode.hxx | 139 +- src/engine/Executor.cxx | 1031 +++++- src/engine/Executor.hxx | 62 +- src/engine/ExecutorSwig.cxx | 47 + src/engine/ExecutorSwig.hxx | 22 + src/engine/ForEachLoop.cxx | 700 ++++ src/engine/ForEachLoop.hxx | 165 + src/engine/ForLoop.cxx | 132 + src/engine/ForLoop.hxx | 41 + src/engine/InGate.cxx | 79 +- src/engine/InGate.hxx | 27 +- src/engine/InPort.cxx | 56 +- src/engine/InPort.hxx | 47 +- src/engine/InlineNode.cxx | 21 + src/engine/InlineNode.hxx | 81 + src/engine/InputDataStreamPort.cxx | 26 +- src/engine/InputDataStreamPort.hxx | 10 +- src/engine/InputPort.cxx | 181 +- src/engine/InputPort.hxx | 101 +- src/engine/InvalidExtractionException.cxx | 13 + src/engine/InvalidExtractionException.hxx | 23 + src/engine/LinkInfo.cxx | 358 ++ src/engine/LinkInfo.hxx | 108 + src/engine/Loop.cxx | 561 ++- src/engine/Loop.hxx | 118 +- src/engine/Makefile.am | 155 +- src/engine/Node.cxx | 368 +- src/engine/Node.hxx | 195 +- src/engine/OptimizerAlg.cxx | 37 + src/engine/OptimizerAlg.hxx | 81 + src/engine/OptimizerLoop.cxx | 549 +++ src/engine/OptimizerLoop.hxx | 118 + src/engine/OutGate.cxx | 88 +- src/engine/OutGate.hxx | 10 +- src/engine/OutPort.cxx | 65 +- src/engine/OutPort.hxx | 18 +- src/engine/OutputDataStreamPort.cxx | 116 +- src/engine/OutputDataStreamPort.hxx | 21 +- src/engine/OutputPort.cxx | 166 +- src/engine/OutputPort.hxx | 52 +- src/engine/Plugin/Makefile.am | 15 + src/engine/Plugin/PluginSimplex.cxx | 97 + src/engine/Plugin/PluginSimplex.hxx | 49 + src/engine/Plugin/SConscript | 17 + src/engine/Plugin/aleas.cxx | 158 + src/engine/Plugin/aleas.hxx | 66 + src/engine/Plugin/critere.hxx | 32 + src/engine/Plugin/decode.cxx | 79 + src/engine/Plugin/decode.hxx | 45 + src/engine/Plugin/distrib.hxx | 34 + src/engine/Plugin/fonction.hxx | 30 + src/engine/Plugin/local.cxx | 58 + src/engine/Plugin/local.hxx | 42 + src/engine/Plugin/maestro.cxx | 51 + src/engine/Plugin/maestro.hxx | 41 + src/engine/Plugin/mt19937ar.cxx | 192 ++ src/engine/Plugin/point.cxx | 238 ++ src/engine/Plugin/point.hxx | 49 + src/engine/Plugin/saclass.cxx | 106 + src/engine/Plugin/saclass.hxx | 59 + src/engine/Plugin/saconst.h | 60 + src/engine/Plugin/saemul.cxx | 123 + src/engine/Plugin/saemul.hxx | 48 + src/engine/Plugin/salomesup.hxx | 33 + src/engine/Plugin/salomevent.cxx | 53 + src/engine/Plugin/salomevent.hxx | 38 + src/engine/Plugin/sasimpl.cxx | 86 + src/engine/Plugin/sasimpl.hxx | 52 + src/engine/Plugin/satest.cxx | 26 + src/engine/Plugin/simplex.cxx | 152 + src/engine/Plugin/simplex.hxx | 50 + src/engine/Plugin/solution.cxx | 46 + src/engine/Plugin/solution.hxx | 34 + src/engine/Pool.cxx | 194 ++ src/engine/Pool.hxx | 64 + src/engine/Port.cxx | 18 +- src/engine/Port.hxx | 18 +- src/engine/Proc.cxx | 182 + src/engine/Proc.hxx | 52 + src/engine/RefCounter.cxx | 49 + src/engine/RefCounter.hxx | 24 + src/engine/Runtime.cxx | 126 +- src/engine/Runtime.hxx | 102 +- src/engine/Scheduler.hxx | 16 +- src/engine/ServiceInlineNode.cxx | 27 + src/engine/ServiceInlineNode.hxx | 28 + src/engine/ServiceNode.cxx | 133 + src/engine/ServiceNode.hxx | 55 + src/engine/SharedPtr.hxx | 44 + src/engine/StaticDefinedComposedNode.cxx | 28 + src/engine/StaticDefinedComposedNode.hxx | 27 + src/engine/Switch.cxx | 655 +++- src/engine/Switch.hxx | 106 +- src/engine/Task.hxx | 13 + src/engine/Test/ComponentInstanceTest.cxx | 97 + src/engine/Test/ComponentInstanceTest.hxx | 42 + src/engine/Test/ContainerTest.cxx | 98 + src/engine/Test/ContainerTest.hxx | 51 + src/engine/Test/IntegrationTestEngine.cxx | 13 + src/engine/Test/Makefile.am | 46 +- src/engine/Test/PluginOptEvTest1.cxx | 84 + src/engine/Test/PluginOptEvTest1.hxx | 35 + .../Test/RuntimeForEngineIntegrationTest.cxx | 72 + .../Test/RuntimeForEngineIntegrationTest.hxx | 23 + src/engine/Test/RuntimeForEngineTest.cxx | 108 + src/engine/Test/RuntimeForEngineTest.hxx | 58 + src/engine/Test/TestEngine.cxx | 2 + src/engine/Test/ToyNode.cxx | 719 ++++ src/engine/Test/ToyNode.hxx | 245 ++ src/engine/Test/engineIntegrationTest.cxx | 2905 ++++++++++++++++ src/engine/Test/engineIntegrationTest.hxx | 109 + src/engine/Test/engineTest.cxx | 555 ++- src/engine/Test/engineTest.hxx | 20 +- src/engine/TypeCode.cxx | 595 +++- src/engine/TypeCode.hxx | 196 +- src/engine/Visitor.cxx | 31 + src/engine/Visitor.hxx | 57 + src/engine/VisitorSaveSchema.cxx | 886 +++++ src/engine/VisitorSaveSchema.hxx | 98 + src/engine/VisitorSaveState.cxx | 242 ++ src/engine/VisitorSaveState.hxx | 41 + src/engine/WhileLoop.cxx | 124 + src/engine/WhileLoop.hxx | 43 + src/engine/pilot.i | 957 ++++++ src/gui/Makefile.am | 133 + src/gui/Pascal4.xml | 741 ++++ src/gui/YACSGui_DataModel.cxx | 99 + src/gui/YACSGui_DataModel.h | 52 + src/gui/YACSGui_DataObject.cxx | 123 + src/gui/YACSGui_DataObject.h | 61 + src/gui/YACSGui_Executor.cxx | 390 +++ src/gui/YACSGui_Executor.h | 88 + src/gui/YACSGui_Graph.cxx | 665 ++++ src/gui/YACSGui_Graph.h | 110 + src/gui/YACSGui_Module.cxx | 966 ++++++ src/gui/YACSGui_Module.h | 149 + src/gui/YACSGui_Node.cxx | 399 +++ src/gui/YACSGui_Node.h | 152 + src/gui/YACSGui_Observer.cxx | 291 ++ src/gui/YACSGui_Observer.h | 95 + src/gui/YACSGui_RunMode.cxx | 389 +++ src/gui/YACSGui_RunMode.h | 97 + src/gui/YACSGui_Swig.cxx | 90 + src/gui/YACSGui_Swig.h | 36 + src/gui/YACSGui_Swig.i | 43 + src/gui/YACSGui_XMLDriver.cxx | 263 ++ src/gui/YACSGui_XMLDriver.h | 401 +++ src/gui/legendre7.xml | 320 ++ src/gui/resources/ModuleYacs.png | Bin 0 -> 1288 bytes src/gui/resources/SalomeApp.xml | 12 + src/gui/resources/YACSGuiCatalog.xml.in | 27 + src/gui/resources/YACSGui_images.po | 83 + src/gui/resources/YACSGui_msg_en.po | 325 ++ src/gui/resources/add_in_study.png | Bin 0 -> 667 bytes src/gui/resources/add_node.png | Bin 0 -> 525 bytes src/gui/resources/change_informations.png | Bin 0 -> 978 bytes src/gui/resources/control_view.png | Bin 0 -> 477 bytes src/gui/resources/export_dataflow.png | Bin 0 -> 1131 bytes src/gui/resources/filter_next_steps.png | Bin 0 -> 1168 bytes src/gui/resources/filter_notification.png | Bin 0 -> 637 bytes src/gui/resources/full_view.png | Bin 0 -> 643 bytes src/gui/resources/import_dataflow.png | Bin 0 -> 1107 bytes src/gui/resources/import_superv_dataflow.png | Bin 0 -> 1746 bytes src/gui/resources/insert_file.png | Bin 0 -> 862 bytes src/gui/resources/kill.png | Bin 0 -> 1087 bytes src/gui/resources/mode_breakpoint.png | Bin 0 -> 818 bytes src/gui/resources/mode_continue.png | Bin 0 -> 308 bytes src/gui/resources/modify_dataflow.png | Bin 0 -> 1007 bytes src/gui/resources/modify_superv_dataflow.png | Bin 0 -> 2084 bytes src/gui/resources/new_dataflow.png | Bin 0 -> 302 bytes src/gui/resources/rebuild_links.png | Bin 0 -> 746 bytes src/gui/resources/reload.png | Bin 0 -> 242 bytes src/gui/resources/remote_run.png | Bin 0 -> 427 bytes src/gui/resources/run.png | Bin 0 -> 987 bytes src/gui/resources/sample.png | Bin 0 -> 1623 bytes src/gui/resources/save_dataflow_state.png | Bin 0 -> 821 bytes src/gui/resources/step_by_step.png | Bin 0 -> 896 bytes src/gui/resources/suspend_resume.png | Bin 0 -> 966 bytes src/gui/resources/table_view.png | Bin 0 -> 467 bytes src/gui/resources/toggle_stop_on_error.png | Bin 0 -> 981 bytes src/gui/runmode.ui | 636 ++++ src/gui/yacsguiloader.py | 22 + src/lineconn2d/LineConn2d.cxx | 66 + src/lineconn2d/LineConn2d.h | 88 + src/lineconn2d/LineConn2d.vcproj | 625 ++++ src/lineconn2d/LineConn2dAfx.h | 34 + src/lineconn2d/LineConn2d_Box.cxx | 202 ++ src/lineconn2d/LineConn2d_Box.h | 147 + src/lineconn2d/LineConn2d_BoxTree.cxx | 47 + src/lineconn2d/LineConn2d_BoxTree.h | 66 + src/lineconn2d/LineConn2d_Connection.cxx | 24 + src/lineconn2d/LineConn2d_Connection.h | 79 + src/lineconn2d/LineConn2d_IntervalBuffer.cxx | 243 ++ src/lineconn2d/LineConn2d_IntervalBuffer.h | 87 + src/lineconn2d/LineConn2d_Model.cxx | 501 +++ src/lineconn2d/LineConn2d_Model.h | 309 ++ src/lineconn2d/LineConn2d_Object.cxx | 114 + src/lineconn2d/LineConn2d_Object.h | 102 + src/lineconn2d/LineConn2d_Path.cxx | 398 +++ src/lineconn2d/LineConn2d_Path.h | 187 + src/lineconn2d/LineConn2d_PathIterator.cxx | 62 + src/lineconn2d/LineConn2d_PathIterator.h | 72 + src/lineconn2d/LineConn2d_Port.h | 49 + src/lineconn2d/LineConn2d_Segment.cxx | 51 + src/lineconn2d/LineConn2d_Segment.h | 111 + src/lineconn2d/LineConn2d_SegmentIterator.h | 69 + src/lineconn2d/LineConn2d_ZInterval.h | 60 + src/lineconn2d/Makefile.am | 56 + src/lineconn2d/Makefile_old.in | 54 + src/prs/Makefile.am | 75 + src/prs/YACSPrs_BlocNode.cxx | 912 +++++ src/prs/YACSPrs_BlocNode.h | 125 + src/prs/YACSPrs_Def.h | 88 + src/prs/YACSPrs_ElementaryNode.cxx | 2294 +++++++++++++ src/prs/YACSPrs_ElementaryNode.h | 429 +++ src/prs/YACSPrs_ForEachLoopNode.cxx | 208 ++ src/prs/YACSPrs_ForEachLoopNode.h | 40 + src/prs/YACSPrs_IfNode.cxx | 129 + src/prs/YACSPrs_IfNode.h | 45 + src/prs/YACSPrs_InlineNode.cxx | 292 ++ src/prs/YACSPrs_InlineNode.h | 55 + src/prs/YACSPrs_Link.cxx | 901 +++++ src/prs/YACSPrs_Link.h | 261 ++ src/prs/YACSPrs_LoopNode.cxx | 359 ++ src/prs/YACSPrs_LoopNode.h | 63 + src/prs/YACSPrs_ServiceNode.cxx | 264 ++ src/prs/YACSPrs_ServiceNode.h | 61 + src/prs/YACSPrs_SwitchNode.cxx | 291 ++ src/prs/YACSPrs_SwitchNode.h | 47 + src/prs/resources/YACSPrs_images.po | 27 + src/prs/resources/YACSPrs_msg_en.po | 23 + src/prs/resources/aborted1.png | Bin 0 -> 5765 bytes src/prs/resources/aborted2.png | Bin 0 -> 5585 bytes src/prs/resources/aborted3.png | Bin 0 -> 5573 bytes src/prs/resources/disabled.png | Bin 0 -> 5791 bytes src/prs/resources/done.png | Bin 0 -> 5854 bytes src/prs/resources/left_arrows.png | Bin 0 -> 2407 bytes src/prs/resources/no_status.png | Bin 0 -> 5809 bytes src/prs/resources/right_arrows.png | Bin 0 -> 2468 bytes src/prs/resources/running.png | Bin 0 -> 5969 bytes src/prs/resources/waiting.png | Bin 0 -> 4997 bytes src/pyqt/Makefile.am | 3 + src/pyqt/gui/Appli.py | 340 ++ src/pyqt/gui/CItems.py | 493 +++ src/pyqt/gui/Editor.py | 19 + src/pyqt/gui/GraphViewer.py | 387 +++ src/pyqt/gui/Icons.py | 30 + src/pyqt/gui/Item.py | 31 + src/pyqt/gui/Items.py | 577 ++++ src/pyqt/gui/PanelManager.py | 15 + src/pyqt/gui/Tree.py | 83 + src/pyqt/gui/__init__.py | 0 src/pyqt/gui/adapt.py | 59 + src/pyqt/gui/icons/components.png | Bin 0 -> 1334 bytes src/pyqt/gui/icons/controllink.png | Bin 0 -> 120 bytes src/pyqt/gui/icons/datalink.png | Bin 0 -> 124 bytes src/pyqt/gui/icons/edit.png | Bin 0 -> 629 bytes src/pyqt/gui/icons/export.gif | Bin 0 -> 267 bytes src/pyqt/gui/icons/folder.gif | Bin 0 -> 120 bytes src/pyqt/gui/icons/green-ball.gif | Bin 0 -> 137 bytes src/pyqt/gui/icons/green-los.gif | Bin 0 -> 143 bytes src/pyqt/gui/icons/green-square.gif | Bin 0 -> 140 bytes src/pyqt/gui/icons/import.gif | Bin 0 -> 270 bytes src/pyqt/gui/icons/inport.png | Bin 0 -> 126 bytes src/pyqt/gui/icons/instream.png | Bin 0 -> 134 bytes src/pyqt/gui/icons/kill.png | Bin 0 -> 889 bytes src/pyqt/gui/icons/modify.png | Bin 0 -> 959 bytes src/pyqt/gui/icons/openfolder.gif | Bin 0 -> 125 bytes src/pyqt/gui/icons/outport.png | Bin 0 -> 126 bytes src/pyqt/gui/icons/outstream.png | Bin 0 -> 131 bytes src/pyqt/gui/icons/port.png | Bin 0 -> 171 bytes src/pyqt/gui/icons/run.png | Bin 0 -> 831 bytes src/pyqt/gui/icons/steps.png | Bin 0 -> 234 bytes src/pyqt/gui/icons/streamlink.png | Bin 0 -> 132 bytes src/pyqt/gui/icons/suspend-resume.gif | Bin 0 -> 214 bytes src/pyqt/gui/imagesxpm.py | 95 + src/pyqt/salomefiles/DEMO_CHRIS_1.xml | 158 + src/pyqt/salomefiles/GraphLoop1.xml | 307 ++ src/pyqt/salomefiles/calc.xml | 301 ++ src/pyqt/salomefiles/my2loopsf.xml | 936 +++++ src/pyqt/salomefiles/myloop.xml | 345 ++ src/pyqt/salomefiles/mymacro.xml | 92 + src/pyqt/salomefiles/mymacro2.xml | 151 + src/pyqt/salomefiles/myproc.xml | 482 +++ src/pyqt/salomefiles/onenode.xml | 126 + src/pyqt/salomefiles/procmacro.xml | 408 +++ src/pyqt/salomefiles/procmacro2.xml | 626 ++++ src/pyqt/salomefiles/procmacro3.xml | 817 +++++ src/pyqt/salomefiles/simple2loops.xml | 674 ++++ src/pyqt/salomefiles/threecompo.xml | 224 ++ src/pyqt/salomefiles/threef.xml | 185 + src/pyqt/salomefiles/threenodes.xml | 243 ++ src/pyqt/salomefiles/twoconnectednodes.xml | 155 + src/pyqt/salomefiles/twoloops.xml | 732 ++++ src/pyqt/salomefiles/twoloopsandf.xml | 936 +++++ src/pyqt/salomefiles/twonodes.xml | 196 ++ src/pyqt/yacsedit.py | 21 + src/pyqt/yacsfiles/forloop3.xml | 37 + src/pyqt/yacsfiles/while1.xml | 45 + src/runtime/CORBACORBAConv.cxx | 20 +- src/runtime/CORBACORBAConv.hxx | 13 +- src/runtime/CORBAComponent.cxx | 170 + src/runtime/CORBAComponent.hxx | 40 + src/runtime/CORBACppConv.cxx | 59 + src/runtime/CORBACppConv.hxx | 25 + src/runtime/CORBANeutralConv.cxx | 43 + src/runtime/CORBANeutralConv.hxx | 24 + src/runtime/CORBANode.cxx | 548 ++- src/runtime/CORBANode.hxx | 57 +- src/runtime/CORBAPorts.cxx | 255 +- src/runtime/CORBAPorts.hxx | 25 +- src/runtime/CORBAPythonConv.cxx | 150 +- src/runtime/CORBAPythonConv.hxx | 72 +- src/runtime/CORBAXMLConv.cxx | 28 +- src/runtime/CORBAXMLConv.hxx | 2 +- src/runtime/CalStreamPort.cxx | 195 ++ src/runtime/CalStreamPort.hxx | 78 + src/runtime/CppCORBAConv.cxx | 43 + src/runtime/CppCORBAConv.hxx | 24 + src/runtime/CppComponent.cxx | 204 ++ src/runtime/CppComponent.hxx | 53 + src/runtime/CppContainer.cxx | 371 ++ src/runtime/CppContainer.hxx | 106 + src/runtime/CppCppConv.cxx | 55 + src/runtime/CppCppConv.hxx | 30 + src/runtime/CppNeutralConv.cxx | 56 + src/runtime/CppNeutralConv.hxx | 23 + src/runtime/CppNode.cxx | 163 +- src/runtime/CppNode.hxx | 36 +- src/runtime/CppPorts.cxx | 177 + src/runtime/CppPorts.hxx | 63 + src/runtime/CppPythonConv.cxx | 57 + src/runtime/CppPythonConv.hxx | 23 + src/runtime/CppXMLConv.cxx | 56 + src/runtime/CppXMLConv.hxx | 22 + src/runtime/Makefile.am | 145 +- src/runtime/NeutralCORBAConv.cxx | 124 + src/runtime/NeutralCORBAConv.hxx | 68 + src/runtime/NeutralCppConv.cxx | 56 + src/runtime/NeutralCppConv.hxx | 29 + src/runtime/NeutralPythonConv.cxx | 142 + src/runtime/NeutralPythonConv.hxx | 69 + src/runtime/NeutralXMLConv.cxx | 35 + src/runtime/NeutralXMLConv.hxx | 27 + src/runtime/PythonCORBAConv.cxx | 165 +- src/runtime/PythonCORBAConv.hxx | 27 +- src/runtime/PythonCppConv.cxx | 49 + src/runtime/PythonCppConv.hxx | 25 + src/runtime/PythonNeutralConv.cxx | 42 + src/runtime/PythonNeutralConv.hxx | 23 + src/runtime/PythonNode.cxx | 347 +- src/runtime/PythonNode.hxx | 32 +- src/runtime/PythonPorts.cxx | 161 +- src/runtime/PythonPorts.hxx | 33 + src/runtime/PythonXMLConv.cxx | 37 + src/runtime/PythonXMLConv.hxx | 22 + src/runtime/RuntimeSALOME.cxx | 1384 ++++++-- src/runtime/RuntimeSALOME.hxx | 160 +- src/runtime/SALOMEDispatcher.cxx | 57 + src/runtime/SALOMEDispatcher.hxx | 40 + src/runtime/SALOMERuntime.i | 123 + src/runtime/SALOMEconfig.h | 57 + src/runtime/SalomeComponent.cxx | 142 + src/runtime/SalomeComponent.hxx | 40 + src/runtime/SalomeContainer.cxx | 129 + src/runtime/SalomeContainer.hxx | 40 + src/runtime/SalomeProc.cxx | 26 + src/runtime/SalomeProc.hxx | 27 + src/runtime/SalomePythonComponent.cxx | 88 + src/runtime/SalomePythonComponent.hxx | 34 + src/runtime/SalomePythonNode.cxx | 213 ++ src/runtime/SalomePythonNode.hxx | 37 + src/runtime/Test/Makefile.am | 42 +- src/runtime/Test/TestComponent.cxx | 81 + src/runtime/Test/TestComponent.hxx | 28 + src/runtime/Test/TestRuntime.cxx | 2 + src/runtime/Test/TestStandAlone.cxx | 38 + src/runtime/Test/echo.idl | 3 + src/runtime/Test/echoSrv.cxx | 142 +- src/runtime/Test/echo_clt.cxx | 75 + src/runtime/Test/runtimeTest.cxx | 1714 +++++++--- src/runtime/Test/runtimeTest.hxx | 97 +- src/runtime/Test/runtimeTest.sh | 4 + src/runtime/Test/standaloneTest.sh | 41 + src/runtime/Test/xmlrun_orig.sh | 67 + src/runtime/TypeConversions.cxx | 2604 +++++++++----- src/runtime/TypeConversions.hxx | 62 +- src/runtime/XMLCORBAConv.cxx | 59 +- src/runtime/XMLCORBAConv.hxx | 2 +- src/runtime/XMLCppConv.cxx | 86 + src/runtime/XMLCppConv.hxx | 23 + src/runtime/XMLNeutralConv.cxx | 70 + src/runtime/XMLNeutralConv.hxx | 22 + src/runtime/XMLNode.cxx | 306 +- src/runtime/XMLNode.hxx | 22 +- src/runtime/XMLPorts.cxx | 98 +- src/runtime/XMLPorts.hxx | 25 + src/runtime/XMLPythonConv.cxx | 76 + src/runtime/XMLPythonConv.hxx | 22 + src/salomeloader/Makefile.am | 5 + src/salomeloader/salomeloader.py | 1010 ++++++ src/wrappergen/Makefile.am | 2 + src/wrappergen/bin/Cpp_Template__SRC/AUTHORS | 1 + .../bin/Cpp_Template__SRC/ChangeLog | 0 .../bin/Cpp_Template__SRC/Makefile.am | 5 + src/wrappergen/bin/Cpp_Template__SRC/NEWS | 0 src/wrappergen/bin/Cpp_Template__SRC/README | 15 + .../adm/unix/config_files/ac_pkg_swig.m4 | 150 + .../adm/unix/config_files/ac_python_devel.m4 | 60 + .../adm/unix/config_files/check_Kernel.m4 | 58 + .../adm/unix/config_files/check_Med.m4 | 61 + .../adm/unix/config_files/check_hdf5.m4 | 83 + .../adm/unix/config_files/check_med2.m4 | 86 + .../adm/unix/config_files/check_pthreads.m4 | 51 + .../adm/unix/config_files/check_python.m4 | 163 + .../adm/unix/config_files/check_swig.m4 | 66 + .../adm/unix/config_files/enable_pthreads.m4 | 41 + .../adm/unix/config_files/production.m4 | 99 + .../Cpp_Template__SRC/adm/unix/make_begin.am | 0 .../Cpp_Template__SRC/adm/unix/make_check.am | 15 + .../Cpp_Template__SRC/adm/unix/make_end.am | 12 + src/wrappergen/bin/Cpp_Template__SRC/archive | 34 + .../bin/Cpp_Template__SRC/build_configure | 38 + .../bin/Cpp_Template__SRC/configure.in.base | 23 + src/wrappergen/bin/Cpp_Template__SRC/rfind | 46 + .../bin/Cpp_Template__SRC/root_clean | 32 + .../Cpp_Template__CXX/Cpp_Template_.cxx | 15 + .../Cpp_Template__CXX/Cpp_Template_.hxx | 20 + .../Cpp_Template__CXX/Makefile.am | 33 + .../Cpp_Template_/Cpp_Template__CXX/main.cxx | 12 + .../Cpp_Template__SWIG/Cpp_Template_.i | 22 + .../Cpp_Template__SWIG/Makefile.am | 32 + .../Cpp_Template__TEST/Cpp_Template__test.py | 16 + .../Cpp_Template__TEST/Makefile.am | 7 + .../src/Cpp_Template_/Makefile.am | 3 + .../bin/Cpp_Template__SRC/src/Makefile.am | 2 + src/wrappergen/bin/Deprecated | 1 + .../adm_local/unix/config_files/README | 3 + .../unix/config_files/ac_cxx_depend_flag.m4 | 144 + .../unix/config_files/ac_cxx_option.m4 | 45 + .../unix/config_files/check_Comp_Env.m4 | 25 + .../adm_local/unix/config_files/check_GUI.m4 | 60 + .../unix/config_files/check_Kernel.m4 | 58 + .../adm_local/unix/config_files/check_Med.m4 | 119 + .../adm_local/unix/config_files/check_Med2.m4 | 114 + .../adm_local/unix/config_files/check_hdf5.m4 | 88 + .../adm_local/unix/config_files/check_med2.m4 | 96 + .../unix/config_files/check_omniorb.m4 | 306 ++ .../unix/config_files/check_pthreads.m4 | 50 + .../unix/config_files/enable_pthreads.m4 | 41 + .../adm_local/unix/config_files/python.m4 | 65 + .../adm_local/unix/make_commence.in | 260 ++ .../adm_local/unix/make_omniorb.in | 56 + .../bin/VERSION | 2 + .../bin/runAppli.in | 8 + .../bin/runSalome.py | 506 +++ .../build_configure | 208 ++ .../configure.in.base | 313 ++ .../doc/dev_guide.txt | 103 + .../idl/HXX2SALOME_GENERIC_CLASS_NAME_Gen.idl | 20 + .../ExecHXX2SALOME_GENERIC_CLASS_NAME.png | Bin 0 -> 831 bytes .../HXX2SALOME_GENERIC_CLASS_NAME.png | Bin 0 -> 831 bytes .../HXX2SALOME_GENERIC_CLASS_NAME_en.ps | 789 +++++ .../HXX2SALOME_GENERIC_CLASS_NAME_en.xml | 26 + .../HXX2SALOME_GENERIC_CLASS_NAME_fr.xml | 23 + .../resources/SalomeApp.xml | 11 + .../resources/config | 1 + .../HXX2SALOME_GENERIC_CLASS_NAME_TEST.py | 7 + .../HXX2SALOME_GENERIC_CLASS_NAME_i.cxx | 55 + .../HXX2SALOME_GENERIC_CLASS_NAME_i.hxx | 42 + .../HXX2SALOME_GENERIC_CLASS_NAMEGUI.cxx | 221 ++ .../HXX2SALOME_GENERIC_CLASS_NAMEGUI.h | 48 + .../HXX2SALOME_GENERIC_CLASS_NAME_icons.po | 14 + .../HXX2SALOME_GENERIC_CLASS_NAME_msg_en.po | 99 + .../HXX2SALOME_GENERIC_CLASS_NAME_msg_fr.po | 99 + src/wrappergen/bin/Makefile.am | 1 + .../HXX2SALOME_GENERIC_CLASS_NAME_SRC/AUTHORS | 0 .../HXX2SALOME_GENERIC_CLASS_NAME_SRC/COPYING | 340 ++ .../ChangeLog | 0 .../HXX2SALOME_GENERIC_CLASS_NAME_SRC/INSTALL | 236 ++ .../Makefile.am | 29 + .../HXX2SALOME_GENERIC_CLASS_NAME_SRC/NEWS | 0 .../HXX2SALOME_GENERIC_CLASS_NAME_SRC/README | 0 .../adm_local/Makefile.am | 1 + .../adm_local/unix/Makefile.am | 4 + .../adm_local/unix/SALOMEconfig.h.in | 36 + .../adm_local/unix/config_files/README | 3 + .../unix/config_files/ac_cc_warnings.m4 | 119 + .../unix/config_files/ac_cxx_depend_flag.m4 | 144 + .../unix/config_files/ac_cxx_have_sstream.m4 | 45 + .../unix/config_files/ac_cxx_namespaces.m4 | 43 + .../unix/config_files/ac_cxx_option.m4 | 45 + .../config_files/ac_cxx_template_options.m4 | 39 + .../config_files/ac_cxx_use_std_iostream.m4 | 55 + .../unix/config_files/ac_cxx_warnings.m4 | 34 + .../unix/config_files/ac_linker_options.m4 | 57 + .../unix/config_files/check_Comp_Env.m4 | 25 + .../adm_local/unix/config_files/check_GUI.m4 | 60 + .../unix/config_files/check_Kernel.m4 | 58 + .../adm_local/unix/config_files/check_Med.m4 | 119 + .../adm_local/unix/config_files/check_Med2.m4 | 114 + .../unix/config_files/check_boost.m4 | 145 + .../adm_local/unix/config_files/check_cas.m4 | 238 ++ .../unix/config_files/check_corba.m4 | 69 + .../adm_local/unix/config_files/check_hdf5.m4 | 88 + .../adm_local/unix/config_files/check_med2.m4 | 96 + .../unix/config_files/check_msg2qm.m4 | 57 + .../unix/config_files/check_omniorb.m4 | 313 ++ .../unix/config_files/check_opengl.m4 | 195 ++ .../unix/config_files/check_pthreads.m4 | 56 + .../unix/config_files/check_python.m4 | 171 + .../adm_local/unix/config_files/check_qt.m4 | 182 + .../unix/config_files/enable_pthreads.m4 | 41 + .../adm_local/unix/config_files/production.m4 | 106 + .../adm_local/unix/make_begin.am | 2 + .../adm_local/unix/make_common_starter.am | 30 + .../adm_local/unix/make_end.am | 24 + .../adm_local/unix/py-compile | 113 + .../bin/Makefile.am | 0 .../bin/VERSION | 2 + .../bin/runAppli.in | 8 + .../bin/runSalome.py | 506 +++ .../build_configure | 63 + .../configure.in.base | 289 ++ .../doc/Makefile.am | 15 + .../doc/dev_guide.txt | 103 + .../doc/rst.css | 288 ++ .../idl/HXX2SALOME_GENERIC_CLASS_NAME_Gen.idl | 26 + .../idl/Makefile.am | 74 + .../py-compile | 146 + .../ExecHXX2SALOME_GENERIC_CLASS_NAME.png | Bin 0 -> 831 bytes .../HXX2SALOME_GENERIC_CLASS_NAME.png | Bin 0 -> 831 bytes .../HXX2SALOME_GENERIC_CLASS_NAME_en.ps | 789 +++++ .../HXX2SALOME_GENERIC_CLASS_NAME_en.xml | 26 + .../HXX2SALOME_GENERIC_CLASS_NAME_fr.xml | 23 + .../resources/Makefile.am | 23 + .../resources/SalomeApp.xml | 11 + .../resources/config | 1 + .../HXX2SALOME_GENERIC_CLASS_NAME_SRC/rfind | 52 + .../root_clean | 26 + .../HXX2SALOME_GENERIC_CLASS_NAMEGUI.cxx | 221 ++ .../HXX2SALOME_GENERIC_CLASS_NAMEGUI.h | 48 + .../HXX2SALOME_GENERIC_CLASS_NAME_icons.po | 14 + .../HXX2SALOME_GENERIC_CLASS_NAME_msg_en.po | 99 + .../HXX2SALOME_GENERIC_CLASS_NAME_msg_fr.po | 99 + .../Makefile.am | 0 .../Makefile.am | 12 + .../HXX2SALOME_GENERIC_CLASS_NAME_TEST.py | 7 + .../HXX2SALOME_GENERIC_CLASS_NAME_i.cxx | 59 + .../HXX2SALOME_GENERIC_CLASS_NAME_i.hxx | 46 + .../Makefile.am | 10 + .../Makefile.am | 0 .../src/Makefile.am | 29 + src/wrappergen/src/Makefile.am | 33 + .../compile_HXX2SALOME_GENERIC_CLASS_NAME.sh | 35 + src/wrappergen/src/hxx2salome | 457 +++ src/wrappergen/src/hxx2salome_check | 96 + src/wrappergen/src/hxx2salome_corba | 134 + src/wrappergen/src/hxx2salome_cpp | 56 + src/wrappergen/src/parse0.awk | 8 + src/wrappergen/src/parse01.awk | 20 + src/wrappergen/src/parse1.awk | 24 + src/wrappergen/src/parse2.awk | 4 + src/wrappergen/src/parse3.awk | 373 ++ src/wrappergen/src/parse30.awk | 138 + src/wrappergen/src/parse4.awk | 205 ++ src/wrappergen/src/parse5.awk | 122 + src/wrappergen/src/renameSalomeModule | 124 + src/wrappergen/src/runIDLparser | 67 + src/yacsloader/LoadState.cxx | 646 ++++ src/yacsloader/LoadState.hxx | 150 + src/yacsloader/Makefile.am | 121 + src/yacsloader/README.html | 406 +++ src/yacsloader/README.txt | 91 + src/yacsloader/Test/Makefile.am | 77 + src/yacsloader/Test/TestYacsLoader.cxx | 15 + .../Test/YacsLoaderInSessionTest.sh.in | 25 + .../Test/YacsLoaderInSessionTest2.sh.in | 32 + src/yacsloader/Test/YacsLoaderTest.cxx | 710 ++++ src/yacsloader/Test/YacsLoaderTest.hxx | 108 + src/yacsloader/Test/YacsLoaderTest.sh.in | 74 + src/yacsloader/Test/config_appli.xml.in | 23 + src/yacsloader/Test/display.sh.in | 12 + src/yacsloader/Test/echo.idl | 90 + src/yacsloader/Test/echoSrv.cxx | 497 +++ src/yacsloader/Test/genPascal.py | 177 + src/yacsloader/Test/genTriangle.py | 168 + src/yacsloader/Test/testEdit.py | 186 + src/yacsloader/Test/testExec.py | 168 + src/yacsloader/Test/testLoader.py | 67 + src/yacsloader/Test/testResume.py | 75 + src/yacsloader/Test/testSave.py | 85 + src/yacsloader/Test/waitContainers.py | 8 + src/yacsloader/Test/xmlrun_orig.sh | 73 + src/yacsloader/debugger.cxx | 130 + src/yacsloader/driver.cxx | 245 ++ src/yacsloader/factory.cxx | 4 + src/yacsloader/factory.hxx | 106 + src/yacsloader/loader.i | 74 + src/yacsloader/parsers.cxx | 3005 +++++++++++++++++ src/yacsloader/parsers.hxx | 88 + src/yacsloader/resume.cxx | 113 + src/yacsloader/samples/aschema.xml | 447 +++ src/yacsloader/samples/bid.xml | 46 + src/yacsloader/samples/bloc1.xml | 46 + src/yacsloader/samples/bloc2.xml | 80 + src/yacsloader/samples/bloc3.xml | 56 + src/yacsloader/samples/bloc4.xml | 67 + src/yacsloader/samples/bool1.xml | 278 ++ src/yacsloader/samples/bschema.xml | 33 + src/yacsloader/samples/calcium0.xml | 61 + src/yacsloader/samples/calcium1.xml | 51 + src/yacsloader/samples/calcium2.xml | 84 + src/yacsloader/samples/calcium3.xml | 89 + src/yacsloader/samples/calcium4.xml | 209 ++ src/yacsloader/samples/cpp1.xml | 206 ++ src/yacsloader/samples/cschema.xml | 36 + src/yacsloader/samples/double1.xml | 277 ++ src/yacsloader/samples/dschema.xml | 48 + src/yacsloader/samples/eschema.xml | 31 + src/yacsloader/samples/foreach1.xml | 57 + src/yacsloader/samples/foreach2.xml | 59 + src/yacsloader/samples/foreach3.xml | 57 + src/yacsloader/samples/foreach4.xml | 49 + src/yacsloader/samples/foreach5.xml | 69 + src/yacsloader/samples/foreach6.xml | 69 + src/yacsloader/samples/foreach_LongCorba.xml | 49 + src/yacsloader/samples/foreach_LongPython.xml | 55 + src/yacsloader/samples/forloop1.xml | 28 + src/yacsloader/samples/forloop2.xml | 32 + src/yacsloader/samples/forloop3.xml | 38 + src/yacsloader/samples/forloop4.xml | 40 + src/yacsloader/samples/forloop5.xml | 42 + src/yacsloader/samples/forloop6.xml | 45 + src/yacsloader/samples/forloop7.xml | 42 + src/yacsloader/samples/forwhile1.xml | 55 + src/yacsloader/samples/fschema.xml | 35 + src/yacsloader/samples/integer1.xml | 277 ++ src/yacsloader/samples/legendre7.xml | 124 + src/yacsloader/samples/objref1.xml | 195 ++ src/yacsloader/samples/oschema.xml | 106 + src/yacsloader/samples/pschema.xml | 418 +++ src/yacsloader/samples/refcnt1.xml | 84 + src/yacsloader/samples/refcnt2.xml | 62 + src/yacsloader/samples/schema.xml | 60 + src/yacsloader/samples/schema2.xml | 467 +++ src/yacsloader/samples/sinline1.xml | 97 + src/yacsloader/samples/sinline2.xml | 33 + src/yacsloader/samples/sinline3.xml | 33 + src/yacsloader/samples/sinline4.xml | 101 + src/yacsloader/samples/sinline5.xml | 65 + src/yacsloader/samples/stream1.xml | 32 + src/yacsloader/samples/stream2.xml | 51 + src/yacsloader/samples/stream3.xml | 85 + src/yacsloader/samples/stream4.xml | 153 + src/yacsloader/samples/string1.xml | 277 ++ src/yacsloader/samples/struct1.xml | 226 ++ src/yacsloader/samples/switch1.xml | 44 + src/yacsloader/samples/switch2.xml | 49 + src/yacsloader/samples/switch3.xml | 55 + src/yacsloader/samples/switch4.xml | 69 + src/yacsloader/samples/switch5.xml | 71 + src/yacsloader/samples/switch6.xml | 70 + src/yacsloader/samples/switch7.xml | 70 + src/yacsloader/samples/switch8.xml | 77 + src/yacsloader/samples/switch9.xml | 85 + src/yacsloader/samples/while1.xml | 45 + src/yacsloader/samples/while2.xml | 47 + src/yacsloader/samples/while3.xml | 49 + src/yacsloader/schema.xsd | 281 ++ src/yacsloader/xmlParserBase.cxx | 481 +++ src/yacsloader/xmlParserBase.hxx | 125 + src/yacsorb/Makefile.am | 85 + src/yacsorb/README.txt | 15 + src/yacsorb/YACSGui.py | 185 + src/yacsorb/yacs.idl | 32 + src/yacsorb/yacsSrv.cxx | 290 ++ src/yacsorb/yacs_clt.cxx | 109 + 781 files changed, 98514 insertions(+), 3676 deletions(-) create mode 100644 Demo/Makefile.am create mode 100644 Demo/echo.idl create mode 100644 Demo/echoSrv.cxx create mode 100644 Demo/schema_orig.xml create mode 100755 Demo/xmlrpcprog_orig.py create mode 100644 Misc/valgrind-python.supp create mode 100644 adm/unix/config_files/ac_cxx_option.m4 create mode 100644 adm/unix/config_files/ac_linker_options.m4 delete mode 100755 adm/unix/config_files/ac_prog_esope.m4 create mode 100644 adm/unix/config_files/check_SALOME.m4 create mode 100755 adm/unix/config_files/check_cas.m4 create mode 100644 adm/unix/config_files/check_expat.m4 create mode 100644 adm/unix/config_files/check_htmlgen.m4 create mode 100644 adm/unix/config_files/check_libxml.m4 create mode 100755 adm/unix/config_files/check_msg2qm.m4 create mode 100644 adm/unix/config_files/check_opengl.m4 create mode 100644 adm/unix/config_files/check_salome.m4 create mode 100755 adm/unix/make_gui_begin.am create mode 100644 doc/Doxyfile.in create mode 100644 doc/Makefile.am create mode 100644 doc/bases.dox create mode 100644 doc/engine.dox create mode 100644 doc/python.dox create mode 100644 doc/runtime.dox create mode 100644 doc/schema.jpeg create mode 100644 doc/yacs.dox create mode 100644 doc/yacsloader.dox create mode 100644 idl/Makefile.am create mode 100644 idl/yacsgui.idl create mode 100644 src/bases/Cstr2d.cxx create mode 100644 src/bases/Cstr2d.hxx create mode 100644 src/bases/DrivenCondition.cxx create mode 100644 src/bases/DrivenCondition.hxx create mode 100644 src/bases/DrivenConditionPT.cxx create mode 100644 src/bases/DrivenConditionPT.hxx create mode 100644 src/bases/DynLibLoader.cxx create mode 100644 src/bases/DynLibLoader.hxx create mode 100644 src/bases/DynLibLoaderGNU.cxx create mode 100644 src/bases/DynLibLoaderGNU.hxx create mode 100644 src/bases/DynLibLoaderWin.cxx create mode 100644 src/bases/DynLibLoaderWin.hxx create mode 100644 src/bases/Test/DLTest.cxx create mode 100644 src/bases/Test/InitTests.cxx create mode 100644 src/bases/Test/UnitTestsResult.hxx create mode 100644 src/bases/YacsTrace.cxx create mode 100644 src/bases/YacsTrace.hxx create mode 100644 src/bases/yacsconfig.h create mode 100644 src/engine/Any.cxx create mode 100644 src/engine/Any.hxx create mode 100644 src/engine/AnyInputPort.cxx create mode 100644 src/engine/AnyInputPort.hxx create mode 100644 src/engine/ComponentInstance.cxx create mode 100644 src/engine/ComponentInstance.hxx create mode 100644 src/engine/ConditionInputPort.cxx create mode 100644 src/engine/ConditionInputPort.hxx create mode 100644 src/engine/Container.cxx create mode 100644 src/engine/Container.hxx create mode 100644 src/engine/DataPort.cxx create mode 100644 src/engine/DataPort.hxx create mode 100644 src/engine/DeploymentTree.cxx create mode 100644 src/engine/DeploymentTree.hxx create mode 100644 src/engine/Dispatcher.cxx create mode 100644 src/engine/Dispatcher.hxx create mode 100644 src/engine/DynParaLoop.cxx create mode 100644 src/engine/DynParaLoop.hxx create mode 100644 src/engine/ExecutorSwig.cxx create mode 100644 src/engine/ExecutorSwig.hxx create mode 100644 src/engine/ForEachLoop.cxx create mode 100644 src/engine/ForEachLoop.hxx create mode 100644 src/engine/ForLoop.cxx create mode 100644 src/engine/ForLoop.hxx create mode 100644 src/engine/InlineNode.cxx create mode 100644 src/engine/InlineNode.hxx create mode 100644 src/engine/InvalidExtractionException.cxx create mode 100644 src/engine/InvalidExtractionException.hxx create mode 100644 src/engine/LinkInfo.cxx create mode 100644 src/engine/LinkInfo.hxx create mode 100644 src/engine/OptimizerAlg.cxx create mode 100644 src/engine/OptimizerAlg.hxx create mode 100644 src/engine/OptimizerLoop.cxx create mode 100644 src/engine/OptimizerLoop.hxx create mode 100644 src/engine/Plugin/Makefile.am create mode 100644 src/engine/Plugin/PluginSimplex.cxx create mode 100644 src/engine/Plugin/PluginSimplex.hxx create mode 100644 src/engine/Plugin/SConscript create mode 100644 src/engine/Plugin/aleas.cxx create mode 100644 src/engine/Plugin/aleas.hxx create mode 100644 src/engine/Plugin/critere.hxx create mode 100644 src/engine/Plugin/decode.cxx create mode 100644 src/engine/Plugin/decode.hxx create mode 100644 src/engine/Plugin/distrib.hxx create mode 100644 src/engine/Plugin/fonction.hxx create mode 100644 src/engine/Plugin/local.cxx create mode 100644 src/engine/Plugin/local.hxx create mode 100644 src/engine/Plugin/maestro.cxx create mode 100644 src/engine/Plugin/maestro.hxx create mode 100644 src/engine/Plugin/mt19937ar.cxx create mode 100644 src/engine/Plugin/point.cxx create mode 100644 src/engine/Plugin/point.hxx create mode 100644 src/engine/Plugin/saclass.cxx create mode 100644 src/engine/Plugin/saclass.hxx create mode 100644 src/engine/Plugin/saconst.h create mode 100644 src/engine/Plugin/saemul.cxx create mode 100644 src/engine/Plugin/saemul.hxx create mode 100644 src/engine/Plugin/salomesup.hxx create mode 100644 src/engine/Plugin/salomevent.cxx create mode 100644 src/engine/Plugin/salomevent.hxx create mode 100644 src/engine/Plugin/sasimpl.cxx create mode 100644 src/engine/Plugin/sasimpl.hxx create mode 100644 src/engine/Plugin/satest.cxx create mode 100644 src/engine/Plugin/simplex.cxx create mode 100644 src/engine/Plugin/simplex.hxx create mode 100644 src/engine/Plugin/solution.cxx create mode 100644 src/engine/Plugin/solution.hxx create mode 100644 src/engine/Pool.cxx create mode 100644 src/engine/Pool.hxx create mode 100644 src/engine/Proc.cxx create mode 100644 src/engine/Proc.hxx create mode 100644 src/engine/RefCounter.cxx create mode 100644 src/engine/RefCounter.hxx create mode 100644 src/engine/ServiceInlineNode.cxx create mode 100644 src/engine/ServiceInlineNode.hxx create mode 100644 src/engine/ServiceNode.cxx create mode 100644 src/engine/ServiceNode.hxx create mode 100644 src/engine/SharedPtr.hxx create mode 100644 src/engine/StaticDefinedComposedNode.cxx create mode 100644 src/engine/StaticDefinedComposedNode.hxx create mode 100644 src/engine/Test/ComponentInstanceTest.cxx create mode 100644 src/engine/Test/ComponentInstanceTest.hxx create mode 100644 src/engine/Test/ContainerTest.cxx create mode 100644 src/engine/Test/ContainerTest.hxx create mode 100644 src/engine/Test/IntegrationTestEngine.cxx create mode 100644 src/engine/Test/PluginOptEvTest1.cxx create mode 100644 src/engine/Test/PluginOptEvTest1.hxx create mode 100644 src/engine/Test/RuntimeForEngineIntegrationTest.cxx create mode 100644 src/engine/Test/RuntimeForEngineIntegrationTest.hxx create mode 100644 src/engine/Test/RuntimeForEngineTest.cxx create mode 100644 src/engine/Test/RuntimeForEngineTest.hxx create mode 100644 src/engine/Test/ToyNode.cxx create mode 100644 src/engine/Test/ToyNode.hxx create mode 100644 src/engine/Test/engineIntegrationTest.cxx create mode 100644 src/engine/Test/engineIntegrationTest.hxx create mode 100644 src/engine/Visitor.cxx create mode 100644 src/engine/Visitor.hxx create mode 100644 src/engine/VisitorSaveSchema.cxx create mode 100644 src/engine/VisitorSaveSchema.hxx create mode 100644 src/engine/VisitorSaveState.cxx create mode 100644 src/engine/VisitorSaveState.hxx create mode 100644 src/engine/WhileLoop.cxx create mode 100644 src/engine/WhileLoop.hxx create mode 100644 src/engine/pilot.i create mode 100644 src/gui/Makefile.am create mode 100644 src/gui/Pascal4.xml create mode 100644 src/gui/YACSGui_DataModel.cxx create mode 100644 src/gui/YACSGui_DataModel.h create mode 100644 src/gui/YACSGui_DataObject.cxx create mode 100644 src/gui/YACSGui_DataObject.h create mode 100644 src/gui/YACSGui_Executor.cxx create mode 100644 src/gui/YACSGui_Executor.h create mode 100644 src/gui/YACSGui_Graph.cxx create mode 100644 src/gui/YACSGui_Graph.h create mode 100644 src/gui/YACSGui_Module.cxx create mode 100644 src/gui/YACSGui_Module.h create mode 100644 src/gui/YACSGui_Node.cxx create mode 100644 src/gui/YACSGui_Node.h create mode 100644 src/gui/YACSGui_Observer.cxx create mode 100644 src/gui/YACSGui_Observer.h create mode 100644 src/gui/YACSGui_RunMode.cxx create mode 100644 src/gui/YACSGui_RunMode.h create mode 100644 src/gui/YACSGui_Swig.cxx create mode 100644 src/gui/YACSGui_Swig.h create mode 100644 src/gui/YACSGui_Swig.i create mode 100644 src/gui/YACSGui_XMLDriver.cxx create mode 100644 src/gui/YACSGui_XMLDriver.h create mode 100644 src/gui/legendre7.xml create mode 100644 src/gui/resources/ModuleYacs.png create mode 100644 src/gui/resources/SalomeApp.xml create mode 100644 src/gui/resources/YACSGuiCatalog.xml.in create mode 100755 src/gui/resources/YACSGui_images.po create mode 100755 src/gui/resources/YACSGui_msg_en.po create mode 100644 src/gui/resources/add_in_study.png create mode 100644 src/gui/resources/add_node.png create mode 100644 src/gui/resources/change_informations.png create mode 100644 src/gui/resources/control_view.png create mode 100644 src/gui/resources/export_dataflow.png create mode 100644 src/gui/resources/filter_next_steps.png create mode 100644 src/gui/resources/filter_notification.png create mode 100644 src/gui/resources/full_view.png create mode 100644 src/gui/resources/import_dataflow.png create mode 100644 src/gui/resources/import_superv_dataflow.png create mode 100644 src/gui/resources/insert_file.png create mode 100644 src/gui/resources/kill.png create mode 100644 src/gui/resources/mode_breakpoint.png create mode 100644 src/gui/resources/mode_continue.png create mode 100644 src/gui/resources/modify_dataflow.png create mode 100644 src/gui/resources/modify_superv_dataflow.png create mode 100644 src/gui/resources/new_dataflow.png create mode 100644 src/gui/resources/rebuild_links.png create mode 100644 src/gui/resources/reload.png create mode 100644 src/gui/resources/remote_run.png create mode 100644 src/gui/resources/run.png create mode 100644 src/gui/resources/sample.png create mode 100644 src/gui/resources/save_dataflow_state.png create mode 100644 src/gui/resources/step_by_step.png create mode 100644 src/gui/resources/suspend_resume.png create mode 100644 src/gui/resources/table_view.png create mode 100644 src/gui/resources/toggle_stop_on_error.png create mode 100644 src/gui/runmode.ui create mode 100644 src/gui/yacsguiloader.py create mode 100755 src/lineconn2d/LineConn2d.cxx create mode 100755 src/lineconn2d/LineConn2d.h create mode 100755 src/lineconn2d/LineConn2d.vcproj create mode 100755 src/lineconn2d/LineConn2dAfx.h create mode 100755 src/lineconn2d/LineConn2d_Box.cxx create mode 100755 src/lineconn2d/LineConn2d_Box.h create mode 100755 src/lineconn2d/LineConn2d_BoxTree.cxx create mode 100755 src/lineconn2d/LineConn2d_BoxTree.h create mode 100755 src/lineconn2d/LineConn2d_Connection.cxx create mode 100755 src/lineconn2d/LineConn2d_Connection.h create mode 100755 src/lineconn2d/LineConn2d_IntervalBuffer.cxx create mode 100755 src/lineconn2d/LineConn2d_IntervalBuffer.h create mode 100755 src/lineconn2d/LineConn2d_Model.cxx create mode 100755 src/lineconn2d/LineConn2d_Model.h create mode 100755 src/lineconn2d/LineConn2d_Object.cxx create mode 100755 src/lineconn2d/LineConn2d_Object.h create mode 100755 src/lineconn2d/LineConn2d_Path.cxx create mode 100755 src/lineconn2d/LineConn2d_Path.h create mode 100755 src/lineconn2d/LineConn2d_PathIterator.cxx create mode 100755 src/lineconn2d/LineConn2d_PathIterator.h create mode 100755 src/lineconn2d/LineConn2d_Port.h create mode 100755 src/lineconn2d/LineConn2d_Segment.cxx create mode 100755 src/lineconn2d/LineConn2d_Segment.h create mode 100755 src/lineconn2d/LineConn2d_SegmentIterator.h create mode 100755 src/lineconn2d/LineConn2d_ZInterval.h create mode 100644 src/lineconn2d/Makefile.am create mode 100755 src/lineconn2d/Makefile_old.in create mode 100644 src/prs/Makefile.am create mode 100644 src/prs/YACSPrs_BlocNode.cxx create mode 100644 src/prs/YACSPrs_BlocNode.h create mode 100644 src/prs/YACSPrs_Def.h create mode 100644 src/prs/YACSPrs_ElementaryNode.cxx create mode 100644 src/prs/YACSPrs_ElementaryNode.h create mode 100644 src/prs/YACSPrs_ForEachLoopNode.cxx create mode 100644 src/prs/YACSPrs_ForEachLoopNode.h create mode 100644 src/prs/YACSPrs_IfNode.cxx create mode 100644 src/prs/YACSPrs_IfNode.h create mode 100644 src/prs/YACSPrs_InlineNode.cxx create mode 100644 src/prs/YACSPrs_InlineNode.h create mode 100644 src/prs/YACSPrs_Link.cxx create mode 100644 src/prs/YACSPrs_Link.h create mode 100644 src/prs/YACSPrs_LoopNode.cxx create mode 100644 src/prs/YACSPrs_LoopNode.h create mode 100644 src/prs/YACSPrs_ServiceNode.cxx create mode 100644 src/prs/YACSPrs_ServiceNode.h create mode 100644 src/prs/YACSPrs_SwitchNode.cxx create mode 100644 src/prs/YACSPrs_SwitchNode.h create mode 100755 src/prs/resources/YACSPrs_images.po create mode 100755 src/prs/resources/YACSPrs_msg_en.po create mode 100755 src/prs/resources/aborted1.png create mode 100755 src/prs/resources/aborted2.png create mode 100755 src/prs/resources/aborted3.png create mode 100755 src/prs/resources/disabled.png create mode 100755 src/prs/resources/done.png create mode 100644 src/prs/resources/left_arrows.png create mode 100755 src/prs/resources/no_status.png create mode 100644 src/prs/resources/right_arrows.png create mode 100755 src/prs/resources/running.png create mode 100755 src/prs/resources/waiting.png create mode 100644 src/pyqt/Makefile.am create mode 100644 src/pyqt/gui/Appli.py create mode 100644 src/pyqt/gui/CItems.py create mode 100644 src/pyqt/gui/Editor.py create mode 100644 src/pyqt/gui/GraphViewer.py create mode 100644 src/pyqt/gui/Icons.py create mode 100644 src/pyqt/gui/Item.py create mode 100644 src/pyqt/gui/Items.py create mode 100644 src/pyqt/gui/PanelManager.py create mode 100644 src/pyqt/gui/Tree.py create mode 100644 src/pyqt/gui/__init__.py create mode 100644 src/pyqt/gui/adapt.py create mode 100644 src/pyqt/gui/icons/components.png create mode 100644 src/pyqt/gui/icons/controllink.png create mode 100644 src/pyqt/gui/icons/datalink.png create mode 100644 src/pyqt/gui/icons/edit.png create mode 100644 src/pyqt/gui/icons/export.gif create mode 100644 src/pyqt/gui/icons/folder.gif create mode 100755 src/pyqt/gui/icons/green-ball.gif create mode 100755 src/pyqt/gui/icons/green-los.gif create mode 100755 src/pyqt/gui/icons/green-square.gif create mode 100644 src/pyqt/gui/icons/import.gif create mode 100644 src/pyqt/gui/icons/inport.png create mode 100644 src/pyqt/gui/icons/instream.png create mode 100644 src/pyqt/gui/icons/kill.png create mode 100644 src/pyqt/gui/icons/modify.png create mode 100644 src/pyqt/gui/icons/openfolder.gif create mode 100644 src/pyqt/gui/icons/outport.png create mode 100644 src/pyqt/gui/icons/outstream.png create mode 100644 src/pyqt/gui/icons/port.png create mode 100644 src/pyqt/gui/icons/run.png create mode 100644 src/pyqt/gui/icons/steps.png create mode 100644 src/pyqt/gui/icons/streamlink.png create mode 100644 src/pyqt/gui/icons/suspend-resume.gif create mode 100644 src/pyqt/gui/imagesxpm.py create mode 100644 src/pyqt/salomefiles/DEMO_CHRIS_1.xml create mode 100644 src/pyqt/salomefiles/GraphLoop1.xml create mode 100644 src/pyqt/salomefiles/calc.xml create mode 100644 src/pyqt/salomefiles/my2loopsf.xml create mode 100644 src/pyqt/salomefiles/myloop.xml create mode 100644 src/pyqt/salomefiles/mymacro.xml create mode 100644 src/pyqt/salomefiles/mymacro2.xml create mode 100644 src/pyqt/salomefiles/myproc.xml create mode 100644 src/pyqt/salomefiles/onenode.xml create mode 100644 src/pyqt/salomefiles/procmacro.xml create mode 100644 src/pyqt/salomefiles/procmacro2.xml create mode 100644 src/pyqt/salomefiles/procmacro3.xml create mode 100644 src/pyqt/salomefiles/simple2loops.xml create mode 100644 src/pyqt/salomefiles/threecompo.xml create mode 100644 src/pyqt/salomefiles/threef.xml create mode 100644 src/pyqt/salomefiles/threenodes.xml create mode 100644 src/pyqt/salomefiles/twoconnectednodes.xml create mode 100644 src/pyqt/salomefiles/twoloops.xml create mode 100644 src/pyqt/salomefiles/twoloopsandf.xml create mode 100644 src/pyqt/salomefiles/twonodes.xml create mode 100644 src/pyqt/yacsedit.py create mode 100644 src/pyqt/yacsfiles/forloop3.xml create mode 100644 src/pyqt/yacsfiles/while1.xml create mode 100644 src/runtime/CORBAComponent.cxx create mode 100644 src/runtime/CORBAComponent.hxx create mode 100644 src/runtime/CORBACppConv.cxx create mode 100644 src/runtime/CORBACppConv.hxx create mode 100644 src/runtime/CORBANeutralConv.cxx create mode 100644 src/runtime/CORBANeutralConv.hxx create mode 100644 src/runtime/CalStreamPort.cxx create mode 100644 src/runtime/CalStreamPort.hxx create mode 100644 src/runtime/CppCORBAConv.cxx create mode 100644 src/runtime/CppCORBAConv.hxx create mode 100644 src/runtime/CppComponent.cxx create mode 100644 src/runtime/CppComponent.hxx create mode 100644 src/runtime/CppContainer.cxx create mode 100644 src/runtime/CppContainer.hxx create mode 100644 src/runtime/CppCppConv.cxx create mode 100644 src/runtime/CppCppConv.hxx create mode 100644 src/runtime/CppNeutralConv.cxx create mode 100644 src/runtime/CppNeutralConv.hxx create mode 100644 src/runtime/CppPorts.cxx create mode 100644 src/runtime/CppPorts.hxx create mode 100644 src/runtime/CppPythonConv.cxx create mode 100644 src/runtime/CppPythonConv.hxx create mode 100644 src/runtime/CppXMLConv.cxx create mode 100644 src/runtime/CppXMLConv.hxx create mode 100644 src/runtime/NeutralCORBAConv.cxx create mode 100644 src/runtime/NeutralCORBAConv.hxx create mode 100644 src/runtime/NeutralCppConv.cxx create mode 100644 src/runtime/NeutralCppConv.hxx create mode 100644 src/runtime/NeutralPythonConv.cxx create mode 100644 src/runtime/NeutralPythonConv.hxx create mode 100644 src/runtime/NeutralXMLConv.cxx create mode 100644 src/runtime/NeutralXMLConv.hxx create mode 100644 src/runtime/PythonCppConv.cxx create mode 100644 src/runtime/PythonCppConv.hxx create mode 100644 src/runtime/PythonNeutralConv.cxx create mode 100644 src/runtime/PythonNeutralConv.hxx create mode 100644 src/runtime/PythonXMLConv.cxx create mode 100644 src/runtime/PythonXMLConv.hxx create mode 100644 src/runtime/SALOMEDispatcher.cxx create mode 100644 src/runtime/SALOMEDispatcher.hxx create mode 100644 src/runtime/SALOMERuntime.i create mode 100644 src/runtime/SALOMEconfig.h create mode 100644 src/runtime/SalomeComponent.cxx create mode 100644 src/runtime/SalomeComponent.hxx create mode 100644 src/runtime/SalomeContainer.cxx create mode 100644 src/runtime/SalomeContainer.hxx create mode 100644 src/runtime/SalomeProc.cxx create mode 100644 src/runtime/SalomeProc.hxx create mode 100644 src/runtime/SalomePythonComponent.cxx create mode 100644 src/runtime/SalomePythonComponent.hxx create mode 100644 src/runtime/SalomePythonNode.cxx create mode 100644 src/runtime/SalomePythonNode.hxx create mode 100644 src/runtime/Test/TestComponent.cxx create mode 100644 src/runtime/Test/TestComponent.hxx create mode 100644 src/runtime/Test/TestStandAlone.cxx create mode 100644 src/runtime/Test/echo_clt.cxx create mode 100755 src/runtime/Test/standaloneTest.sh create mode 100755 src/runtime/Test/xmlrun_orig.sh create mode 100644 src/runtime/XMLCppConv.cxx create mode 100644 src/runtime/XMLCppConv.hxx create mode 100644 src/runtime/XMLNeutralConv.cxx create mode 100644 src/runtime/XMLNeutralConv.hxx create mode 100644 src/runtime/XMLPythonConv.cxx create mode 100644 src/runtime/XMLPythonConv.hxx create mode 100644 src/salomeloader/Makefile.am create mode 100644 src/salomeloader/salomeloader.py create mode 100644 src/wrappergen/Makefile.am create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/AUTHORS create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/ChangeLog create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/Makefile.am create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/NEWS create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/README create mode 100755 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/ac_pkg_swig.m4 create mode 100755 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/ac_python_devel.m4 create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_Kernel.m4 create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_Med.m4 create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_hdf5.m4 create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_med2.m4 create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_pthreads.m4 create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_python.m4 create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_swig.m4 create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/enable_pthreads.m4 create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/production.m4 create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/make_begin.am create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/make_check.am create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/adm/unix/make_end.am create mode 100755 src/wrappergen/bin/Cpp_Template__SRC/archive create mode 100755 src/wrappergen/bin/Cpp_Template__SRC/build_configure create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/configure.in.base create mode 100755 src/wrappergen/bin/Cpp_Template__SRC/rfind create mode 100755 src/wrappergen/bin/Cpp_Template__SRC/root_clean create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/Cpp_Template_.cxx create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/Cpp_Template_.hxx create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/Makefile.am create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/main.cxx create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__SWIG/Cpp_Template_.i create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__SWIG/Makefile.am create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__TEST/Cpp_Template__test.py create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__TEST/Makefile.am create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Makefile.am create mode 100644 src/wrappergen/bin/Cpp_Template__SRC/src/Makefile.am create mode 100644 src/wrappergen/bin/Deprecated create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/README create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_depend_flag.m4 create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_option.m4 create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Comp_Env.m4 create mode 100755 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_GUI.m4 create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Kernel.m4 create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med.m4 create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med2.m4 create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_hdf5.m4 create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_med2.m4 create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_omniorb.m4 create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_pthreads.m4 create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/enable_pthreads.m4 create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/python.m4 create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_commence.in create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_omniorb.in create mode 100755 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/VERSION create mode 100755 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runAppli.in create mode 100755 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runSalome.py create mode 100755 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/build_configure create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/configure.in.base create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/dev_guide.txt create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/idl/HXX2SALOME_GENERIC_CLASS_NAME_Gen.idl create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/ExecHXX2SALOME_GENERIC_CLASS_NAME.png create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME.png create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_en.ps create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_en.xml create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_fr.xml create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/SalomeApp.xml create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/config create mode 100755 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME/HXX2SALOME_GENERIC_CLASS_NAME_TEST.py create mode 100755 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME/HXX2SALOME_GENERIC_CLASS_NAME_i.cxx create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME/HXX2SALOME_GENERIC_CLASS_NAME_i.hxx create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.cxx create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.h create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_icons.po create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_en.po create mode 100644 src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_fr.po create mode 100644 src/wrappergen/bin/Makefile.am create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/AUTHORS create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/COPYING create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/ChangeLog create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/INSTALL create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/Makefile.am create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/NEWS create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/README create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/Makefile.am create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/Makefile.am create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/SALOMEconfig.h.in create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/README create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cc_warnings.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_depend_flag.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_have_sstream.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_namespaces.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_option.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_template_options.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_use_std_iostream.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_warnings.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_linker_options.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Comp_Env.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_GUI.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Kernel.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med2.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_boost.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_cas.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_corba.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_hdf5.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_med2.m4 create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_msg2qm.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_omniorb.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_opengl.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_pthreads.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_python.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_qt.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/enable_pthreads.m4 create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/production.m4 create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_begin.am create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_common_starter.am create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_end.am create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/py-compile create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/Makefile.am create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/VERSION create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runAppli.in create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runSalome.py create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/build_configure create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/configure.in.base create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/Makefile.am create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/dev_guide.txt create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/rst.css create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/idl/HXX2SALOME_GENERIC_CLASS_NAME_Gen.idl create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/idl/Makefile.am create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/py-compile create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/ExecHXX2SALOME_GENERIC_CLASS_NAME.png create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME.png create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_en.ps create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_en.xml create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_fr.xml create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/Makefile.am create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/SalomeApp.xml create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/config create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/rfind create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/root_clean create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.cxx create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.h create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_icons.po create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_en.po create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_fr.po create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/Makefile.am create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_CPP/Makefile.am create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/HXX2SALOME_GENERIC_CLASS_NAME_TEST.py create mode 100755 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/HXX2SALOME_GENERIC_CLASS_NAME_i.cxx create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/HXX2SALOME_GENERIC_CLASS_NAME_i.hxx create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/Makefile.am create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_SWIG/Makefile.am create mode 100644 src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/Makefile.am create mode 100644 src/wrappergen/src/Makefile.am create mode 100644 src/wrappergen/src/compile_HXX2SALOME_GENERIC_CLASS_NAME.sh create mode 100755 src/wrappergen/src/hxx2salome create mode 100644 src/wrappergen/src/hxx2salome_check create mode 100644 src/wrappergen/src/hxx2salome_corba create mode 100644 src/wrappergen/src/hxx2salome_cpp create mode 100755 src/wrappergen/src/parse0.awk create mode 100755 src/wrappergen/src/parse01.awk create mode 100755 src/wrappergen/src/parse1.awk create mode 100755 src/wrappergen/src/parse2.awk create mode 100755 src/wrappergen/src/parse3.awk create mode 100644 src/wrappergen/src/parse30.awk create mode 100644 src/wrappergen/src/parse4.awk create mode 100644 src/wrappergen/src/parse5.awk create mode 100755 src/wrappergen/src/renameSalomeModule create mode 100755 src/wrappergen/src/runIDLparser create mode 100644 src/yacsloader/LoadState.cxx create mode 100644 src/yacsloader/LoadState.hxx create mode 100644 src/yacsloader/Makefile.am create mode 100644 src/yacsloader/README.html create mode 100644 src/yacsloader/README.txt create mode 100644 src/yacsloader/Test/Makefile.am create mode 100644 src/yacsloader/Test/TestYacsLoader.cxx create mode 100755 src/yacsloader/Test/YacsLoaderInSessionTest.sh.in create mode 100644 src/yacsloader/Test/YacsLoaderInSessionTest2.sh.in create mode 100644 src/yacsloader/Test/YacsLoaderTest.cxx create mode 100644 src/yacsloader/Test/YacsLoaderTest.hxx create mode 100755 src/yacsloader/Test/YacsLoaderTest.sh.in create mode 100644 src/yacsloader/Test/config_appli.xml.in create mode 100755 src/yacsloader/Test/display.sh.in create mode 100644 src/yacsloader/Test/echo.idl create mode 100644 src/yacsloader/Test/echoSrv.cxx create mode 100644 src/yacsloader/Test/genPascal.py create mode 100644 src/yacsloader/Test/genTriangle.py create mode 100644 src/yacsloader/Test/testEdit.py create mode 100644 src/yacsloader/Test/testExec.py create mode 100644 src/yacsloader/Test/testLoader.py create mode 100644 src/yacsloader/Test/testResume.py create mode 100644 src/yacsloader/Test/testSave.py create mode 100644 src/yacsloader/Test/waitContainers.py create mode 100755 src/yacsloader/Test/xmlrun_orig.sh create mode 100644 src/yacsloader/debugger.cxx create mode 100644 src/yacsloader/driver.cxx create mode 100644 src/yacsloader/factory.cxx create mode 100644 src/yacsloader/factory.hxx create mode 100644 src/yacsloader/loader.i create mode 100644 src/yacsloader/parsers.cxx create mode 100644 src/yacsloader/parsers.hxx create mode 100644 src/yacsloader/resume.cxx create mode 100644 src/yacsloader/samples/aschema.xml create mode 100644 src/yacsloader/samples/bid.xml create mode 100644 src/yacsloader/samples/bloc1.xml create mode 100644 src/yacsloader/samples/bloc2.xml create mode 100644 src/yacsloader/samples/bloc3.xml create mode 100644 src/yacsloader/samples/bloc4.xml create mode 100644 src/yacsloader/samples/bool1.xml create mode 100644 src/yacsloader/samples/bschema.xml create mode 100644 src/yacsloader/samples/calcium0.xml create mode 100644 src/yacsloader/samples/calcium1.xml create mode 100644 src/yacsloader/samples/calcium2.xml create mode 100644 src/yacsloader/samples/calcium3.xml create mode 100644 src/yacsloader/samples/calcium4.xml create mode 100644 src/yacsloader/samples/cpp1.xml create mode 100644 src/yacsloader/samples/cschema.xml create mode 100644 src/yacsloader/samples/double1.xml create mode 100644 src/yacsloader/samples/dschema.xml create mode 100644 src/yacsloader/samples/eschema.xml create mode 100644 src/yacsloader/samples/foreach1.xml create mode 100644 src/yacsloader/samples/foreach2.xml create mode 100644 src/yacsloader/samples/foreach3.xml create mode 100644 src/yacsloader/samples/foreach4.xml create mode 100644 src/yacsloader/samples/foreach5.xml create mode 100644 src/yacsloader/samples/foreach6.xml create mode 100644 src/yacsloader/samples/foreach_LongCorba.xml create mode 100644 src/yacsloader/samples/foreach_LongPython.xml create mode 100644 src/yacsloader/samples/forloop1.xml create mode 100644 src/yacsloader/samples/forloop2.xml create mode 100644 src/yacsloader/samples/forloop3.xml create mode 100644 src/yacsloader/samples/forloop4.xml create mode 100644 src/yacsloader/samples/forloop5.xml create mode 100644 src/yacsloader/samples/forloop6.xml create mode 100644 src/yacsloader/samples/forloop7.xml create mode 100644 src/yacsloader/samples/forwhile1.xml create mode 100644 src/yacsloader/samples/fschema.xml create mode 100644 src/yacsloader/samples/integer1.xml create mode 100644 src/yacsloader/samples/legendre7.xml create mode 100644 src/yacsloader/samples/objref1.xml create mode 100644 src/yacsloader/samples/oschema.xml create mode 100644 src/yacsloader/samples/pschema.xml create mode 100644 src/yacsloader/samples/refcnt1.xml create mode 100644 src/yacsloader/samples/refcnt2.xml create mode 100644 src/yacsloader/samples/schema.xml create mode 100644 src/yacsloader/samples/schema2.xml create mode 100644 src/yacsloader/samples/sinline1.xml create mode 100644 src/yacsloader/samples/sinline2.xml create mode 100644 src/yacsloader/samples/sinline3.xml create mode 100644 src/yacsloader/samples/sinline4.xml create mode 100644 src/yacsloader/samples/sinline5.xml create mode 100644 src/yacsloader/samples/stream1.xml create mode 100644 src/yacsloader/samples/stream2.xml create mode 100644 src/yacsloader/samples/stream3.xml create mode 100644 src/yacsloader/samples/stream4.xml create mode 100644 src/yacsloader/samples/string1.xml create mode 100644 src/yacsloader/samples/struct1.xml create mode 100644 src/yacsloader/samples/switch1.xml create mode 100644 src/yacsloader/samples/switch2.xml create mode 100644 src/yacsloader/samples/switch3.xml create mode 100644 src/yacsloader/samples/switch4.xml create mode 100644 src/yacsloader/samples/switch5.xml create mode 100644 src/yacsloader/samples/switch6.xml create mode 100644 src/yacsloader/samples/switch7.xml create mode 100644 src/yacsloader/samples/switch8.xml create mode 100644 src/yacsloader/samples/switch9.xml create mode 100644 src/yacsloader/samples/while1.xml create mode 100644 src/yacsloader/samples/while2.xml create mode 100644 src/yacsloader/samples/while3.xml create mode 100644 src/yacsloader/schema.xsd create mode 100644 src/yacsloader/xmlParserBase.cxx create mode 100644 src/yacsloader/xmlParserBase.hxx create mode 100644 src/yacsorb/Makefile.am create mode 100644 src/yacsorb/README.txt create mode 100644 src/yacsorb/YACSGui.py create mode 100644 src/yacsorb/yacs.idl create mode 100644 src/yacsorb/yacsSrv.cxx create mode 100644 src/yacsorb/yacs_clt.cxx diff --git a/Demo/Makefile.am b/Demo/Makefile.am new file mode 100644 index 000000000..b29316e4d --- /dev/null +++ b/Demo/Makefile.am @@ -0,0 +1,17 @@ +include $(top_srcdir)/adm/unix/make_begin.am + +BUILT_SOURCES = echoSK.cc schema.xml xmlrpcprog.py +bin_PROGRAMS=echoSrv +echoSrv_SOURCES = echoSrv.cxx echoSK.cc +echoSrv_CXXFLAGS = $(OMNIORB_INCLUDES) $(OMNIORB_CXXFLAGS) +echoSrv_LDFLAGS = $(OMNIORB_LIBS) +AM_CXXFLAGS = $(THREAD_DEF) + +schema.xml:schema_orig.xml + cp $(srcdir)/schema_orig.xml schema.xml +xmlrpcprog.py:xmlrpcprog_orig.py + cp $(srcdir)/xmlrpcprog_orig.py xmlrpcprog.py + +CLEANFILES = *.hh *SK.cc schema.xml xmlrpcprog.py + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/Demo/echo.idl b/Demo/echo.idl new file mode 100644 index 000000000..ca9276c10 --- /dev/null +++ b/Demo/echo.idl @@ -0,0 +1,73 @@ +#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 echoObj2(in Obj i,out Obj j) ; + void echoD(in D i,out D j) ; + void echoC(in C i,out C 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/Demo/echoSrv.cxx b/Demo/echoSrv.cxx new file mode 100644 index 000000000..e4752614f --- /dev/null +++ b/Demo/echoSrv.cxx @@ -0,0 +1,445 @@ +#include + +#include + +#include +using namespace std; + +#define _DEVDEBUG_ +#ifdef _DEVDEBUG_ +#define MYDEBTRACE {std::cerr << __FILE__ << " [" << __LINE__ << "] : ";} +#define DEBTRACE(msg) {MYDEBTRACE; std::cerr<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 echoLong(CORBA::Long 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 echoObj2(eo::Obj_ptr , eo::Obj_out); + void echoD(eo::D_ptr , eo::D_out); + void echoC(eo::C_ptr , eo::C_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) +{ + DEBTRACE("Echo_i::echoString " << mesg); + return CORBA::string_dup(mesg); +} + +void Echo_i::echoDouble(CORBA::Double i,CORBA::Double& j ) { + DEBTRACE("Echo_i::echoDouble " << i); + j=i+1; +} + +void Echo_i::echoIntVec(const eo::IntVec& in, eo::IntVec_out out) +{ + DEBTRACE("Echo_i::echoIntVec " << in.length()); + for(int i=0;i_PD_repoId); + }; + out=new eo::ObjectVec(in); +} + +void Echo_i::echoObjectVecVec(const eo::ObjectVecVec& in, eo::ObjectVecVec_out out) +{ + DEBTRACE("Echo_i::echoObjectVecVec " << in.length()); + for(int i=0;i< in.length(); i++){ + for(int j=0;j< in[i].length(); j++){ + DEBTRACE(in[i][j]->_PD_repoId); + }; + }; + out=new eo::ObjectVecVec(in); +} + +void Echo_i::echoDoubleVec(const eo::DoubleVec& in,eo::DoubleVec_out out ) +{ + DEBTRACE("Echo_i::echoDoubleVec " << in.length()); + for(int i=0;iechoLong(10); + oo=eo::C::_duplicate(o); +} + +void Echo_i::echoD(eo::D_ptr o,eo::D_out oo){ + DEBTRACE("Echo_i::echoD "); + o->echoLong2(10); + //oo=eo::D::_duplicate(o); + D_i* myD = new D_i(); + oo=myD->_this(); + myD->_remove_ref(); +} + +void Echo_i::echoObj2(eo::Obj_ptr o,eo::Obj_out oo){ + DEBTRACE("Echo_i::echoObj2 "); + o->echoLong(10); + oo=eo::Obj::_duplicate(o); +} + +eo::Obj_ptr Echo_i::echoObj(CORBA::Long i ,eo::Obj_ptr o,CORBA::Long j,eo::Obj_out oo){ + DEBTRACE("Echo_i::echoObj " << i << "," << j ); + oo=eo::Obj::_duplicate(o); + return eo::Obj::_duplicate(o); +} + +void Echo_i::createObj(CORBA::Long i ,eo::Obj_out oo){ + DEBTRACE("Echo_i::createObj " << i); + Obj_i* myobj = new Obj_i(); + CORBA::Object_var myref = myobj->_this(); + oo = eo::Obj::_narrow(myref); + myobj->_remove_ref(); +} + +void Echo_i::createC(eo::C_out oo){ + DEBTRACE("Echo_i::createC "); + 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) +{ + DEBTRACE("Echo_i::echoAll " << d << "," << l << "," << m); + dd=d; + ll=l; + s=CORBA::string_dup(m); + oo=eo::Obj::_duplicate(o); +}; + +//Implementation Obj +CORBA::Long Obj_i::echoLong(CORBA::Long i ){ + DEBTRACE("Obj_i::echoLong " << i ); + CORBA::Long j=i+1; + return j; +} + +//Implementation C +CORBA::Long C_i::echoLong(CORBA::Long i ){ + DEBTRACE("C_i::echoLong " << i); + CORBA::Long j=i+5; + return j; +} + +//Implementation D +CORBA::Long D_i::echoLong2(CORBA::Long i ){ + DEBTRACE("D_i::echoLong " << i); + CORBA::Long j=i+10; + return j; +} +CORBA::Long D_i::echoLong(CORBA::Long i ){ + DEBTRACE("D_i::echoLong " << i); + CORBA::Long j=i+1; + return j; +} + +//Implementation E +CORBA::Long E_i::echoLong2(CORBA::Long i ){ + DEBTRACE("E_i::echoLong " << i); + CORBA::Long j=i+20; + return j; +} +CORBA::Long E_i::echoLong(CORBA::Long i ){ + DEBTRACE("E_i::echoLong " << i); + 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)); + DEBTRACE("'" << (char*)sior << "'"); + myechoref = eo::Echo::_narrow(obj); + + if( !bindObjectToName(orb, myechoref,"Echo") ) 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(); + + //create object C and register it in naming service + C_i* myC = new C_i(); + obj=myC->_this(); + eo::C_var myCref=eo::C::_narrow(obj); + myC->_remove_ref(); + if( !bindObjectToName(orb, myCref,"C") ) return 1; + + //create object D and register it in naming service + D_i* myD = new D_i(); + obj=myD->_this(); + eo::D_var myDref=eo::D::_narrow(obj); + myD->_remove_ref(); + if( !bindObjectToName(orb, myDref,"D") ) return 1; + + //create object Obj and register it in naming service + Obj_i* myObj = new Obj_i(); + obj=myObj->_this(); + eo::Obj_var myObjref=eo::Obj::_narrow(obj); + myObj->_remove_ref(); + if( !bindObjectToName(orb, myObjref,"Obj") ) return 1; + } + orb->run(); + } + catch(CORBA::SystemException&) { + DEBTRACE("Caught CORBA::SystemException."); + } + catch(CORBA::Exception& ex) { + DEBTRACE("Caught CORBA::Exception." << ex); + } + catch(omniORB::fatalException& fe) { + DEBTRACE("Caught omniORB::fatalException:"); + DEBTRACE(" file: " << fe.file()); + DEBTRACE(" line: " << fe.line()); + DEBTRACE(" mesg: " << fe.errmsg()); + } + catch(...) { + DEBTRACE("Caught unknown exception." ); + } + + return 0; +} + + +////////////////////////////////////////////////////////////////////// + +static CORBA::Boolean +bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref,const char *name) +{ + 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) ) { + DEBTRACE("Failed to narrow the root naming context."); + return 0; + } + } + catch(CORBA::ORB::InvalidName& ex) { + // This should not happen! + DEBTRACE("Service required is invalid [does not exist]." ); + 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) ) { + DEBTRACE("Failed to narrow naming context."); + return 0; + } + } + + // Bind objref with name Echo to the testContext: + CosNaming::Name objectName; + objectName.length(1); + objectName[0].id = name; // 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) { + DEBTRACE("Caught system exception COMM_FAILURE -- unable to contact the " + << "naming service."); + return 0; + } + catch(CORBA::SystemException&) { + DEBTRACE("Caught a CORBA::SystemException while using the naming service."); + return 0; + } + + return 1; +} + diff --git a/Demo/schema_orig.xml b/Demo/schema_orig.xml new file mode 100644 index 000000000..63de3a17e --- /dev/null +++ b/Demo/schema_orig.xml @@ -0,0 +1,79 @@ + + + + + + a=1 + def f(p1): + global a + a=a+1 + print a + return p1 + + + + + + + def f(p1): + return p1 + + + + + + xmlsh + ./xmlrpcprog.py + echo + + + + + + def f(p1): + return p1 + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoLong + + + + + + node1 node2 + node1 node3 + node3 node4 + node4 node5 + + node1p1 + node3 p1 + node1p1 + node2 p1 + node3p1 + node4 p1 + node4p1 + node5 p1 + + node1 p1 + 32356 + + + + + + def f(p1): + print p1 + return p1 + + + + + b1 node4 + b1.b.node5p1 + node4 p1 + + diff --git a/Demo/xmlrpcprog_orig.py b/Demo/xmlrpcprog_orig.py new file mode 100755 index 000000000..051f4eb4d --- /dev/null +++ b/Demo/xmlrpcprog_orig.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +import xmlrpclib,sys + +data=""" + + echo + + hello, world + 3.5 + coucou + + +""" +def echo(args): + print args + return 96785439 + +f=open("input") +data=f.read() +f.close() + +params, method = xmlrpclib.loads(data) + +try: + call=eval(method) + response=call(params) + response = (response,) +except: + # report exception back to server + response = xmlrpclib.dumps( xmlrpclib.Fault(1, "%s:%s" % sys.exc_info()[:2])) +else: + response = xmlrpclib.dumps( response, methodresponse=1) + +print response +f=open("output",'w') +f.write(response) +f.close() diff --git a/INSTALL b/INSTALL index 96b298df3..242c679ea 100644 --- a/INSTALL +++ b/INSTALL @@ -3,20 +3,36 @@ Installation Instructions Specific part for YACS ~~~~~~~~~~~~~~~~~~~~~~ + Prerequisites ============= YACS needs: - g++ 3.3.5 or more, - CPPUNIT - omniORB 4.05 or more, - - Python + - Python, + - SALOME 3.2.x KERNEL (for SALOME tests) + +**WARNINGS**: + - with g++>= 4.1, problem with CORBA::Any and double, for omniORB <= 4.0.7 + You need to take the latest omniORB cvs snapshot from http://omniorb.sourceforge.net/snapshots Build and check =============== +SALOME is required for directories runtime and yacsloader. For tests with make check, +we suppose that all SALOME _ROOT_DIR are in a directory under a name +/_, for instance $HOME/SALOME/KERNEL_V3_2_3. +We also suppose that there a script that sets prerequisites environment for SALOME +under the name /profile_. +So, to define SALOME installation, just KERNEL_ROOT_DIR is required. Other path +are deduced. + build and install are done in separate directories, not in source directory. For instance, if the path to YACS sources is ${BASEREP}/YACS_SRC:: + export KERNEL_ROOT_DIR=... + cd ${BASEREP} rm -rf build install mkdir build install @@ -48,7 +64,7 @@ Basic Installation These are generic installation instructions. - The `configure' shell script attempts to guess correct values for +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 @@ -57,20 +73,20 @@ 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' +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 +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 +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'. diff --git a/Makefile.am b/Makefile.am index 2cad62a26..152af0d96 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,2 +1,14 @@ +include $(top_srcdir)/adm/unix/make_begin.am + +if SALOME_KERNEL + SUBDIRS = idl src doc +else + SUBDIRS = src doc +endif + +install-exec-hook: + if [ "x`uname -m`" == "xx86_64" ] ; then cd ${prefix} && ln -sf lib64 lib ; fi + +check-local: + cat /tmp/${USER}/UnitTestsResult -SUBDIRS = src diff --git a/Misc/valgrind-python.supp b/Misc/valgrind-python.supp new file mode 100644 index 000000000..6b444b9db --- /dev/null +++ b/Misc/valgrind-python.supp @@ -0,0 +1,216 @@ +# +# This is a valgrind suppression file that should be used when using valgrind. +# +# Here's an example of running valgrind: +# +# cd python/dist/src +# valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \ +# ./python -E -tt ./Lib/test/regrtest.py -u bsddb,network +# +# You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER +# to use the preferred suppressions with Py_ADDRESS_IN_RANGE. +# +# If you do not want to recompile Python, you can uncomment +# suppressions for PyObject_Free and PyObject_Realloc. +# +# See Misc/README.valgrind for more information. + +# all tool names: Addrcheck,Memcheck,cachegrind,helgrind,massif +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Addr4 + fun:Py_ADDRESS_IN_RANGE +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Value4 + fun:Py_ADDRESS_IN_RANGE +} + +{ + ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value + Memcheck:Cond + fun:Py_ADDRESS_IN_RANGE +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Addr4 + fun:PyObject_Free +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Value4 + fun:PyObject_Free +} + +{ + ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value + Memcheck:Cond + fun:PyObject_Free +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Addr4 + fun:PyObject_Realloc +} + +{ + ADDRESS_IN_RANGE/Invalid read of size 4 + Memcheck:Value4 + fun:PyObject_Realloc +} + +{ + ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value + Memcheck:Cond + fun:PyObject_Realloc +} + +### +### All the suppressions below are for errors that occur within libraries +### that Python uses. The problems to not appear to be related to Python's +### use of the libraries. +### +{ + GDBM problems, see test_gdbm + Memcheck:Param + write(buf) + fun:write + fun:gdbm_open + +} + +### +### These occur from somewhere within the SSL, when running +### test_socket_sll. They are too general to leave on by default. +### +###{ +### somewhere in SSL stuff +### Memcheck:Cond +### fun:memset +###} +###{ +### somewhere in SSL stuff +### Memcheck:Value4 +### fun:memset +###} +### +###{ +### somewhere in SSL stuff +### Memcheck:Cond +### fun:MD5_Update +###} +### +###{ +### somewhere in SSL stuff +### Memcheck:Value4 +### fun:MD5_Update +###} + +# +# All of these problems come from using test_socket_ssl +# +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_bin2bn +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_num_bits_word +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:BN_num_bits_word +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_mod_exp_mont_word +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BN_mod_exp_mont +} + +{ + from test_socket_ssl + Memcheck:Param + write(buf) + fun:write + obj:/usr/lib/libcrypto.so.0.9.7 +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:RSA_verify +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:RSA_verify +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:DES_set_key_unchecked +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:DES_encrypt2 +} + +{ + from test_socket_ssl + Memcheck:Cond + obj:/usr/lib/libssl.so.0.9.7 +} + +{ + from test_socket_ssl + Memcheck:Value4 + obj:/usr/lib/libssl.so.0.9.7 +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:BUF_MEM_grow_clean +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:memcpy + fun:ssl3_read_bytes +} + +{ + from test_socket_ssl + Memcheck:Cond + fun:SHA1_Update +} + +{ + from test_socket_ssl + Memcheck:Value4 + fun:SHA1_Update +} + + diff --git a/README b/README index 6d0a46bbd..0d46d9b0e 100644 --- a/README +++ b/README @@ -18,10 +18,52 @@ Fonction de v - inventaire des ports de donnée entrants non initialisés et non connectés. - faut-il vérifier quelque chose pour les gates ? - +Regles d'ecriture C++ à definir : + - pas de clause using namespace dans les .hxx + - prefixer les attributs de classe par _ + - indentation style gnu + - utilisation des namespace dans les cxx + - nom complets dans les declarations (identité avec .hxx pour doxygen) IMPROVEMENTS : -- OutGate::isAlreadyInList : use std::find -- Bloc::checkNoCyclePassingThrough : first loop iter1=currentNodesToTest.erase(iter1) as last argument +- keep namespace YACS::ENGINE only for engine. +- test Loop::init : initialization of InputPort of Node inside the + Loop overwrite by an in-link +- bug CC : loop in bloc initialized with 0 and overloaded by previous + node. +- several outputports of a switch case linked to a same inputport +- Add some tests on link update when ForLoop or WhileLoop node is removed +- No backlinks authorized in ForEachLoop +- ComposedNode::edAddLink : perform getAllRepresentants before on +start port. catch exception to cleanly destroy all delegates +eventually done before +- Call init after clone of internal node in ForEach. +- getDeploymentTree during running. idem for edGetDirectDescendants +for DynParaLoop. +- check that restoreInit should not been called in InputPort copy + constructor. A test with ForEachLoop should be performed with edInit + value inside. +- throw OutputPort::exInit. Apparently useless. +- CollectorSwOutPort managing several OutPorts per branch. +- Switch inter branches forbidden ; check. + +CHECKLIST: + +- methode load non bloquante. +- revoir getQualifiedName dans Node pour eviter dynamic_cast vers switch + +- test foreach4.xml problemes sporadiques (CC) sur conversions de doubles + +- ecriture graphe XML : + - ajout attribut _isComponentMethod initialisé a true pour noeuds SALOME + est-ce utile ? + - / dans bschema, cschema, dschema... + - calcium*.xml + - foreach1.xml: , datalink manquant, en trop + - refcnt1.xml: , en trop + - stream1.xml: , ... + - ordre ecriture types + - verifier schema, schema2, fschema, oschema, pschema... + diff --git a/adm/unix/config_files/ac_cxx_option.m4 b/adm/unix/config_files/ac_cxx_option.m4 new file mode 100644 index 000000000..d1f43ea6a --- /dev/null +++ b/adm/unix/config_files/ac_cxx_option.m4 @@ -0,0 +1,46 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl @synopsis AC_CXX_OPTION(-option,variable where we add option if ok,action if ok; action if not ok) +dnl +dnl Check options for C++ compiler +dnl +dnl @author Bernard Secher - 15/01/2004 +dnl +AC_DEFUN([AC_CXX_OPTION], [ + AC_MSG_CHECKING(wether $CXX accepts $1) + cat > conftest.cxx < conftest.log 2>&1 + var=`echo $1 | sed -e "s, .*$,," | sed -e "s,^-,,"` +#CCRT if ! grep -e $var conftest.log > /dev/null 2>&1 ; then + if grep -e $var conftest.log > /dev/null 2>&1 ; then + AC_MSG_RESULT(no) + eval $4 + else + AC_MSG_RESULT(yes) + $2="${$2} $1" + eval $3 + fi +]) + + diff --git a/adm/unix/config_files/ac_linker_options.m4 b/adm/unix/config_files/ac_linker_options.m4 new file mode 100644 index 000000000..9006a46fe --- /dev/null +++ b/adm/unix/config_files/ac_linker_options.m4 @@ -0,0 +1,57 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl @synopsis AC_LINKER_OPTIONS +dnl +dnl Check warning flags for C++ compiler to control warning messages +dnl +dnl @author Bernard Secher (CEA) - 04/12/2003 +dnl +AC_DEFUN([AC_LINKER_OPTIONS],[ + + AC_CHECKING(for LIB_LOCATION_SUFFIX) + LIB_LOCATION_SUFFIX="" + case "$build_cpu" in + x86_64*) LIB_LOCATION_SUFFIX="64" ;; + *) LIB_LOCATION_SUFFIX="" ;; + esac + AC_SUBST(LIB_LOCATION_SUFFIX) + AC_MSG_RESULT(LIB_LOCATION_SUFFIX is $LIB_LOCATION_SUFFIX) + + for opt in "-Xlinker -export-dynamic" -transitive_link; do + AC_CXX_OPTION($opt,LDEXPDYNFLAGS,flag=yes,flag=no) + if test "$flag" = "yes"; then + break + fi + done + AC_SUBST(LDEXPDYNFLAGS) + +dnl + case $host_os in + osf*) + STDLIB="-lcxxstd" + ;; + *) + STDLIB="-lstdc++" + ;; + esac + AC_SUBST(STDLIB) +]) diff --git a/adm/unix/config_files/ac_pkg_swig.m4 b/adm/unix/config_files/ac_pkg_swig.m4 index 6810ca27b..625a01251 100755 --- a/adm/unix/config_files/ac_pkg_swig.m4 +++ b/adm/unix/config_files/ac_pkg_swig.m4 @@ -22,6 +22,7 @@ dnl Andrew Collier . dnl dnl AC_DEFUN([AC_PROG_SWIG],[ + swig_ok=no AC_PATH_PROG([SWIG],[swig]) if test -z "$SWIG" ; then AC_MSG_WARN([cannot find 'swig' program. You should look at http://www.swig.org]) @@ -70,6 +71,7 @@ AC_DEFUN([AC_PROG_SWIG],[ SWIG='echo "Error: SWIG version >= $1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false' else AC_MSG_NOTICE([SWIG executable is '$SWIG']) + swig_ok=yes SWIG_LIB=`$SWIG -swiglib` AC_MSG_NOTICE([SWIG runtime library directory is '$SWIG_LIB']) fi diff --git a/adm/unix/config_files/ac_prog_esope.m4 b/adm/unix/config_files/ac_prog_esope.m4 deleted file mode 100755 index 4b9e42c23..000000000 --- a/adm/unix/config_files/ac_prog_esope.m4 +++ /dev/null @@ -1,50 +0,0 @@ -# Check availability of Med binary distribution -# -# Author : Anthony GEAY (CEA, 2005) -# - -AC_DEFUN([AC_PROG_ESOPE],[ -CHECK_MED - -AC_CHECKING(for Esope) - -srcdirea=`( cd $srcdir && pwd )` - -esope_ok=yes - -AC_ARG_WITH(esope, - [ --with-esope=EXEC esope executable ], - [ESOPE="$withval" - AC_MSG_RESULT("select $withval as esope executable") - ], [ - AC_PATH_PROG(ESOPE, esopv10_0) - ]) -if test "x$ESOPE" = "x" ; -then - ESOPE=$srcdirea/bin/esopv10_0 - AC_MSG_RESULT(use esope furnished in sources at location : $ESOPE) -fi -AC_SUBST(ESOPE) - -dnl --- To improve UNIX 32 -EFLAGS="ESOPE=2000000,NORME=TRADUCTEUR,FORT=UNIX32" -AC_SUBST(EFLAGS) - -AC_PATH_PROG(CPPFORESOPE, cpp) -if test "x$CPPFORESOPE" = "x" ; -then - esope_ok=no - AC_MSG_RESULT(cpp not found in PATH !!! - used by esope to generate Fortran files) -fi -AC_SUBST(CPPFORESOPE) - -CPPFORESOPEFLAGS="-Dunix32 -Dlinux ${MED_INCLUDES}" -AC_SUBST(CPPFORESOPEFLAGS) -dnl --- Segment directory -SEGMENTS_DIR="-I"$srcdirea/bin/SEGMENTS -AC_SUBST(SEGMENTS_DIR) - -AC_MSG_RESULT(for Esope: $esope_ok) - -])dnl - diff --git a/adm/unix/config_files/ac_python_devel.m4 b/adm/unix/config_files/ac_python_devel.m4 index e0ac20c9c..1988fef1a 100755 --- a/adm/unix/config_files/ac_python_devel.m4 +++ b/adm/unix/config_files/ac_python_devel.m4 @@ -57,4 +57,15 @@ AC_DEFUN([AC_PYTHON_DEVEL],[ print conf('LOCALMODLIBS')+' '+conf('LIBS')" AC_MSG_RESULT($PYTHON_EXTRA_LIBS)` AC_SUBST(PYTHON_EXTRA_LIBS) + # + # linking flags needed when embedding + # + AC_MSG_CHECKING(python extra linking flags) + if test -z "$PYTHON_EXTRA_LDFLAGS"; then + PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \ + conf = distutils.sysconfig.get_config_var; \ + print conf('LINKFORSHARED')"` + fi + AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS]) + AC_SUBST(PYTHON_EXTRA_LDFLAGS) ]) diff --git a/adm/unix/config_files/check_SALOME.m4 b/adm/unix/config_files/check_SALOME.m4 new file mode 100644 index 000000000..d3a43d675 --- /dev/null +++ b/adm/unix/config_files/check_SALOME.m4 @@ -0,0 +1,349 @@ +# ----------------------------------------------------------------------------- +# --- from KERNEL_SRC 3.2.3 +# Check availability of Salome's KERNEL binary distribution +# +# Author : Jerome Roy (CEA, 2003) +# + +AC_DEFUN([CHECK_KERNEL],[ +AC_REQUIRE([AC_LINKER_OPTIONS])dnl + +AC_CHECKING(for Kernel) + +Kernel_ok=no + +KERNEL_LDFLAGS="" +KERNEL_CXXFLAGS="" + +AC_ARG_WITH(kernel, + [--with-kernel=DIR root directory path of KERNEL build or installation], + [KERNEL_DIR="$withval"], + [KERNEL_DIR=""]) + +if test "x${KERNEL_DIR}" = "x" ; then + AC_MSG_RESULT(for \${KERNEL_ROOT_DIR}: ${KERNEL_ROOT_DIR}) + # no --with-kernel-dir option used + if test "x${KERNEL_ROOT_DIR}" != "x" ; then + # KERNEL_ROOT_DIR environment variable defined + KERNEL_DIR=${KERNEL_ROOT_DIR} + else + # search Kernel binaries in PATH variable + AC_PATH_PROG(TEMP,runSalome) + if test "x${TEMP}" != "x" ; then + AC_MSG_RESULT(runSalome was found at : ${TEMP}) + KERNEL_BIN_DIR=`dirname ${TEMP}` + KERNEL_DIR=`cd ${KERNEL_BIN_DIR}/../..; pwd` + fi + fi +fi + +if test -f ${KERNEL_DIR}/bin/salome/runSalome ; then + AC_MSG_RESULT(Using Kernel module distribution in ${KERNEL_DIR}) + Kernel_ok=yes + + if test "x${KERNEL_ROOT_DIR}" = "x" ; then + KERNEL_ROOT_DIR=${KERNEL_DIR} + fi + + if test "x${KERNEL_SITE_DIR}" = "x" ; then + KERNEL_SITE_DIR=${KERNEL_ROOT_DIR} + fi + + AC_SUBST(KERNEL_ROOT_DIR) + AC_SUBST(KERNEL_SITE_DIR) + + KERNEL_LDFLAGS=-L${KERNEL_DIR}/lib${LIB_LOCATION_SUFFIX}/salome + KERNEL_CXXFLAGS=-I${KERNEL_DIR}/include/salome + + AC_SUBST(KERNEL_LDFLAGS) + AC_SUBST(KERNEL_CXXFLAGS) +else + AC_MSG_WARN("Cannot find compiled Kernel module distribution") +fi + +AC_MSG_RESULT(for Kernel: $Kernel_ok) + +])dnl + +# ----------------------------------------------------------------------------- +# --- from GUI_SRC 3.2.3 +# Check availability of Salome binary distribution +# +# Author : Marc Tajchman (CEA, 2002) +#------------------------------------------------------------ + +AC_DEFUN([CHECK_GUI],[ +AC_REQUIRE([AC_LINKER_OPTIONS])dnl + +AC_CHECKING(for $2 $1 ) + +SalomeGUI_ok=no + +GUI_LDFLAGS="" +GUI_CXXFLAGS="" + +AC_ARG_WITH(gui, + --with-salome_gui=DIR root directory path of SALOME GUI installation, + SALOME_GUI_DIR="$withval",SALOME_GUI_DIR="") + +if test "x${SALOME_GUI_DIR}" = "x" ; then + # no --with-gui-dir option used + AC_MSG_RESULT(try \${GUI_ROOT_DIR}: ${GUI_ROOT_DIR}) + if test "x${GUI_ROOT_DIR}" != "x" ; then + # SALOME_ROOT_DIR environment variable defined + SALOME_GUI_DIR=${GUI_ROOT_DIR} + else + # search Salome binaries in PATH variable + AC_PATH_PROG(TEMP, $1) + if test "x${TEMP}" != "x" ; then + AC_MSG_RESULT($1 was found at : ${TEMP}) + SALOME_BIN_DIR=`dirname ${TEMP}` + SALOME_GUI_DIR=`cd ${SALOME_BIN_DIR}/../..; pwd` + fi + fi +fi + +if test -f ${SALOME_GUI_DIR}/bin/salome/$1 ; then + SalomeGUI_ok=yes + AC_MSG_RESULT(Using SALOME GUI distribution in ${SALOME_GUI_DIR}) + + if test "x${GUI_ROOT_DIR}" == "x" ; then + GUI_ROOT_DIR=${SALOME_GUI_DIR} + fi + + AC_SUBST(GUI_ROOT_DIR) + + GUI_LDFLAGS=-L${SALOME_GUI_DIR}/lib${LIB_LOCATION_SUFFIX}/salome + GUI_CXXFLAGS=-I${SALOME_GUI_DIR}/include/salome + + AC_SUBST(GUI_LDFLAGS) + AC_SUBST(GUI_CXXFLAGS) +else + AC_MSG_WARN("Cannot find compiled SALOME GUI distribution") +fi + +AC_MSG_RESULT(for $2: ${SalomeGUI_ok}) + +])dnl + +AC_DEFUN([CHECK_SALOME_GUI],[ + CHECK_GUI([SUITApp], + [SALOME GUI]) +])dnl + +# ----------------------------------------------------------------------------- +# --- from PYHELLO1_SRC 3.2.3 +# Check availability of PYHELLO binary distribution +# +# Author : Marc Tajchman (CEA, 2002) +#------------------------------------------------------------ + +AC_DEFUN([CHECK_PYHELLO],[ + +AC_CHECKING(for PyHello) + +PyHello_ok=no + +AC_ARG_WITH(pyHello, + --with-py-hello=DIR root directory path of PYHELLO installation, + PYHELLO_DIR="$withval",PYHELLO_DIR="") + +if test "x$PYHELLO_DIR" = "x" ; then + +# no --with-py-hello option used + + if test "x$PYHELLO_ROOT_DIR" != "x" ; then + + # PYHELLO_ROOT_DIR environment variable defined + PYHELLO_DIR=$PYHELLO_ROOT_DIR + + else + + # search PyHello binaries in PATH variable + AC_PATH_PROG(TEMP, PYHELLOGUI.py) + if test "x$TEMP" != "x" ; then + PYHELLO_BIN_DIR=`dirname $TEMP` + PYHELLO_DIR=`dirname $PYHELLO_BIN_DIR` + fi + + fi +# +fi + +if test -f ${PYHELLO_DIR}/bin/salome/PYHELLOGUI.py ; then + PyHello_ok=yes + AC_MSG_RESULT(Using PYHELLO distribution in ${PYHELLO_DIR}) + + if test "x$PYHELLO_ROOT_DIR" == "x" ; then + PYHELLO_ROOT_DIR=${PYHELLO_DIR} + fi + AC_SUBST(PYHELLO_ROOT_DIR) +else + AC_MSG_WARN("Cannot find compiled PYHELLO distribution") +fi + +AC_MSG_RESULT(for PYHELLO: $PyHello_ok) + +])dnl + +# ----------------------------------------------------------------------------- +# --- from GEOM_SRC 3.2.3 +# Check availability of Geom binary distribution +# +# Author : Nicolas REJNERI (OPEN CASCADE, 2003) +# + +AC_DEFUN([CHECK_GEOM],[ + +AC_CHECKING(for Geom) + +Geom_ok=no + +GEOM_LDFLAGS="" +GEOM_CXXFLAGS="" + +AC_ARG_WITH(geom, + [ --with-geom=DIR root directory path of GEOM installation ], + GEOM_DIR="$withval",GEOM_DIR="") + +if test "x$GEOM_DIR" == "x" ; then + +# no --with-geom-dir option used + + if test "x$GEOM_ROOT_DIR" != "x" ; then + + # GEOM_ROOT_DIR environment variable defined + GEOM_DIR=$GEOM_ROOT_DIR + + else + + # search Geom binaries in PATH variable + AC_PATH_PROG(TEMP, libGEOM_Swig.py) + if test "x$TEMP" != "x" ; then + GEOM_BIN_DIR=`dirname $TEMP` + GEOM_DIR=`dirname $GEOM_BIN_DIR` + fi + + fi +# +fi + +if test -f ${GEOM_DIR}/bin/salome/libGEOM_Swig.py ; then + Geom_ok=yes + AC_MSG_RESULT(Using Geom module distribution in ${GEOM_DIR}) + + if test "x$GEOM_ROOT_DIR" == "x" ; then + GEOM_ROOT_DIR=${GEOM_DIR} + fi + AC_SUBST(GEOM_ROOT_DIR) + + GEOM_LDFLAGS=-L${GEOM_DIR}/lib${LIB_LOCATION_SUFFIX}/salome + GEOM_CXXFLAGS=-I${GEOM_DIR}/include/salome + + AC_SUBST(GEOM_LDFLAGS) + AC_SUBST(GEOM_CXXFLAGS) + +else + AC_MSG_WARN("Cannot find compiled Geom module distribution") +fi + +AC_MSG_RESULT(for Geom: $Geom_ok) + +])dnl + +# ----------------------------------------------------------------------------- +# --- from VISU_SRC 3.2.3 +########################################################### +# File : check_Visu.m4 +# Author : Vadim SANDLER (OCN) +# Created : 13/07/05 +# Copyright (C) 2005 Open CASCADE +# Check availability of VISU binary distribution +########################################################### + +AC_DEFUN([CHECK_VISU],[ + +AC_CHECKING(for VISU) + +Visu_ok=no + +VISU_LDFLAGS="" +VISU_CXXFLAGS="" + + +AC_ARG_WITH(visu, + [ --with-visu=DIR root directory path of VISU module installation ], + VISU_DIR="$withval",VISU_DIR="") + +if test "x$VISU_DIR" == "x" ; then + # no --with-visu-dir option used + if test "x$VISU_ROOT_DIR" != "x" ; then + # VISU_ROOT_DIR environment variable defined + VISU_DIR=$VISU_ROOT_DIR + fi +fi + +if test -f ${VISU_DIR}/idl/salome/VISU_Gen.idl ; then + Visu_ok=yes + AC_MSG_RESULT(Using VISU module distribution in ${VISU_DIR}) + + if test "x$VISU_ROOT_DIR" == "x" ; then + VISU_ROOT_DIR=${VISU_DIR} + fi + AC_SUBST(VISU_ROOT_DIR) + + VISU_LDFLAGS=-L${VISU_DIR}/lib${LIB_LOCATION_SUFFIX}/salome + VISU_CXXFLAGS=-I${VISU_DIR}/include/salome + + AC_SUBST(VISU_LDFLAGS) + AC_SUBST(VISU_CXXFLAGS) + +else + AC_MSG_WARN("Cannot find VISU module sources") +fi + +AC_MSG_RESULT(for VISU: $Visu_ok) + +])dnl + +# ----------------------------------------------------------------------------- + +AC_DEFUN([CHECK_SALOME_ENV],[ + +AC_CHECKING(for SALOME_ENV) + +Salome_Env_ok=no + +AC_ARG_WITH(salome_env, + [ --with-salome_env= path of script that sets salome prerequisites ], + SALOME_ENV_PATH="$withval",SALOME_ENV_PATH="") + +if test "x$SALOME_ENV_PATH" == "x" ; then + # no --with-salome_env option used + if test "x$PREREQUISITE_SH" != "x" ; then + # PREREQUISITE_SH environment variable defined + SALOME_ENV_PATH=$PREREQUISITE_SH + fi +fi + +if test "x$SALOME_ENV_PATH" != "x" ; then + if test -f ${SALOME_ENV_PATH} ; then + Salome_Env_ok=yes + AC_MSG_RESULT(Using script ${SALOME_ENV_PATH} for salome prerequisites in tests) + + if test "x$PREREQUISITE_SH" == "x" ; then + PREREQUISITE_SH=${SALOME_ENV_PATH} + fi + AC_SUBST(PREREQUISITE_SH) + fi +fi + +if test -f ${SALOME_ENV_PATH} ; then + AC_MSG_RESULT(for SALOME_ENV: $Salome_Env_ok) +else + AC_MSG_WARN("Cannot find SALOME_ENV module sources") + AC_MSG_RESULT(for SALOME_ENV: $Salome_Env_ok) +fi + +])dnl + diff --git a/adm/unix/config_files/check_cas.m4 b/adm/unix/config_files/check_cas.m4 new file mode 100755 index 000000000..ab2ba319d --- /dev/null +++ b/adm/unix/config_files/check_cas.m4 @@ -0,0 +1,238 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +AC_DEFUN([CHECK_CAS],[ +AC_REQUIRE([AC_PROG_CXX])dnl +AC_REQUIRE([AC_PROG_CXXCPP])dnl + +AC_CHECKING(for OpenCascade) + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +AC_SUBST(CAS_CPPFLAGS) +AC_SUBST(CAS_CXXFLAGS) +AC_SUBST(CAS_KERNEL) +AC_SUBST(CAS_MATH) +AC_SUBST(CAS_VIEWER) +AC_SUBST(CAS_TKTopAlgo) +AC_SUBST(CAS_MODELER) +AC_SUBST(CAS_OCAF) +AC_SUBST(CAS_OCAFVIS) +AC_SUBST(CAS_DATAEXCHANGE) +AC_SUBST(CAS_LDFLAGS) +AC_SUBST(CAS_LDPATH) +AC_SUBST(CAS_STDPLUGIN) + +CAS_CPPFLAGS="" +CAS_CXXFLAGS="" +CAS_LDFLAGS="" +occ_ok=no +config_h=no + +dnl libraries directory location +case $host_os in + linux*) + casdir=Linux + ;; + freebsd*) + casdir=Linux + ;; + irix5.*) + casdir=Linux + ;; + irix6.*) + casdir=Linux + ;; + osf*) + casdir=Linux + ;; + solaris2.*) + casdir=Linux + ;; + *) + casdir=Linux + ;; +esac + +AC_MSG_CHECKING(for OpenCascade directories) + +if test -z "$CASROOT"; then + AC_MSG_RESULT(CASROOT not defined) + for d in `echo $LD_LIBRARY_PATH | sed -e "s/:/ /g"` ; do + if test -f $d/libTKernel.so ; then + AC_MSG_RESULT(libTKernel.so detected in $d) + CASROOT=$d + CASROOT=`echo ${CASROOT} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + break + fi + done +fi + +if test -d ${CASROOT}/${casdir}/lib; then + CAS_LDPATH="-L$CASROOT/$casdir/lib " + AC_MSG_RESULT(yes) +else + if test -d ${CASROOT}/lib; then + CAS_LDPATH="-L$CASROOT/lib " + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi +fi + + +dnl were is OCC ? +if test -z "$CASROOT"; then + AC_MSG_WARN(You must provide CASROOT variable : see OCC installation manual) +else + occ_ok=yes + OCC_VERSION_MAJOR=0 + OCC_VERSION_MINOR=0 + OCC_VERSION_MAINTENANCE=0 + ff=$CASROOT/inc/Standard_Version.hxx + if test -f $ff ; then + grep "define OCC_VERSION_MAJOR" $ff > /dev/null + if test $? = 0 ; then + OCC_VERSION_MAJOR=`grep "define OCC_VERSION_MAJOR" $ff | awk '{i=3 ; print $i}'` + fi + grep "define OCC_VERSION_MINOR" $ff > /dev/null + if test $? = 0 ; then + OCC_VERSION_MINOR=`grep "define OCC_VERSION_MINOR" $ff | awk '{i=3 ; print $i}'` + fi + grep "define OCC_VERSION_MAINTENANCE" $ff > /dev/null + if test $? = 0 ; then + OCC_VERSION_MAINTENANCE=`grep "define OCC_VERSION_MAINTENANCE" $ff | awk '{i=3 ; print $i}'` + fi + fi +fi + +if test "x$occ_ok" = "xyes"; then + +dnl test c++ compiler flag for unsigned character + for opt in -funsigned-char -unsigned ; do + AC_CXX_OPTION($opt,CAS_CXXFLAGS,flag=yes,flag=no) + if test "$flag" = "yes"; then + break + fi + done + +dnl cascade headers + + CPPFLAGS_old="$CPPFLAGS" +case $host_os in + linux*) + CAS_CPPFLAGS="-DOCC_VERSION_MAJOR=$OCC_VERSION_MAJOR -DOCC_VERSION_MINOR=$OCC_VERSION_MINOR -DOCC_VERSION_MAINTENANCE=$OCC_VERSION_MAINTENANCE -DLIN -DLINTEL -DCSFDB -DNo_exception -DHAVE_CONFIG_H -DHAVE_LIMITS_H -DHAVE_WOK_CONFIG_H" + + OCC_VERSION_STRING="$OCC_VERSION_MAJOR.$OCC_VERSION_MINOR.$OCC_VERSION_MAINTENANCE" + case $OCC_VERSION_STRING in + [[0-5]].* | 6.0.* | 6.1.0) # catch versions < 6.1.1 + CAS_CPPFLAGS="$CAS_CPPFLAGS -DNO_CXX_EXCEPTION" + ;; + *) + CAS_CPPFLAGS="$CAS_CPPFLAGS -DOCC_CONVERT_SIGNALS" + ;; + esac + CAS_CPPFLAGS="$CAS_CPPFLAGS -I$CASROOT/inc" + ;; + osf*) + CAS_CPPFLAGS="-DOCC_VERSION_MAJOR=$OCC_VERSION_MAJOR -DOCC_VERSION_MINOR=$OCC_VERSION_MINOR -DOCC_VERSION_MAINTENANCE=$OCC_VERSION_MAINTENANCE -DLIN -DLINTEL -DCSFDB -DNo_exception -DHAVE_CONFIG_H -DHAVE_LIMITS_H -DHAVE_WOK_CONFIG_H -I$CASROOT/inc" + ;; +esac + CPPFLAGS="$CPPFLAGS $CAS_CPPFLAGS" + + echo + echo testing config.h + + AC_CHECK_HEADER(config.h, config_h=yes, [ + echo "config.h file not found!" + ]) + + if test "x$config_h" = xno ; then + AC_MSG_WARN(config.h file not found) + dnl There is no consequence for SALOME building because + dnl this file is not used. SALOME uses SALOMEconfig.h instead! + else + AC_MSG_RESULT(config.h file ok) + fi + + AC_CHECK_HEADER(Standard_Type.hxx,occ_ok=yes ,occ_ok=no) + +fi + +if test "x$occ_ok" = xyes ; then + + AC_MSG_CHECKING(for OpenCascade libraries) + + LIBS_old="$LIBS" + LIBS="$LIBS $CAS_LDPATH -lTKernel" + + AC_CACHE_VAL(salome_cv_lib_occ,[ + AC_TRY_LINK( +#include +, size_t size; + TCollection_AsciiString aStr ("toto"); + aStr.Capitalize();, + eval "salome_cv_lib_occ=yes",eval "salome_cv_lib_occ=no") + ]) + occ_ok="$salome_cv_lib_occ" + +fi +CPPFLAGS="$CPPFLAGS_old" +LIBS="$LIBS_old" + +if test "x$occ_ok" = xno ; then + AC_MSG_RESULT(no) + AC_MSG_WARN(Opencascade libraries not found) +else + AC_MSG_RESULT(yes) + CAS_KERNEL="$CAS_LDPATH -lTKernel" + CAS_MATH="$CAS_LDPATH -lTKMath" + + if test -f $CASROOT/$casdir/lib/libStdPlugin.so ; then + # this libraries are only for CASCADE 5.2.3 + CAS_STDPLUGIN="StdPlugin" + fi + + CAS_OCAF="$CAS_LDPATH -lPTKernel -lTKernel -lTKCDF -lTKLCAF -lTKPCAF -lTKStdSchema" + CAS_OCAFVIS="$CAS_LDPATH -lTKCAF -lStdPlugin -lStdLPlugin -lTKPLCAF -lTKPShape -lTKStdLSchema -lTKShapeSchema" + + CAS_TKV3d="$CAS_LDPATH -lTKV3d" + CAS_VIEWER="$CAS_TKV3d -lTKService" + + CAS_TKBRep="$CAS_LDPATH -lTKG2d -lTKG3d -lTKGeomBase -lTKBRep" + + CAS_TKTopAlgo="$CAS_TKBRep -lTKGeomAlgo -lTKTopAlgo" + CAS_TKPrim="$CAS_TKTopAlgo -lTKPrim" + + CAS_MODELER="$CAS_TKPrim -lTKBO -lTKBool -lTKHLR -lTKFillet -lTKOffset -lTKFeat" + + CAS_DATAEXCHANGE="$CAS_LDPATH -lTKIGES -lTKSTEP" + + CAS_LDFLAGS="$CAS_KERNEL $CAS_MATH $CAS_OCAF $CAS_OCAFVIS $CAS_VIEWER $CAS_MODELER $CAS_DATAEXCHANGE" + +fi + +AC_LANG_RESTORE + +])dnl + + diff --git a/adm/unix/config_files/check_expat.m4 b/adm/unix/config_files/check_expat.m4 new file mode 100644 index 000000000..98bb5d18e --- /dev/null +++ b/adm/unix/config_files/check_expat.m4 @@ -0,0 +1,20 @@ + +AC_DEFUN([AC_CHECK_EXPAT],[ + +AC_CHECKING(for expat) + +AC_CHECK_HEADER(expat.h,expat_ok="yes",expat_ok="no") + +if test "x$expat_ok" = "xyes" +then + AC_CHECK_LIB(expat,XML_ExpatVersionInfo, LIBS="-lexpat $LIBS",,) +fi + +AC_MSG_RESULT(for expat: $expat_ok) + +EXPAT_LIBS=$LIBS +AC_SUBST(EXPAT_LIBS) + +])dnl +dnl + diff --git a/adm/unix/config_files/check_htmlgen.m4 b/adm/unix/config_files/check_htmlgen.m4 new file mode 100644 index 000000000..7130999b3 --- /dev/null +++ b/adm/unix/config_files/check_htmlgen.m4 @@ -0,0 +1,112 @@ +dnl Copyright (C) 2003 CEA/DEN, EDF R&D + +AC_DEFUN([CHECK_HTML_GENERATORS],[ + +AC_CHECKING(for html generators) + +doxygen_ok=yes +dnl were is doxygen ? +AC_PATH_PROG(DOXYGEN,doxygen) +if test "x$DOXYGEN" = "x" +then + AC_MSG_WARN(doxygen not found) + doxygen_ok=no +fi +if test "x$doxygen_ok" = "xyes" +then + version=`$DOXYGEN --version` + AC_MSG_RESULT(doxygen version $version) + case "$version" in + 1.4.4*) + DOXYGEN_WITH_PYTHON=yes + DOXYGEN_WITH_STL=no + ;; + 1.4.5*) + DOXYGEN_WITH_PYTHON=yes + DOXYGEN_WITH_STL=yes + ;; + 1.4.6*) + DOXYGEN_WITH_PYTHON=yes + DOXYGEN_WITH_STL=yes + ;; + 1.4.7*) + DOXYGEN_WITH_PYTHON=yes + DOXYGEN_WITH_STL=yes + ;; + 1.4.8*) + DOXYGEN_WITH_PYTHON=yes + DOXYGEN_WITH_STL=yes + ;; + 1.4.9*) + DOXYGEN_WITH_PYTHON=yes + DOXYGEN_WITH_STL=yes + ;; + [1-9].[5-9]*) + DOXYGEN_WITH_PYTHON=yes + DOXYGEN_WITH_STL=yes + ;; + *) + DOXYGEN_WITH_PYTHON=no + DOXYGEN_WITH_STL=no + ;; + esac + AC_MSG_RESULT(doxygen with support STL - $DOXYGEN_WITH_STL) + AC_MSG_RESULT(doxygen with support PYTHON - $DOXYGEN_WITH_PYTHON) + AC_SUBST(DOXYGEN_WITH_PYTHON) + AC_SUBST(DOXYGEN_WITH_STL) +fi +dnl AC_SUBST(DOXYGEN) + +AC_SUBST(GRAPHVIZHOME) +AC_SUBST(GRAPHVIZ_CPPFLAGS) +AC_SUBST(GRAPHVIZ_LDFLAGS) +GRAPHVIZ_CPPFLAGS="" +GRAPHVIZ_LDFLAGS="" + +graphviz_ok=yes +dnl were is graphviz ? +AC_PATH_PROG(DOT,dot) +if test "x$DOT" = "x" ; then + AC_MSG_WARN(graphviz not found) + graphviz_ok=no +else + GRAPHVIZ_CPPFLAGS="-I${GRAPHVIZHOME}/include/graphviz" + GRAPHVIZ_LDFLAGS="-L${GRAPHVIZHOME}/lib/graphviz" +fi +dnl AC_SUBST(DOT) + +AC_PATH_PROG(LATEX,latex) +if test "x$LATEX" = "x" ; then + AC_MSG_WARN(latex not found) +fi +AC_SUBST(LATEX) + +AC_PATH_PROG(DVIPS,dvips) +if test "x$DVIPS" = "x" ; then + AC_MSG_WARN(dvips not found) +fi +AC_SUBST(DVIPS) + +AC_PATH_PROG(PDFLATEX,pdflatex) +if test "x$PDFLATEX" = "x" ; then + AC_MSG_WARN(pdflatex not found) +fi +AC_SUBST(PDFLATEX) + +rst2html_ok=yes +dnl were is rst2html ? +AC_PATH_PROG(RST2HTML,rst2html) +if test "x$RST2HTML" = "x"; then + AC_PATH_PROG(RST2HTML,rst2html.py) +fi + +if test "x$RST2HTML" = "x"; then + AC_MSG_WARN(rst2html not found) + rst2html_ok=no +fi +AC_SUBST(RST2HTML) + +AM_CONDITIONAL(RST2HTML_IS_OK, [test x"$rst2html_ok" = xyes]) + +])dnl +dnl diff --git a/adm/unix/config_files/check_libxml.m4 b/adm/unix/config_files/check_libxml.m4 new file mode 100644 index 000000000..bc43b4902 --- /dev/null +++ b/adm/unix/config_files/check_libxml.m4 @@ -0,0 +1,41 @@ + +AC_DEFUN([AC_CHECK_LIBXML],[ + +AC_CHECKING(for libxml) + +# Custom location of libxml2 package can be specified +# thorugh LIBXML_DIR variable +if test "x$LIBXML_DIR" != "x" +then + CPPFLAGS="$CPPFLAGS -I$LIBXML_DIR/include/libxml2" + CXXFLAGS="$CXXFLAGS -I$LIBXML_DIR/include/libxml2" + TMPLIBS="-L$LIBXML_DIR/lib -lxml2 $LIBS" +else + CPPFLAGS="$CPPFLAGS -I/usr/include/libxml2" + CXXFLAGS="$CXXFLAGS -I/usr/include/libxml2" + TMPLIBS="-lxml2 $LIBS" +fi + +AC_CHECK_HEADER(libxml/parser.h,libxml_ok="yes",libxml_ok="no") + +if test "x$libxml_ok" = "xyes" +then + LIBS_old=$LIBS + LIBS=$TMPLIBS + AC_CHECK_LIB(xml2,xmlInitParser,libxml_ok="yes",libxml_ok="no",) + LIBS=$LIBS_old +fi + +if test "x$libxml_ok" = "xyes" +then + LIBS=$TMPLIBS +fi + +AC_MSG_RESULT(for libxml: $libxml_ok) + +LIBXML_LIBS=$LIBS +AC_SUBST(LIBXML_LIBS) + +])dnl +dnl + diff --git a/adm/unix/config_files/check_msg2qm.m4 b/adm/unix/config_files/check_msg2qm.m4 new file mode 100755 index 000000000..8d0c5474f --- /dev/null +++ b/adm/unix/config_files/check_msg2qm.m4 @@ -0,0 +1,57 @@ +# Check availability of Qt's msg2qm tool binary distribution +# +# Author : Jerome Roy (CEA, 2003) +# + +AC_DEFUN([CHECK_MSG2QM],[ + +AC_CHECKING(for msg2qm) + +msg2qm_ok=no + +AC_ARG_WITH(msg2qm, + [ --with-msg2qm=DIR root directory path of MSG2QM installation], + MSG2QM_DIR="$withval",MSG2QM_DIR="") + +if test "x$MSG2QM_DIR" == "x" ; then + +# no --with-MSG2QM-dir option used + + if test "x$MSG2QM_ROOT" != "x" ; then + + # MSG2QM_ROOT environment variable defined + MSG2QM_DIR=$MSG2QM_ROOT + + else + + # search MSG2QM binaries in PATH variable + AC_PATH_PROG(TEMP, msg2qm) + if test "x$TEMP" != "x" ; then + MSG2QM_DIR=`dirname $TEMP` + fi + + fi +# +fi + +# look for msg2qm in ${MSG2QM_DIR} directory +if test -f ${MSG2QM_DIR}/msg2qm ; then + msg2qm_ok=yes + MSG2QM="${MSG2QM_DIR}/msg2qm" + AC_MSG_RESULT(Using MSG2QM executable in ${MSG2QM_DIR}) +else + # if not found, look for msg2qm in ${MSG2QM_DIR}/bin directory + if test -f ${MSG2QM_DIR}/bin/msg2qm ; then + msg2qm_ok=yes + MSG2QM="${MSG2QM_DIR}/bin/msg2qm" + AC_MSG_RESULT(Using MSG2QM executable in ${MSG2QM_DIR}/bin) + else + AC_MSG_WARN("Cannot find MSG2QM executable") + fi +fi + +AC_SUBST(MSG2QM) +AC_MSG_RESULT(for MSG2QM: $msg2qm_ok) + +])dnl + diff --git a/adm/unix/config_files/check_omniorb.m4 b/adm/unix/config_files/check_omniorb.m4 index 998acd86e..33c322c37 100644 --- a/adm/unix/config_files/check_omniorb.m4 +++ b/adm/unix/config_files/check_omniorb.m4 @@ -1,5 +1,5 @@ -AC_DEFUN([CHECK_OMNIORB],[ +AC_DEFUN([AC_CHECK_OMNIORB],[ AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_CXX])dnl AC_REQUIRE([AC_PROG_CPP])dnl @@ -56,35 +56,25 @@ then OMNIORB_INCLUDES="-I$OMNIORB_ROOT/include -I$OMNIORB_ROOT/include/omniORB${OMNIORB_VERSION} -I$OMNIORB_ROOT/include/COS" AC_SUBST(OMNIORB_INCLUDES) + # ENABLE_PTHREADS + 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__" + OMNIORB_CXXFLAGS="$OMNIORB_CXXFLAGS -D__linux__ -D_REENTRANT" ;; esac AC_SUBST(OMNIORB_CXXFLAGS) @@ -95,7 +85,7 @@ then AC_LANG_CPLUSPLUS AC_CHECK_HEADER(CORBA.h,omniORB_ok="yes",omniORB_ok="no") - CPPFLAGS=$CPPFLAGS_old +dnl CPPFLAGS=$CPPFLAGS_old fi @@ -185,11 +175,8 @@ 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} - + OMNIORB_IDLCXXFLAGS="-nf -I$OMNIORB_ROOT/idl" + OMNIORB_IDLPYFLAGS="-bpython -I$OMNIORB_ROOT/idl" AC_SUBST(OMNIORB_IDLCXXFLAGS) AC_SUBST(OMNIORB_IDLPYFLAGS) @@ -212,15 +199,15 @@ then AC_SUBST(OMNIORB_IDL_TIE_H) AC_SUBST(OMNIORB_IDL_TIE_CXX) - AC_DEFINE(OMNIORB) + AC_DEFINE(OMNIORB,,[Presence de omniORB]) CORBA_HAVE_POA=1 - AC_DEFINE(CORBA_HAVE_POA) + AC_DEFINE(CORBA_HAVE_POA,,[POA presence]) CORBA_ORB_INIT_HAVE_3_ARGS=1 - AC_DEFINE(CORBA_ORB_INIT_HAVE_3_ARGS) + AC_DEFINE(CORBA_ORB_INIT_HAVE_3_ARGS,,[?]) CORBA_ORB_INIT_THIRD_ARG='"omniORB"' - AC_DEFINE(CORBA_ORB_INIT_THIRD_ARG, "omniORB") + AC_DEFINE(CORBA_ORB_INIT_THIRD_ARG, "omniORB", [?]) fi @@ -243,71 +230,10 @@ 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) +IDL=${OMNIORB_IDL} +IDLGENFLAGS="-bcxx " +AC_SUBST(IDL) +AC_SUBST(IDLGENFLAGS) ])dnl dnl diff --git a/adm/unix/config_files/check_opengl.m4 b/adm/unix/config_files/check_opengl.m4 new file mode 100644 index 000000000..8a56e0f54 --- /dev/null +++ b/adm/unix/config_files/check_opengl.m4 @@ -0,0 +1,195 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +AC_DEFUN([CHECK_OPENGL],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([AC_LINKER_OPTIONS])dnl + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +AC_ARG_WITH(opengl, + [AC_HELP_STRING([--with-opengl=DIR],[root directory path of OpenGL installation])], + [opengl_dir="$withval"], + [dirs="/usr/lib${LIB_LOCATION_SUFFIX} /usr/local/lib${LIB_LOCATION_SUFFIX} /opt/graphics/OpenGL/lib${LIB_LOCATION_SUFFIX} /usr/openwin/lib${LIB_LOCATION_SUFFIX} /usr/X11R6/lib${LIB_LOCATION_SUFFIX}"])dnl + +AC_CHECKING(for OpenGL) +AC_CHECKING(for OpenGL headers) + +OGL_INCLUDES="" +OGL_LIBS="" + +GL_LIB_PATH="" +GLU_LIB_PATH="" + +OpenGL_ok=no +OpenGL_libs_ok=no +OpenGL_headers_ok=no + +dnl openGL headers +# by default +if test "x${opengl_dir}" != "x" ; then + AC_MSG_RESULT(for opengl_dir: $opengl_dir) + AC_CHECK_HEADER([${opengl_dir}/include/GL/gl.h], + [OpenGL_headers_ok=yes; OGL_INCLUDES="-I${opengl_dir}/include"], + [OpenGL_headers_ok=no]) + if test "x${OpenGL_headers_ok}" = "xyes" ; then + AC_CHECKING(for default OpenGL library) + if test "x${opengl_dir}" = "x/usr" ; then + OGL_LIBS="" + else + OGL_LIBS="-L${opengl_dir}/lib" + fi + LDFLAGS_old="$LDFLAGS" + LDFLAGS="$LDFLAGS $OGL_LIBS" + AC_CHECK_LIB([GL], + [glBegin], + [OpenGL_libs_ok=yes], + [OpenGL_libs_ok=no]) + if test "x${OpenGL_libs_ok}" = "xyes" ; then + AC_TRY_LINK([], + [], + [OpenGL_libs_ok=yes ; OpenGL_ok=yes; OGL_LIBS="$OGL_LIBS -lGL"], + [OpenGL_libs_ok=no]) + fi + LDFLAGS="$LDFLAGS_old" + fi +fi + +if test "x${OpenGL_headers_ok}" = "xno" ; then + AC_CHECK_HEADER(GL/gl.h, + [OpenGL_headers_ok=yes], + [OpenGL_headers_ok=no]) +fi + +# under SunOS ? +if test "x${OpenGL_headers_ok}" = "xno" ; then + AC_CHECK_HEADERS(/usr/openwin/share/include/GL/glxmd.h, + [OpenGL_headers_ok=yes; OGL_INCLUDES="-I/usr/openwin/share/include/"], + [OpenGL_headers_ok=no]) +fi + +# under IRIX ? +if test "x${OpenGL_headers_ok}" = "xno" ; then + AC_CHECK_HEADERS(/opt/graphics/OpenGL/include/GL/glxmd.h, + [OpenGL_headers_ok=yes; OGL_INCLUDES="-I/opt/graphics/OpenGL/include"], + [OpenGL_headers_ok=no]) +fi + +# some linux OpenGL servers hide the includes in /usr/X11R6/include/GL +if test "x${OpenGL_headers_ok}" = "xno" ; then + AC_CHECK_HEADERS(/usr/X11R6/include/GL/gl.h, + [OpenGL_headers_ok=yes; OGL_INCLUDES="-I/usr/X11R6/include"], + [OpenGL_headers_ok=no]) +fi + +if test "x${OpenGL_headers_ok}" = "xyes" ; then + AC_CHECKING(for OpenGL library) + for idir in $dirs; do + if test -r "${idir}/libGL.so"; then + AC_MSG_RESULT(in ${idir}) + if test "x${idir}" = "x/usr/lib${LIB_LOCATION_SUFFIX}" ; then + GL_LIB_PATH="" + else + GL_LIB_PATH="-L${idir}" + fi + break + fi + # under IRIX ? + if test -r "${idir}/libGL.sl"; then + AC_MSG_RESULT(in ${idir}) + if test "x${idir}" = "x/usr/lib${LIB_LOCATION_SUFFIX}" ; then + GL_LIB_PATH="" + else + GL_LIB_PATH="-L${idir}" + fi + break + fi + done + LDFLAGS_old="${LDFLAGS}" + LDFLAGS="${LDFLAGS} ${GL_LIB_PATH}" + AC_CHECK_LIB([GL], + [glBegin], + [OpenGL_libs_ok=yes], + [OpenGL_libs_ok=no]) + if test "x${OpenGL_libs_ok}" = "xyes" ; then + AC_TRY_LINK([], + [], + [OpenGL_libs_ok=yes ; OGL_LIBS="${OGL_LIBS} ${GL_LIB_PATH} -lGL"], + [OpenGL_libs_ok=no]) + fi + LDFLAGS="$LDFLAGS_old" +fi + +if test "x${OpenGL_libs_ok}" = "xyes" ; then + for idir in $dirs; do + if test -r "${idir}/libGLU.so"; then + AC_MSG_RESULT(in ${idir}) + if test "x${idir}" = "x/usr/lib${LIB_LOCATION_SUFFIX}" ; then + GLU_LIB_PATH="" + else + GLU_LIB_PATH="-L${idir}" + fi + break + fi + # under IRIX ? + if test -r "${idir}/libGLU.sl"; then + AC_MSG_RESULT(in ${idir}) + if test "x${idir}" = "x/usr/lib${LIB_LOCATION_SUFFIX}" ; then + GLU_LIB_PATH="" + else + GLU_LIB_PATH="-L${idir}" + fi + break + fi + done + LDFLAGS_old="${LDFLAGS}" + LDFLAGS="${LDFLAGS} ${OGL_LIBS} ${GLU_LIB_PATH}" + AC_CHECK_LIB([GLU], + [gluBeginSurface], + [OpenGL_libs_ok=yes], + [OpenGL_libs_ok=no]) + if test "x${OpenGL_libs_ok}" = "xyes" ; then + AC_TRY_LINK([], + [], + [OpenGL_libs_ok=yes ; OGL_LIBS="${OGL_LIBS} ${GLU_LIB_PATH} -lGLU"], + [OpenGL_libs_ok=no]) + fi + LDFLAGS="$LDFLAGS_old" +fi + +if test "x${OpenGL_headers_ok}" = "xyes" ; then + if test "x${OpenGL_libs_ok}" = "xyes" ; then + OpenGL_ok=yes + fi +fi + +AC_MSG_RESULT(for OpenGL_headers_ok: $OpenGL_headers_ok) +AC_MSG_RESULT(for OpenGL_libs_ok: $OpenGL_libs_ok) +AC_MSG_RESULT(for OpenGL_ok: $OpenGL_ok) + +AC_SUBST(OGL_INCLUDES) +AC_SUBST(OGL_LIBS) + +AC_LANG_RESTORE + +])dnl diff --git a/adm/unix/config_files/check_qt.m4 b/adm/unix/config_files/check_qt.m4 index e8df7ee47..0472d93dd 100755 --- a/adm/unix/config_files/check_qt.m4 +++ b/adm/unix/config_files/check_qt.m4 @@ -25,8 +25,15 @@ 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_REQUIRE([CHECK_OPENGL])dnl +AC_REQUIRE([AC_LINKER_OPTIONS])dnl + +AC_CHECKING(for Qt) + +if test "x$OpenGL_ok" != "xyes" ; then + AC_MSG_WARN(Qt needs OpenGL correct configuration, check configure output) +fi -AC_CHECKING(for QT) qt_ok=yes AC_LANG_SAVE @@ -36,6 +43,14 @@ if test "x$QTDIR" = "x" then AC_MSG_RESULT(please define QTDIR variable) qt_ok=no +else + AC_MSG_RESULT(QTDIR is $QTDIR) + qt_inc_ok=no + QTINC="" + AC_CHECK_FILE(${QTDIR}/include/qt3/qglobal.h,QTINC="/qt3",QTINC="") + QT_VERS=`grep "QT_VERSION_STR" ${QTDIR}/include${QTINC}/qglobal.h | sed -e 's%^#define QT_VERSION_STR\([[:space:]]*\)%%g' -e 's%\"%%g'` + AC_MSG_RESULT(Qt version is $QT_VERS) + QT_VERS="Qt_"`echo $QT_VERS | sed -e 's%\"%%g' -e 's%\.%_%g'` fi if test "x$qt_ok" = "xyes" @@ -79,24 +94,24 @@ QT_ROOT=$QTDIR if test "x$qt_ok" = "xyes" then - AC_MSG_CHECKING(include of qt headers) - CPPFLAGS_old=$CPPFLAGS - CPPFLAGS="$CPPFLAGS -I$QTDIR/include" + CPPFLAGS="$CPPFLAGS -I$QTDIR/include${QTINC}" AC_LANG_CPLUSPLUS AC_CHECK_HEADER(qaction.h,qt_ok=yes ,qt_ok=no) CPPFLAGS=$CPPFLAGS_old + AC_MSG_CHECKING(include of qt headers) + if test "x$qt_ok" = "xno" then AC_MSG_RESULT(qt headers not found, or too old qt version, in $QTDIR/include) AC_MSG_RESULT(QTDIR environment variable may be wrong) else AC_MSG_RESULT(yes) - QT_INCLUDES="-I${QT_ROOT}/include -DQT_THREAD_SUPPORT" - QT_MT_INCLUDES="-I${QT_ROOT}/include -DQT_THREAD_SUPPORT" + QT_INCLUDES="-I${QT_ROOT}/include${QTINC} -DQT_THREAD_SUPPORT -DQT_CLEAN_NAMESPACE" + QT_MT_INCLUDES="-I${QT_ROOT}/include${QTINC} -DQT_THREAD_SUPPORT -DQT_CLEAN_NAMESPACE" fi fi @@ -104,10 +119,15 @@ if test "x$qt_ok" = "xyes" then AC_MSG_CHECKING(linking qt library) LIBS_old=$LIBS - LIBS="$LIBS -L$QTDIR/lib -lqt-mt $OGL_LIBS" + if test "x$QTDIR" = "x/usr" + then + LIBS="$LIBS -lqt-mt $OGL_LIBS" + else + LIBS="$LIBS -L$QTDIR/lib${LIB_LOCATION_SUFFIX} -lqt-mt $OGL_LIBS" + fi CXXFLAGS_old=$CXXFLAGS - CXXFLAGS="$CXXFLAGS -I$QTDIR/include" + CXXFLAGS="$CXXFLAGS $QT_INCLUDES" AC_CACHE_VAL(salome_cv_lib_qt,[ AC_TRY_LINK( @@ -122,12 +142,42 @@ then if test "x$qt_ok" = "xno" then - AC_MSG_RESULT(unable to link with qt library) - AC_MSG_RESULT(QTDIR environment variable may be wrong) + #AC_MSG_RESULT(unable to link with qt library) + #AC_MSG_RESULT(QTDIR environment variable may be wrong) + # BEGIN: for CCRT (installation of qt have only a "lib" directory) + LIBS="$LIBS_old -L$QTDIR/lib -lqt-mt $OGL_LIBS" + + AC_CACHE_VAL(salome_cv_lib_qt,[ + AC_TRY_LINK( +#include +, int n; + char **s; + QApplication a(n, s); + a.exec();, + eval "salome_cv_lib_qt=yes",eval "salome_cv_lib_qt=no") + ]) + qt_ok="$salome_cv_lib_qt" + + if test "x$qt_ok" = "xno" + then + AC_MSG_RESULT(unable to link with qt library) + AC_MSG_RESULT(QTDIR environment variable may be wrong) + else + AC_MSG_RESULT(yes) + QT_LIBS="-L$QTDIR/lib -lqt-mt" + QT_MT_LIBS="-L$QTDIR/lib -lqt-mt" + fi + # END: for CCRT else AC_MSG_RESULT(yes) - QT_LIBS="-L$QTDIR/lib -lqt-mt" - QT_MT_LIBS="-L$QTDIR/lib -lqt-mt" + if test "x$QTDIR" = "x/usr" + then + QT_LIBS=" -lqt-mt" + QT_MT_LIBS=" -lqt-mt" + else + QT_LIBS="-L$QTDIR/lib${LIB_LOCATION_SUFFIX} -lqt-mt" + QT_MT_LIBS="-L$QTDIR/lib${LIB_LOCATION_SUFFIX} -lqt-mt" + fi fi LIBS=$LIBS_old @@ -140,12 +190,14 @@ AC_SUBST(UIC) AC_SUBST(QT_ROOT) AC_SUBST(QT_INCLUDES) +AC_SUBST(QT_MT_INCLUDES) AC_SUBST(QT_LIBS) AC_SUBST(QT_MT_LIBS) +AC_SUBST(QT_VERS) AC_LANG_RESTORE -AC_MSG_RESULT(for qt: $qt_ok) +AC_MSG_RESULT(for Qt: $qt_ok) # Save cache AC_CACHE_SAVE diff --git a/adm/unix/config_files/check_salome.m4 b/adm/unix/config_files/check_salome.m4 new file mode 100644 index 000000000..7427e2726 --- /dev/null +++ b/adm/unix/config_files/check_salome.m4 @@ -0,0 +1,75 @@ +# Check availability of Salome's KERNEL binary distribution +# +# Author : Jerome Roy (CEA, 2003) +# + +AC_DEFUN([AC_CHECK_KERNEL],[ + +AC_CHECKING(for Kernel) + +Kernel_ok=no +dsc_ok=no + +AC_ARG_WITH(kernel, + [ --with-kernel=DIR root directory path of KERNEL build or installation], + KERNEL_DIR="$withval",KERNEL_DIR="") + +if test "x$KERNEL_DIR" = "x" ; then + +# no --with-kernel-dir option used + + if test "x$KERNEL_ROOT_DIR" != "x" ; then + + # KERNEL_ROOT_DIR environment variable defined + KERNEL_DIR=$KERNEL_ROOT_DIR + + else + + # search Kernel binaries in PATH variable + AC_PATH_PROG(TEMP, runSalome) + if test "x$TEMP" != "x" ; then + KERNEL_BIN_DIR=`dirname $TEMP` + KERNEL_DIR=`dirname $KERNEL_BIN_DIR` + fi + + fi +# +fi + + +if test -f ${KERNEL_DIR}/bin/salome/runSalome ; then + Kernel_ok=yes + AC_MSG_RESULT(Using Kernel module distribution in ${KERNEL_DIR}) + AC_DEFINE(SALOME_KERNEL,,[With Salome KERNEL]) + + if test "x$KERNEL_ROOT_DIR" = "x" ; then + KERNEL_ROOT_DIR=${KERNEL_DIR} + fi + if test "x$KERNEL_SITE_DIR" = "x" ; then + KERNEL_SITE_DIR=${KERNEL_ROOT_DIR} + fi + SALOME_ROOT_DIR=`AS_DIRNAME(["$KERNEL_ROOT_DIR"])` + SALOME_VERSION="`echo $KERNEL_ROOT_DIR | sed s@$SALOME_ROOT_DIR/KERNEL@@`" + + if test -f ${KERNEL_DIR}/idl/salome/DSC_Engines.idl ; then + # DSC extension available + dsc_ok=yes + AC_MSG_RESULT(Using DSC Ports module distribution in ${KERNEL_DIR}) + AC_DEFINE(DSC_PORTS,,[With DSC ports]) + else + AC_MSG_WARN("Cannot find DSC Ports module distribution") + fi + + AC_SUBST(KERNEL_ROOT_DIR) + AC_SUBST(KERNEL_SITE_DIR) + AC_SUBST(SALOME_ROOT_DIR) + AC_SUBST(SALOME_VERSION) + +else + AC_MSG_WARN("Cannot find compiled Kernel module distribution") +fi + +AC_MSG_RESULT(for Kernel: $Kernel_ok) + +])dnl + diff --git a/adm/unix/config_files/production.m4 b/adm/unix/config_files/production.m4 index d5fa2a330..71b9143ae 100755 --- a/adm/unix/config_files/production.m4 +++ b/adm/unix/config_files/production.m4 @@ -94,7 +94,7 @@ enable_debug=AC_ENABLE_DEBUG_DEFAULT)dnl if test "X$enable_debug" = "Xyes"; then FFLAGS="$FFLAGS -g " CFLAGS="$CFLAGS -g " - CXXFLAGS="$CXXFLAGS -g " + CXXFLAGS="$CXXFLAGS -g -D_DEBUG_ " else FFLAGS="$FFLAGS" CFLAGS="$CFLAGS" diff --git a/adm/unix/make_begin.am b/adm/unix/make_begin.am index eeec91183..928083b95 100755 --- a/adm/unix/make_begin.am +++ b/adm/unix/make_begin.am @@ -1,2 +1,32 @@ +## +# Here any commonly used variables can be defined +## + +# Standard directory for installation +salomeincludedir = $(includedir)/@PACKAGE@ +libdir = $(prefix)/lib@LIB_LOCATION_SUFFIX@/@PACKAGE@ +bindir = $(prefix)/bin/@PACKAGE@ +salomescriptdir = $(bindir) + +# Directory for installing idl files +salomeidldir = $(prefix)/idl/@PACKAGE@ + +# Directory for installing resource files +salomeresdir = $(prefix)/share/@PACKAGE@/resources/@MODULE_NAME@ + +# Directories for installing admin files +admlocaldir = $(prefix)/adm_local +admlocalunixdir = $(admlocaldir)/unix +admlocalm4dir = $(admlocaldir)/unix/config_files + +# Shared modules installation directory +sharedpkgpythondir =$(pkgpythondir)/shared_modules + +# Documentation directory +docdir = $(datadir)/doc/@PACKAGE@ EXTRA_DIST = $(wildcard $(srcdir)/*.hxx) $(wildcard $(srcdir)/*.h) + +# Gui specific makefile variable (not needed for base, engine, runtime parts) +# To improve +include $(top_srcdir)/adm/unix/make_gui_begin.am diff --git a/adm/unix/make_end.am b/adm/unix/make_end.am index a6a697426..5102c67ee 100755 --- a/adm/unix/make_end.am +++ b/adm/unix/make_end.am @@ -8,7 +8,7 @@ SUFFIXES = SUFFIXES += .i WRAP.cxx .idl .hh SK.cc _idl.py .iWRAP.cxx : - $(SWIG) $(SWIG_PYTHON_OPT) $(SWIG_PYTHON_INCLUDES) -o $@ $< + $(SWIG) $(SWIG_PYTHON_OPT) $(SWIG_PYTHON_INCLUDES) $(MYSWIG_FLAGS) -o $@ $< .idlSK.cc: $(OMNIORB_IDL) $(OMNIORB_IDLCXXFLAGS) -bcxx $< @@ -17,4 +17,62 @@ SUFFIXES += .i WRAP.cxx .idl .hh SK.cc _idl.py $(OMNIORB_IDL) $(OMNIORB_IDLCXXFLAGS) -bcxx $< .idl_idl.py: - $(OMNIORB_IDL) -bpython $< + $(OMNIORB_IDL) -bpython $(IDLPYFLAGS) $< + +# -------------------------------------------- +# *.h --> *_moc.cxx +# -------------------------------------------- + +SUFFIXES += .h _moc.cxx + +.h_moc.cxx : + $(MOC) -o $@ $< + +clean-local-h2Moc : + rm -f *_moc.cxx + +# -------------------------------------------- +# *.ui --> *.h +# -------------------------------------------- + +SUFFIXES += .ui .h + +.ui.h : + $(UIC) -o $@ $< + +clean-local-ui2h : + for Header in $(patsubst %.ui,%.h,$(wildcard *.ui)) ; do \ + rm -f $$Header ; \ + done ; + +# -------------------------------------------- +# *.ui --> *.cxx +# -------------------------------------------- + +SUFFIXES += .ui .cxx + +.ui.cxx : + $(UIC) -o $@ -impl $(patsubst %.cxx,%.h,$@) $< + +clean-local-ui2cxx : + for Impl in $(patsubst %.ui,%.cxx,$(wildcard *.ui)) ; do \ + rm -f $$Impl ; \ + done ; + +# -------------------------------------------- +# *.po --> *.qm +# -------------------------------------------- + +SUFFIXES += .po .qm + +.po.qm : + subdir=`dirname $@` ; \ + if ! test -d $$subdir; then \ + mkdir -p $$subdir ; \ + fi ; \ + $(MSG2QM) $< $@ + +clean-local-po2qm : + rm -f *.qm + +clean-local : clean-local-h2Moc clean-local-po2qm clean-local-ui2cxx clean-local-ui2h diff --git a/adm/unix/make_gui_begin.am b/adm/unix/make_gui_begin.am new file mode 100755 index 000000000..fa551e451 --- /dev/null +++ b/adm/unix/make_gui_begin.am @@ -0,0 +1,7 @@ + +# .qm translator files and icons +QMFILES = $(POFILES:%.po=%.qm) +#resourcesdir = $(pkgdatadir)/resources +#resources_DATA = $(QMFILES) $(ICONS) +dist_salomeres_DATA = $(QMFILES) ${ICONS} + diff --git a/build_configure b/build_configure index db3c5f437..c690a8974 100755 --- a/build_configure +++ b/build_configure @@ -2,21 +2,10 @@ # -- # -PROJECT="YACS" - -# -- -# set VERSION from CVS_TAG_NAME - -CVS_TAG_NAME='$Name$' -VERSION=${CVS_TAG_NAME} -VERSION=`echo ${VERSION/'$Name:'/}` -VERSION=`echo ${VERSION/'$'/}` -if test X$VERSION = X ; then - VERSION=`date +"%F"` # -%H-%M -else - VERSION=`echo $VERSION | sed -e "s/V_//g"` - VERSION=`echo $VERSION | sed -e "s/_/./g"` -fi +PROJECT="salome" +VERSION=4.0.0 +XVERSION=0x040000 +MODULE_NAME="yacsgui" # -- ORIG_DIR=`pwd` @@ -46,18 +35,32 @@ cd ${CONF_DIR} rm -f configure.in touch configure.in #echo "AC_INIT(src)" >> configure.in -echo "AC_INIT(YACS,0.1)" >> configure.in +echo "AC_INIT($PROJECT,$VERSION)" >> configure.in echo "RELEASE=$VERSION" >> configure.in echo "PROJECT=$PROJECT" >> configure.in +echo "PACKAGE=$PROJECT" >> configure.in +echo "MODULE_NAME=$MODULE_NAME" >> configure.in + cat configure.in.base >> configure.in + echo "AC_OUTPUT([ \\" >> configure.in -# echo " src/XDATA/xversion.py \\" >> configure.in -# echo " doc/xversion.tex \\" >> configure.in + sed -e 's,\.am, \\,' -e 's,\.\/,,' Makefile.am.list >> configure.in + +echo " src/yacsloader/Test/YacsLoaderTest.sh \\" >> configure.in +echo " src/yacsloader/Test/YacsLoaderInSessionTest.sh \\" >> configure.in +echo " src/yacsloader/Test/YacsLoaderInSessionTest2.sh \\" >> configure.in +echo " src/yacsloader/Test/display.sh \\" >> configure.in +echo " src/yacsloader/Test/config_appli.xml \\" >> configure.in +echo " src/gui/resources/YACSGuiCatalog.xml \\" >> configure.in +echo " doc/Doxyfile \\" >> configure.in + echo "])" >> configure.in # -- + run "libtoolize" run "aclocal -I adm/unix/config_files" +run "autoheader -I adm/unix/config_files" run "autoconf" run "automake --add-missing --copy" diff --git a/configure.in.base b/configure.in.base index a35cbf8e4..a1abc8946 100644 --- a/configure.in.base +++ b/configure.in.base @@ -2,16 +2,125 @@ # Copyright (C) CEA, EDF # Author : Anthony Geay (CEA) # -- +# ----------------------------------------------------------------------------- +# +# This function return on stdout the absolute path of the filename in +# argument. Exemple: +# $ filename="../KERNEL_SRC/configure +# $ absfilename=`absolute_path $filename` +function absolute_path { + filename=$1 + here=`pwd` + apath=`dirname $filename` + cd $apath + apath=`pwd` + cd $here + echo $apath +} + +# Build directory, where the configure script is executed. +ROOT_BUILDDIR=`pwd` +# Source directory, where the configure script is located. +ROOT_SRCDIR=`absolute_path $0` + +AC_SUBST(ROOT_SRCDIR) +AC_SUBST(ROOT_BUILDDIR) + +echo +echo Source root directory : $ROOT_SRCDIR +echo Build root directory : $ROOT_BUILDDIR + +# ----------------------------------------------------------------------------- AC_ENABLE_DEBUG(yes) AC_DISABLE_PRODUCTION AC_SUBST(RELEASE) +AC_SUBST(MODULE_NAME) +AC_SUBST(PACKAGE) + AM_INIT_AUTOMAKE($PROJECT, $RELEASE) +AC_CONFIG_HEADER(yacs_config.h) + +#Linker options +AC_CANONICAL_BUILD +AC_LINKER_OPTIONS + +#Mandatory products AC_PROG_CXX AM_PROG_LIBTOOL -CHECK_CPPUNIT +AM_PATH_PYTHON(2.3) +AC_PYTHON_DEVEL +python_ok=yes +CHECK_THREAD +AC_CHECK_OMNIORB +AC_CHECK_EXPAT +AC_CHECK_LIBXML + +#Optional products AC_PROG_SWIG(1.3.17) SWIG_ENABLE_CXX SWIG_PYTHON -CHECK_THREAD -CHECK_OMNIORB +CHECK_CPPUNIT +AC_CHECK_KERNEL +CHECK_QT +CHECK_MSG2QM +CHECK_CAS +CHECK_HTML_GENERATORS + +AM_CONDITIONAL([PYTHON_API], [test "x$swig_ok" == "xyes"]) +AM_CONDITIONAL([SALOME_KERNEL], [test "x$KERNEL_ROOT_DIR" != "x"]) +AM_CONDITIONAL([DSC_PORTS], [test -f $KERNEL_ROOT_DIR/idl/salome/DSC_Engines.idl]) + +#CHECK_KERNEL +CHECK_GUI(SALOME_Session_Server,SALOME_Session_Server) +#CHECK_PYHELLO +#CHECK_GEOM +#CHECK_VISU +#CHECK_SALOME_ENV + +AM_CONDITIONAL([HAS_GUI], [test "x$GUI_ROOT_DIR" != "x"]) + +echo +echo +echo +echo "------------------------------------------------------------------------" +echo "$PACKAGE $VERSION" +echo "------------------------------------------------------------------------" +echo +echo "Configuration Options Summary:" +echo +echo "Mandatory products:" +echo " Threads ................ : $thread_ok" +echo " OmniOrb (CORBA) ........ : $omniORB_ok" +echo " Python ................. : $python_ok" +echo " Expat .................. : $expat_ok" +echo " libxml ................. : $libxml_ok" +echo +echo "Optional products:" +echo " swig (python wrapper)... : $swig_ok" +echo " SALOME KERNEL .......... : $Kernel_ok" +echo " DSC extension .......... : $dsc_ok" +echo " Cppunit (make check).... : $cppunit_ok" +echo " Qt (salome)............. : $qt_ok" +echo " msq2qm ................. : $msg2qm_ok" +echo " SALOME GUI ............. : $SalomeGUI_ok" +echo " OCC..................... : $occ_ok" +echo +echo "------------------------------------------------------------------------" +echo + +if test "x$thread_ok" = "xno"; then + AC_MSG_ERROR([Thread is required],1) +fi +if test "x$omniORB_ok" = "xno"; then + AC_MSG_ERROR([OmniOrb is required],1) +fi +if test "x$python_ok" = "xno"; then + AC_MSG_ERROR([Python is required],1) +fi +if test "x$expat_ok" = "xno"; then + AC_MSG_ERROR([Expat is required],1) +fi +if test "x$libxml_ok" = "xno"; then + AC_MSG_ERROR([Libxml is required],1) +fi diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in new file mode 100644 index 000000000..67bf37ac4 --- /dev/null +++ b/doc/Doxyfile.in @@ -0,0 +1,282 @@ +# Doxyfile 1.4.2 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = YACS +PROJECT_NUMBER = 0.1 +OUTPUT_DIRECTORY = . +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 = +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 = \ + @top_srcdir@/doc \ + @top_srcdir@/idl \ + @top_srcdir@/src/bases \ + @top_srcdir@/src/engine \ + @top_srcdir@/src/runtime \ + @top_srcdir@/src/yacsloader \ + @top_srcdir@/src/yacsorb \ + @top_srcdir@/src/gui \ + @top_srcdir@/src/lineconn2d \ + @top_srcdir@/src/prs \ + @top_srcdir@/src/pyqt + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.py \ + *.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 = @top_srcdir@/src/yacsloader/tools +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = */Test/* +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = @top_srcdir@/doc +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = YES +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/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 000000000..f20fa1066 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,12 @@ + +include $(top_srcdir)/adm/unix/make_begin.am + +docs: + doxygen + +install-data-local:docs + $(INSTALL) -d $(docdir)/gui/YACSGui; + cp -rf $(top_builddir)/doc/html/* $(docdir)/gui/YACSGui; + cp -rf $(top_builddir)/doc/html/index.html $(docdir)/gui/YACSGui/index.htm; + cp -rf $(top_srcdir)/src/yacsloader/samples $(docdir)/gui/YACSGui; + rm -rf $(docdir)/gui/YACSGui/samples/CVS; diff --git a/doc/bases.dox b/doc/bases.dox new file mode 100644 index 000000000..392249c48 --- /dev/null +++ b/doc/bases.dox @@ -0,0 +1,14 @@ +/*! \page bases Base classes + +\section toc Table of contents + + - \ref bases_intro + + +\section bases_intro Introduction + +\code + +\endcode + +*/ diff --git a/doc/engine.dox b/doc/engine.dox new file mode 100644 index 000000000..1eb4dec30 --- /dev/null +++ b/doc/engine.dox @@ -0,0 +1,222 @@ +/*! \page engine Engine + +\section toc Table of contents + + - \ref engine_intro + - \ref basic_concepts + - \ref engine_executor + +\section engine_intro Introduction + +The engine is in charge to : + + - edit + - check consistency + - schedule + - execute + +graphs of execution independently from the context (\ref engine_runtime) the graph is destined to run. + +\section basic_concepts Basic concepts in YACS::ENGINE + +The understanding of YACS::ENGINE implementation needs a well +knowledge of the following concepts : + +- \ref engine_node +- \ref engine_ports +- \ref engine_links +- \ref engine_types +- \ref engine_context +- \ref engine_placement + +\section engine_executor Executor + +The executor is in charge to run a graph of execution. Executor is +TOTALLY independant from Node and Port implementation. The only APIs seen +from YACS::ENGINE::Executor are YACS::ENGINE::Scheduler and YACS::ENGINE::Task. So, from the Executor point of +view, a graph of execution is a scheduler scheduling tasks. +The responsability of executor is to launch, concurrently or not, tasks selected by +scheduler and to +notify to tasks and to the scheduler what it is going to do and what happend +during tasks' execution. +There are several launching mode in executor. Here the common modes : +- launch tasks until scheduler declares that all is finished. +- launch tasks until a given task is upon to be launched. +- launch tasks one by one. (step by step) + +*/ + +/*! \page engineConcepts Engine concepts + +\section engine_node Nodes + +A Node is an entity performing a treatement or job using ingoing data +given in ingoing \ref engine_ports +provided by other Nodes or 'manually' set and providing itself data in outgoing \ref engine_ports. A +Node is eventually put into a scope (see \ref engine_hierarchy) in +which all it's links with other Nodes can be performed. The most +little scope if it exists of a Node is referenced by YACS::ENGINE::Node::_father. + +There are 2 types of Node : + +- Node performing a job NOT splitable into several simpler jobs. In +this case job is called task. This type of Node can be dowcasted into +YACS::ENGINE::ElementaryNode. That's why, YACS::ENGINE::ElementaryNode inherits from YACS::ENGINE::Task +and YACS::ENGINE::Node. + +- Node performing job splittable into several jobs. This type of +Node can be dowcasted into YACS::ENGINE::ComposedNode. As this specific +type of Node is composed of several Nodes it is in charge of schedule +them. That's why, YACS::ENGINE::ComposedNode inherits from YACS::ENGINE::Scheduler and YACS::ENGINE::Node. + +\subsection engine_hierarchy Node hierarchy + +- It has been called hierarchy 'MyHierarchy' of a node 'MyNode' the biggest tree which each node of +this tree is an instance of ComposedNode and each leaves are instances +of ElementaryNode. One of these leaves/nodes is 'MyNode'. The links between leaves/nodes nodes/nodes are +established by the fatherness stored in each instance of Node +(YACS::ENGINE::Node::_father). +- The unique node of +this tree only linked down (with _father equal to 0) and having no +father is called \b RootNode of 'MyHierarchy'. +- A \b level \b of \b hierarchy of 'MyHierarchy' is the set of node/leaf having +the same father. +- A \b scope of a the hierarchy 'MyHierarchy' is a subtree of +'MyHierarchy' tree. A scope is represented by the head node of this subtree. + +\section engine_ports Ports + +A YACS::ENGINE::Port is an interface of a YACS::ENGINE::Node from the +outside. Ports can have several semantics. + +- \ref engine_control_flow +- \ref engine_data_flow +- \ref engine_data_stream + +\subsection engine_control_flow Control flow + +The semantic of this port is to put constraints on the sequence of +execution to synchronize nodes, on THE SAME +LEVEL of \ref engine_hierarchy between them. + +\subsection engine_data_flow Data + +Instances of these type of ports inherits from YACS::ENGINE::DataFlowPort. +This type of port represents data exchange protocol performed +physically by implementation in \ref +engine_runtime at the end of execution an instance of an ElementaryNode. So contrary to \ref +engine_data_stream, this data exchange protocol is performed following +\ref engine_control_flow synchronization. + +\subsection engine_data_stream DataStream + +Instances of these type of ports inherits from +YACS::ENGINE::DataStreamPort. DataStream ports are ports for data +exchange NOT synchronized by \ref engine_control_flow. + +\section engine_links Links + +A link in YACS does not lie onto a C++ object. A link exists in +YACS::ENGINE model only like +a sorted pair (YACS::ENGINE::OutPort, YACS::ENGINE::InPort). +The semantic of elements of pair can be different (\ref engine_data_flow +or \ref engine_data_stream ). This pair +is stored in both YACS::ENGINE::OutPort side and YACS::ENGINE::InPort +side. The storage YACS::ENGINE::InPort side is only for +edition facility (Node, Port suppression), but at execution time, only links info +YACS::ENGINE::OutPort side is used. + +A link is constructed by the call to +YACS::ENGINE::ComposedNode::edAddLink method. The instance of +YACS::ENGINE::ComposedNode on which apply edAddLink must be so that +inPort and OutPort are both in its scope. + +\subsection engine_links_cpx Point of view of engine at run time + +It is important to note that a link defined by edAddLink method can +hide potentially a serie of elementary links. This is particalary true +when 2 dataflow ports inside 2 different loops are linked each other ; +in this case \ref engine_data_flow / \ref engine_data_stream +conversion is requested. +An elementary link is a link in which the semantic of both elements in pair +are exactly the same. So the complexity linked to modification of port +semantic in a link is managed at edition time so that at run time only +elementary links are seen. + +\section engine_types Data types + +YACS::ENGINE::TypeCode instances are destined to describe data + structure of a piece of data expected by an instance of + YACS::ENGINE::DataPort (for type checking at edition : static type + checking) or held in YACS::ENGINE::Any instance (for type checking + at execution : dynamic type checking). +All data exchanged by calculation nodes through input and output +data ports have a type. + +The type is given by the port that holds the data by calling +its YACS::ENGINE::DataPort::edGetType() method. +All types are instances of the YACS::ENGINE::TypeCode class or one of +its derived classes : YACS::ENGINE::TypeCode_objref, YACS::ENGINE::TypeCode_seq. + +\section engine_context Context + +A context is a set of libraries allowing directly or indirectly from C++ calls to : + + - launch on demand, a computation or a job specified uniquely by a + string of character and a list of inputs and giving in return a + list of data in specific data formats. + - handle data of these specific data formats. Each of these data + formats overlapping all or part of data overlapped by YACS::ENGINE::Any. + +Concretely it takes form of set of : + + - middlewares (CORBA, SOAP, MPI, PVM ...) + - high level langage interpreters (as python, perl, shell) callable + from C++. + - plateform (SALOME) + +\section engine_runtime Runtime + +A runtime exists in a given \ref engine_context. A runtime is in charge to : + +- treat physically the basic execution of elementary tasks in a given context +- the traduction of data in this context. +- to perform the physical deployment of the execution. + +The runtime simply appears in engine as an interface +that a concrete runtime must implement to be piloted by YACS::ENGINE. + +\section engine_placement Deployment + +This the 3rd point of view of a graph of execution, after +links between nodes (see \ref engine_links ) and hierarchy in nodes ( +\ref engine_hierarchy ). +Deployment concept is accessible in interface YACS::ENGINE::Task with the +concept of YACS::ENGINE::ComponentInstance and YACS::ENGINE::Container. + +- a ComponentInstance is a common environement \b shared by a set of + YACS::ENGINE::ServiceNode. Typically ServiceNodes sharing a same + ComponentInstance are sharing a same state taking different form + (environement var and/or memory space and/or internal variables...). +- a Container is a common process \b shared by several ComponentInstances. + +A task needed to be placed or deployed +at runtime has to return something different from 0 on call to +YACS::ENGINE::Task::getComponent(). YACS::ENGINE::ServiceNode is the +abstract class representing all executable nodes needed to be +deployed. + +It's important to note that the placement (or deployment) of +ServiceNodes can be performed at different moment at runtime. + +- Either it is performed once for all YACS::ENGINE::Container before +launching any task. This placement startegy is \b absolutly required for batch +mode. This condition is checked by the YACS::ENGINE::Executor by +calling YACS::ENGINE::Scheduler::isPlacementPredictableB4Run. +- or it is done at the last moment on call of +YACS::ENGINE::Load when execution of a ServiceNode is required by +Executor on running process. + + + +*/ diff --git a/doc/python.dox b/doc/python.dox new file mode 100644 index 000000000..f486e5b14 --- /dev/null +++ b/doc/python.dox @@ -0,0 +1,31 @@ +/*! \page python Python wrapping + + +The main classes and methods are wrapped in Python with +the SWIG tool (at least version 1.3.24) + +\section python_modules Multi modules +As in C++ the wrapping is split in 3 modules : engine, runtime, loader +so that other runtime or loader can be used with the same engine. +We need to be careful with definitions shared by the 3 modules : put +them in a unique dynamic library and link the modules with it. + +\section python_exception Exception wrapping +In swig, exception can be wrapped either by declaring throw in interface +file (.i) or by declaring an exception handler. +A generic exception handler has been declared so throw declarations must +be removed to not wrap exceptions two times. + +\section python_gil Global Interpreter Lock +For some methods we need to release the Python GIL. +This is done by using a swig exception handler that releases the lock +on entry and reacquires it on exit. + +\section python_ownership Ownership +Some methods (factory mainly) don't give ownership to python. For example, +createNode from runtime object returns a newly created node to python but +python has not ownership so when it disappears from python, the C++ object +is not destroyed. +To give ownership to python we use %newobject macro. + +*/ diff --git a/doc/runtime.dox b/doc/runtime.dox new file mode 100644 index 000000000..7033372de --- /dev/null +++ b/doc/runtime.dox @@ -0,0 +1,40 @@ +/*! \page runtime SALOME Runtime + +\section toc Table of contents + + - \ref runtime_intro + - \ref runtime_elements + +\section runtime_intro Introduction + +The runtime package provides implementation of %YACS generic nodes +for SALOME platform. + + +\section runtime_elements SALOME runtime nodes + +The SALOME runtime implements following nodes : + + - function inline node in python + - script inline node in python + - component service node for SALOME components + - reference service node for CORBA objects + - reference service node for script shell with inputs/outputs in XML files + + +\subsection runtime_funcnode Inline function node +A function inline node is implemented by a Python function. + +\subsection runtime_scriptnode Inline script node +A script inline node is implemented by a Python script. + +\subsection runtime_componentnode Component service node +... + +\subsection runtime_corbanode CORBA reference service node +... + +\subsection runtime_xmlnode XML reference service node +... + +*/ diff --git a/doc/schema.jpeg b/doc/schema.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..0484407cbc0db760350c47ac20a4003982dedd8e GIT binary patch literal 17860 zcmeIZWmsKZmM*$*w*&~z26k`=?izvz2=4Cgu7L#CO@Kgf3BlbVxVyW%1_&1P?ypYQ zss2(`U48CzyU&l?i)XTUmayg+bBsCP@s2T{=APC7Y#9k@2>=EL0AQd$z|$ijB&H-T zs-mF82QoKdvT`sr2f48_vw&z_oh|LmLDDjkAendKk{~xOHabR-iK&^PtBniD(bdq# z(!~??X%P?ukP#7)5D}1(kdRPNkWtZbG0@S_&8es4EJ78ep;1Lj!kWo<4pbykw1F$e~aIo-j2ng`-(5HQ& z_W^hugl812qKMBG4Us4vaoOI-Wg%0&u4u zWas4Oea-(?P*_=2T~k|E-_Y36+11_C+t)uZF*!9oGdnlGu)eXmwY{^uw|{VU{`2DU z>iXu_?H_W%0C4|HEa>n5CD?Cr;Xvhrg@=cONBTo97+7~`gTsMGpkPIOCaQ>J==hwH z?L9K?>$t3nb`&ahrBgg3r*Tw#Fvt4Kvp+=pi)8;f!20E3e$%)r%As}rUE9fF1a zW4opPt6yF{O6GK~o|BxJKYTQP0wx%=_GsZUo`4VDDo;SxsLm76%B6oFBY97?kpF<` zwfpd^@(I}T+M~_H^nb)TR(=c-bbh>__dgdTKaH`5z%No12Kt~2kYWe z|1RNklGBWbk0yUiGljq&ZFV^DN87y@d;%y&@%`u2gdZqtN&}&OkLBOz+?{cS7xM&2 zl~`wH!iLlSi^eca{;v6Kd1EZB4+4YU)6s9*gIK-uB6w0|gUsNwW6-qmBa%ox{wIC7=^ zvmFw_hDv8N&)UUiJ|6hpp_W5WQkje~2_sRezl}H&M9fZ8*1Soo4OW8BwpIKEdjhSj z3x~%Jlc35?ghISbj8l$YaS>;xnE|dnfh$R5RZloFl_1K2K{|1fM=8^Gw8cx2vwmVk zbtN`rszBsj&LMT7egCz)ys2traQ#Gr+lqz5!*VjsaIIb#sQ)D*eCmbGa~Vle9j1ge zFI_ynj@wn`$&#|8t)EPG+0t3QxpopjLHm{o&P=f?iJ>^|JDC5dL6@LV|1I8i;XBm+ zCm>f{bxd7&gZvk!hr(k=rT;$OG~j}(C=UG5oFB=afY{v#;Ufm}$2hH7QRurNty{bs zqj#vi(0A2p#{T1PLHmKkyV)yz8lty&R(ZKz9(#?mBoo^}evA+odccM#N}?)d7`}kK z7RV7!Fhwa5j;AWp24DtYPLEqH*zk=+`Q|NgL?9eDC!TYdAfg_q#KlTD_+mJCVHUZV z`l9J5P<7$67St;SA-n01x$IG zo7_Veo3xaMJR_Ke?(z*vk)P6)PYnZz#a($hz1u9oxLpE#*tbvmHyi z7a6u#z9~~KKP^cLHxC}$uR_jCSypYH%Zd%i6>{jZ(}~Jy6;N#&MeKF{wx=ZNNTjik zKe5PE)S*8dE!Aa$zr=d}egQ&`WGogW($LCHB*2_!WKqFDS-TyT%7q#Ttc!yDIJyTp zmRn1(Q`}mLtyA=`dg2gr6YZUhgIC_YfpnEsWcVG?t%njTz?E_OYkZ%+=;O4$4DUa( zwRt;6XZ8%L@N&CF2SnCkb4xv}=5agoz+Sx+K_bl*LnDyxSt74NT5WCDTO`gG<-JKQ+L1Nf zLxMGxX{Et|xt9c+Qxs;VSn%3 znL=_~_OY2kaQcEx)YKZGyO{w7ZWss18~O3YP99hs)k+_1v&0HCJl&rDm2@-$851Y8DWW3dHd)IVm)+61 zd_77Ir8zHKYPIKzb88c+**Re1GGmR=21(bpA|qW!eboGl*7kfP*voX7246O{W5wZw zO6U`(!VV|?lHkYm*eTxQV=nsIi|duxN}V0c+$U0peHMwa^-Sme#bvv|1e3F~bw!If zUP8&CWv(PV%VNKG!3uA9PscO3B_TFX0s8lYyz7!Q&g{JyD@r~fb1I0*zb6&{ndevX< zO~&tg7|f~#JUJFEpc5L(e~6KH@5TOD9#EcuIW>g`%ErH}57D=Leg%=N9AWFZ% zWkTmh0NUU(POtAn1T>!jLyafkB7CM1_3xIKe+|j|XYP6Pt)Boh$T2B%31Rxg3I04& z6W)SM`dV~hTakes5?+ZoOhsE>Sy=TO)&sXrt@o_8ck+=`N2uH!>5@JeqT+s8S1}6NKmpd!YF8j8AJU{?2s4QutfT}Ts<`INnF@w(X@xIV#HX^w`_h__9^TlHHrv0x9e+U$>fjK|8AA*NiW{pwOPy{-*C zdH)Z`CAP0RwYZ{K>nqB`nCDRimy#1V#K9ySrLyH~4$^Ia3v346r;3Q9oFt4gtAV1N zeS3?@0l($K9^**rHFE5&xB8`Uj0T(h6;X>T6PFDdrpyQ|aY>Hf zkTY7wrxhYPpy3P5Jm5}L3@TM0*g;nx_CMC=KWy-yw%;Mp9z(_%7Svj4pw_A>d=Y*S z!1q^AfFiozAW*6Q?_t_M{mwt?L#f}-M;WrHC%~ZS33wp3)J1T<&NzQ}VSk69{{-wU z%KQzF{S}w}tMl)@|HIY(?5dfVf&YfvFn{ko!{0mVU%=qM`siQpGh{SB0g#X!|2g_6 z;0cgeP#4vC*uDQGNc`BY{si1|P5e!ne^u(gJpbPR|AwjNFYG|E_YZsz`?t-Iktd*w zNHuTDV-@|nqUSIcc_2P6R`lKi&M17Byw{I#^JpRafPCd~DC~!um;Jfwm3i%vITB$z z)LlC~pcu1@D3{*Lctb*K3sFOD&%>v}D*U*Av-IXV3Zl;>tOjyy}nWH4$dyHVf}KCvdh0Yk@Y zQ^o)HZt|MW?OT*O3V5y$K>?b+v_V?lREb$tWX4HIGM=pa0;U5>4@|+@S^h`6Qp&oz zGv+9c^LnYx=tpXEBL@JcQd+?1J;%(>Hm;(`Uu_NcKZ+HgvBjU)j-t%p-STgq@OMkc z|50SZ5Eb9e?e)-XyZ&%h`|O)zflm9-x6T-9E>KWE|CWwJy)<4WY!-^#0*zdO)q-7= zT^-TaEK6fJ9&yNlX_%}*Dr^_}+VdD=4JD5$xt@fqgQS2+l&_&$5@mZEMwPaEvW&Lv zn~v~m=xz(If{mk3o`84c7Ux|^iqm%2Lx=5)J5o+CRBq!R`@t|N<5klf4{z!#TWcEV zu0K3yIKEvwQyy{?L;gNVN}az^wED|3Z(lL40)p$^z`8skaXzh`4kxjO6JJl7UA3>S zuJJf_hFIfXcVgRk$Gob4bA@v(N@#R!7OVK%R0h+uI82?4?Ka=vy<{h5kxsjB@TF(^}QUGn;bSle~2pZ%lGt;zLO_EDH}&@#MN zO!zS}ygjkWK60sYG)d{eu1eYq@0 zb~hv(2j_b#S3JF|+e!Ia>o1F+Z8P;MW!BaA;}w#VWzpn*k>V$mS!&J2-*LaIYw&RU zHBJ@7_RRTXoX|NpysZH;DAI&zyp-}zwrWa?ratu7*lvG)*aBVl2)9ifvPmBS4;58V zH^2Nervm0;x4qXj-$(`#ymr9*GD^52*}k8_>;trZz#@fF$ERqm&zh2|1q*+2hvvi|-2-?nmW-g|=2)6is;`7{q+?C{sc zn9Wm3nZ)<|Y#loVU?ZXy!AdxomXz4PshmARC^_;x-_l%55LtyUbb?TT0@`i^u|R<+ zNRa5;YdNl~@8CdUh6cBuB%A?^lA(NZ#>-3HE-hg^zP>j@Db zG@I`P#oXDGa-DSQ%m}C&7i;gY&PyuPq~Vm2l9rNAAxLPX-iJ&4XqnBk@n{lB>Ut#0 zkcvKI!gqUp&Ot49-dNtY)H0=(Fumnvmdvz$pD7M+x&z@^1Tb@H`yX9tl%uv57sb-X zeI)%$_W2ZJj!qBQn+v?6P$=Q>#R8hnk)47d9yYVj>K4A{tqCLRFE2?tJ939^m@MUC z{t(h{o)<7DXd@u2S-O!~=sCDnJ;Mv^V{+wHU1QD@12Q?@OCh+k+`9$sYo7TCHwH;h zT-4WmdmQ{~CF>7(3)Eqb;DkD+Yy7-brsz@9pN*Z|w0+&FIPLP~#+LefU2}DHjR#&% zv_w68>6$D~9egU8<3i2W%q50!H$ETdO-+I;t*N!|*c-mb7oI#l~mV zL!o!982l=~h~0INrqYp_lT_>qC5-KB>27~~%y)G3M&I}4$uQFXJY*sfx5+;uK}8zE z`}HLu$EVg3OqH9C-a9Q@ZMk`eg@n>HYb%1|u1YzldLNg?pt#2o2EFU9IzG%6d*fo? zbXn~t%df#3%Y>+()xC@8%pS=^NA1!Mh|5A!RDK?ucbsc;WuD3lWC}Y9i1)=g_rCl^ zaCx~YqmRj)<4d|yCE#w4(VTb&RwRgf6NEXp)KvjT>Oq(zn#T?~!+Urv$-UuLsmDKC zT(Ndz?}epUC8~Jo^sAGE%ujKqI`6FIXcVvKOTNzXqHpaK5zEyRT zkwNk?ZAsak(vx|!L$z9}Tk2|sGeJXLCdZPtb0BjjKl$!KIt>Lv?P4!RPxS@`2v$5EtDx~7ms!9 zrT6Lua~^7g-RzwfF7qFhhV2ShY~J;WD3S9RaWhMduckAg^`s21hWgjjV|DkyQ?!WDd1V0Y;ifg;U^*?LKyy4KfdnD@LW7h6R(cZX1!bm8wnK!?yUGQ zBP6~*%Zdn|Xgxxr>GMD==QmG^!4UegdY=Z;9?wIC*QSIu_OH6WXq+V+u^mX~YRWk? zXRt){5&3qlTG$p2!B<38WPBmnjq3x#V>XfW(&Of zre&?}zF^jP6|2wI?`~(CC}IN8dGrfYfZWjq3wy(TcxghL*{Q=wPiv(G$|t39l0zlb z$h(@iC8RUI=5B(AZ|N#Rkl`bX9|lTc?%AwTQzGQNZvB$%AF{ql#&8jAt7F$5pv6H77v*tsbF)kP1?a$6-&toay4YKS7Dau+-8|LK`_79#lCZ39hx8yXkwDO# z7iMUJtMSH5OzP{Uv^BoZQ|CBhZ%D%i;K{?BPx%yL@oa5JJg?KD>MM9j$Mpx63&{Ql zvDEKi?Y}C9`nDTLT;yqcLJ1{5Uqd7*gVmK-M3DlKH}PKL!t_DmHui!Ej@bIJk}QGZ zYc%U=?><$L9(Ct1+%;N2s14>9o3kp|*RS_c_@19J9P#RlT)k}Qxc8QD5*153zYmUFGDF(I(q)+frEBbf)m_!9#QO@K%{C^~bd#N}r@ z#&mP-HI5|5vn*+`_|$5`-D=Oj7ETkSb>gii8O^ z>FUDg<(Hqx#8_p=lhrpo3weO87QQEzgAz4Unx85-ni9Viw*L8YhRK-)1!hccl0XPi z&MyPZteCiZ*1k4WQJ6}VkLa2)htQYyet*d~q=)wR;^B0IYq3Z8KfAP+mymwEHVMXF$q-=84MIZNHcU0x zdWPP=rhxwQDvik%3ktd|2d0rA4v6(gX0w=_356!TvPwy4>E2)! zv$R_A?ODGL2p4FeLIPm|;8P4aypan3n4?uJJzW1wckZLwILBG1S~I;5Sj$e1_cX3< zr=l1o&1zR?lIS=fsm-X@g|q|!OdH@B4#}X4tZ??WaC+yV{O&vG(5nDD-LLnneSq`* zE3O}`wW)^j10$Ggq6>Va3^EmC7frtGZ)>9$MwYq6pSdXB_tSvm`@!)Lt8F|cNX_yxSK zx*1k!t_+4`=A#XzVdCeBDR?9hdD$MJYsOZg?IfpgAR1-8u`YaLMPnyW1&buE+|-o{ z6vzXLc2-g&xwTzMa%6gpo{%PPfcP?g!Wq!mUSSiVqZ3#wkBUC}XwHTqOMK`nF~VP@ zDbS}6dX^^ziX9kmP<;=N2f`MGhoyz>{`Xz_XMa0CQv8ws`0xZAG0;55=|VY?-;yUP zFk_11xB#@ljNW)Zils9?0p-R1x8l}NLg@GG$=`JF4?n2teR$~0HzHe9AW*Li#O8&8 z0}2b-G{Zm$07MFSW&tbx&+^vBbD~^Dh5j}x;$XM4OkKVOSBlNM_FYq+g_B}jI^sCd zyRVWWqK3YOOX8lzp__G4T{8<-r9O2?^piYBVAnPSTm%W4WYnCffq%#uF_7K%Yz&;s zsmsI+C7;?Ibt1el0O06&&{zPV7bXC?3y2}>#)Z-Axm{JPiawZ8V0+OAU!a5xW~)ra zGZ00Pg2xsG!Yeec7fiRfAy#~hV`8q%7(>qsSe9)8SeevbYCxX_@t23G?>GFNF9l)+ zi`8+(ani(}ck4dEfS&;`byuVOBItri~cy1(w6iwHL>VGq5i-C%_vI*G$H zj4SHQ{)r(HUKfDQz756xYmlE$K-4>EQ2;3u-cSbVK70)Gs)j51A@LpMw%e;xA{Omb zbXwyP$7)uzCjez9o{m1LZk{Tn%?DyDUlmSu6vw3BH(m7E!t_RN;; z06y;QJS#4{^K|kcAxpvY~@SuF)?TL^^DmGgdricA6 z3qCej{?U*}+KQVHd+3MZqzRg8oQd|cu6+YyCC;UYmuGo=0NhVHETlXL}U%Ec2K^=N!n4&;3V;<*(PE$mIzzpD5lr!Ms6iN@Bkg_Ys2jK>;$1G9E`m_b|ZoNbLV39%g zszxEK(dRZ$GXKU;<&Id}vni2s%kS4x0(>x9A{FYFayDsU@!26Vwj1NMCtzjeMy%(S z-2HL1X=?omu-M?`_HWD-Zg{1afBFP$fSqr+1_a#%rE7?FXDUY#BCj2nJWamEnT1M~ z#q!!Nl^gMN!%4Tqy#0OD{+`nFsXTJ2R%eH5ekCqe{Cm04Bb{(1v&761*XQfh`(6qu zVoy*4dh2Prh5yow@Ts)t6VUSwQ`(JBiy`H=+7XenouIguO9JJaybPJfa1QbnbBm6` z=)5oh6N((S|6)YY8YB68a%jp!FXRabBJjT{TnhBCE7_>8OXST=fa?X@5b8?xfufPA zQpcoU{(E2i|J?7?zqeLRGHx}uHU&=12-v51!donZT zHM6ZQxA}ywaMAA-H0Vk6^+-I2xI>ySX(um^sUE4lYIB&T&iLzFr|rZDBI47MJKiAk zJG>VK;8K-rR?^9oXHD#7HzRnl?qx2P6;ws9^J+gD$B-uLnMIi>_hS$mLSabcq_25* zlE(SQxXW^jJE48^=)?0W@>9m$THfGMt%({!fhJPIGHXx`fAoZ zb+}Hz{4d}~_3$4uUqvdV!wEc05c)aGS|Sw;#57Y|b2P4>q|LHKiEV@(??-^$g%U+^ zgd<#4sTw&U?_Z3Rtu>Hyie#nN!&U|4arzaBsqKR4GwyNccoALv zz3jr(11>Gq99^py4hxHAh|;O_yOT7nHGme>^9a;vPeX#of+Jo}X2y9+8`MhWMqZh^ z!X$*eYlD(IGt;;zx!3H^r4r|Ul+SWDX(}Kr{5q-p{>4t9i?jh1i_}4ii>m2NH4_cL z$k6wh6aLju@x(R#M9)D)`uh)(aD?chL$lm0nu{&nQ)lh)#;?Gocq(2H4_xgfF?Vac z;pPbNa}b1EId(uolw47K{?j*QUlgh{zbyNn{Pn>A_QWspY0SoNPNeLaUw6jWP}xKp zgV(J0{a%jOBuBMG-7C0#(>(?cspEVDnPxkXN>V`(MUk@bf;|1r^R>T39M&@#AR$U` zAvfHn)6Y8uC`cQkdA_jkr;6GjhZUgh1yf8rd zMb+Q8&?9gHY`&l|am5>!-7LWiUS^hdO~zU#GV<(GaAh}nQ;fu~+1|sm1s5R{Mpo!E ziY?>niABlqiQGK$38=tYCKv>U8{d+=pv+6snJ{ePf*d3&E(Hal>3|%3xpp}PdUYJq z%m$rq;`P20yF8FF@nRv`$}3V89Coo(s420qnJS^s5Wu;rlTkJDp9sjktcr%UtbNx@ zNS6EdrR~akKpTlUc;q^wXi2QhmYSXq;X>s4LTR%MF>hTG-%uyc4Id z*DpW{S2us-a1p1nr`RVuTxboES!#;X+YuaII+j$?xup-_2Y9}Utt((^E0CO85UD6j zv`@ULiqg~|2}CBr_MY50;|dZ8O1rU6`4#c%Umxh~sHA6AO}thGZBrr8iTT15KspwxNa zmyUFjhIHxOF^&SWxQON$b7FQ@UND3gd|l#2ix|JuPexiLg3pkqg*^Kq97F4Xc9S$g z(FC=S4*>vpV2eR#qy?+?8ZR9|2L7WsF-FCUIHgOmM z4X2+lK^iHZz&olywu2m%K(^Z4DxmN{GleQXP@66Q^Hkd+_rz(cbA;$5`ul$(7iESd z`fq_5lJNQuXwg&EV+XXbav!fmbn~ug&>oH8D6g>&a&odTd{Ux`cRZmPN7!x`g06xG zAK12L5GVZS@~48reKo$FB*(8-ZsSYyOVs^Fev!hTL2H4$@USf6aN4OyEZw&74x&Wj z=vFvX;;4n01^|)>l2zYX%zYRUG;thcCw!r;@>9WgecR*=Hd`~NvbQkoMZd|?8zZ|H zgRuc@Zof=JVJh3{Zcoyv%d+$>E97H|>&Xz~a$ePF%EU)TdtMe_37T^9+~q$vG%oZA zl0G%+{wi&ZnZk6Ub?Zs>a@we8O2uf-C-P*mS21OFqFK67cV0(JrzG3j!AjrAV+J3k z?gtX8KA0egXSbHYU#iNN{B?C@x@*Rf1EZeN8+E7b_h}6RXBuSWwy(N`XdBOj5>34A ztMckn`uZvd@+#Xk;1ZNxxZk~TCo%q`Zj9INn7D7DW9xMKta31T_-*d zMF3UM&1KGOUb7ngnXRPTm4d95y-g);=@M7sgeqfLHV$^4mtGa<4e;jCt1=zUXFUz} zS%(Xai~B1QQH7kTaS2Y762;+CyfE6kqmGLtCKquxPL@51DS0=|5pu4H*yX=Ww^Zp% zcOCnI_%=9!J2mmq0P}{^-B6C;=}kC|R_mEhTI9>7pAz7Pc26*!_{X!9l=sxnsNcI6 z+zk9soS??G*0TMWTN~NC70;#<64iUH0SLp4Y6bd}%)O{SBZ=jcHqTor8P0J8E2G$| z4+>?l_Bf91;>|8tx{uui?<%L}z!8E|qFONX3|Z)M>EWN|qY1&b0C3U+7}H*|K=~CS+Z&s!;68<6<^`FqrK_-$DF` z)h0JYnfRy{{#irv5b9J*%R>E#zUo;`Lo}>JJ#nSN6L*qW6aj!8N(U_63#7}Ty&D6~ zqHA$3^{Bir5$ng);Z^nR-0nMJAJu}jvgME~_87P#bOlc^er-rn_$9T26LS>_+`WiKv7&_Y9s>UP|wt`!TVp;A7W03?#2l+u62&#q); z>+3CAaRsRvTDlrvNo_!YM`dg=DQ!>%=z^w(vgO#$X#YFI^!C&}1L={Pu-R>EakPo~rq zx}`b+;Nl|-sHoEeW&CFcA5r36H!Pbq*RgO`EdAbi+2BLEliyVh^k5tZ62P}P@Nx5g zb1B1>vtCboC08CT=4_jz^;Y4^=UV1y{J!8W>)dxGf69P_Xj}*mGVW@vOQnjhWtLAU zZA-K`d_MQJW4v}fGSURwAJv5nwRzI4vVQz>raGO0wzyPaP?25-Y>eFPj!}%{^GIqj z_C@}h<7j49dxFU|%3A&$%ry^Lxa6rjxo5dL@P?U8$zLO-)TMgUi1A#z-PM|9TWVH+lZ(zTL8>1V4R;>v>=$6Z%NX+ z&{%lztO=tyu>(OI?(0%&>Tc?-mlB8Uin>IC`94I!_zZuA*qLAJK<#Q>o|9g^xd@ z5dueUg+vnQxI?`r!nn>NolI4Pro?J1lqXDfpspqPzQ+2Hn$DSoM^dk-A@GE3jpPw8 z%QSnx_7>htNxPdVER>3>^i5{8ta*W;wBW(e>HHy|a>t|YaKaMLOKk>9mILGiWC0va zH6rG+uk*cz_N7$wU0f2A3-)Qx%U4L~+V*6~eWucey=PgCt5nV&Bi4VRKsu$z#kndO9ME@ps2Prvdlm>sN>e|m8q$Zj=Z(X$m}%#O(GnQDzmT}L zks^7aY`a8h=xvfB+8bU%v)NpDb4^^~+f?fOuLT)WN;>pp@ z=V7Lnl4b?EM=te9{CmfgR@*g=k*Jb=ue2q12dgB=%Cp2Bu3$;fwzS(_u8H!c0_uU* z==;^qx`idDVah^jFI&tVRRd9m9p4{G@#(&FO9?1WHFm)gt-jQG8>?vT?q78+b{JN< z_?t>T47|=*q6U8;lP{bxM|n@?IfY4{q3_%v+(Wel*IU^~$HF&!*mrKQ zWXD~ZhE|BDZEY8ho+-?g5^+BKsAN6dgC>yV89htKAvfAe3si z`IWj`zgZ{Kl4lV(*@=HkmIdY>>$a&a_DPEX8@>)usW=j}L}E-UYvetK({%P|#7x^_ z>Z&^6u9TxpR0-9S3PMF*k`~GV-1CK_P8e6;P1+qB+UhObt_)BRBOW=GBPfbqF z8_J~$X*yHXC5T9;No0EZW$q(EYliCSPL69aY2v0cz)7Oaaj2e z{urJU){9J{FMe8hB|eUxf<4L3S15~bn_vH|m@K8bBT85z%`>c+t)POd2dnBTF4%`Y zVth{v=NR^`r4~Mj6+I8+XYHpsjCKp3n-F;EnXkp1_9gw*S!BTDJNRTBxL#O+K(uX{ z38@L^NW3izAD;Mu2~H+z{!jHa6Rw1e$GV!Ii?yGL5wx$RNe6|*%x6p@`F(r zt}x>-Cz*|jEAHjv*=$DP>8n3)J#S-@yI0Iv+&rF@`+9PhvEU$WzT`)kKR*poJ42lHZ>2=^d4p1$3JJUb_Q!jmz&E8=V9VB!KmdbJ~F^Dmj1=5V6n&J z=nQ8O`olw=zvb%w6F^R>Tfcj9JmNWmh^cHE8Kc4$ZhWJz6L4I4#^@yBNuxA5W66GG z`b?OB`Jj~TY*ejlqpeoVYSib)^>q!mx=(I8D&)EQV{>G*g5A& zh~){$RQrRKv~2xF6v6hrO18l&{F|+SRxaZBMIuwj=SxZY{8D`u*cU+LH)BW+!OH}{ z&P}Xa1PlKgt}oC{l;5hbiYHFAvI`&nob^;HP1@L>leoHl2}!SmJ<-n2xEdUcaP#s# zi`-2$NHn?~X5LPre{~~quLvbZ5o4fR@jU&1QGX>vjg6%~lW5?O{L$k#Om=y~4W>U# zPga9>1O1d_c)78k#lUvh<;9e+s5x4w#k8^J8!JQP1~#GZ5i&E5`v}Cx1vqP4t_fqB zKT!6_UL51+xpHn9JOLiykpbe`HTFOW2RYlhInDh<$N4!eQA=wwH!*l44jqU*t^<^f zjuKMlHRh*^h<*YTTcDXL^N>s4skC(0A)^Tn`>PM#CJSsRrcw1H+}Pr}L7iH|zmU|X zva0IrTcPDJ%-*)#7=bF084#YiXDmymjkk331hP0vx^It(#U_1(O=eO|%L8c=c4Cvv zJ;BC_?rtxWV+z1)Fk`6W+2Lk?-C~3!=)HC<LbOw%yIZ0ht=+CcG5E<`hhTP?DJ zXYhE%0rALD(`o;ab~1Rku40Cgq)Id1np?nDBiBr#SE)yJEfxKJQ%!b46os0@d@6k7 zh6dJ6>YTnMTmj^q#ZYw*O^(nao+f~>eS~M**{V~ieA>YB;&9QrPqmhiX@+De#!_wG6L6fA#JuEkx63n1*v6}w-K~70`FD1w zctuX&KgIy{@%HM~`zZ0xkAE@gf-435KfPY) zFZr4!IZflK|K=a>^F6-5#-7`AKwKN(L@_;o0v6`CnD1Q|8=NPpO7IOYQ*;MaRP;}y zZgL)jF`$G$JoJ%sIT-7)nv2(f*^FgR$Kg#*F7cL5o)t>&098lE*y5 zJP{}+sGV`BvU#Q>Q&C{^JhFmhjZCoc=9D^Cgk8t_xs2a^h!U*xcI2fUs${n zChkrx%qWLhBE7J$b0d90x?Ac&>1Ny536||>ayrd&EB4*_(_gFZsZM=m{e}-Pmto}S+hI- zmOl`g7yj*PYzK5Im)phF;LcT%F4xjgxKJSIh#ElZ90>pQb(1I(FHL@SxH*4(eAC~R z+W(_cb)0{m>os2WQ0VkZ+e%7$B%dff$?f@-Ul}cF10ZTdrUFRos?bf@@TdL{s43)+ zXj#zokOg#y4V13B5fy+c{`FVroEEs}f0H8oKTrLSCjQ4J{;zn)@0D=B`Jz>K%!hmK ruX>W6hU*XX69)oEDQL8tu6>~OfWAJk9|uguKdbopFT9TQH2?nqHx0b{ literal 0 HcmV?d00001 diff --git a/doc/yacs.dox b/doc/yacs.dox new file mode 100644 index 000000000..9ea5a8bf0 --- /dev/null +++ b/doc/yacs.dox @@ -0,0 +1,102 @@ +//---------------------------------------------------------------------------------- +/*! +// \file yacs.dox +// \author Christian Caremoli +// \date 2006-11 +*/ +//---------------------------------------------------------------------------------- + +/*! +\mainpage + + \section Introduction + + \b %YACS is a tool to supervise execution of complex interconnected + scientific applications on computer networks and clusters. + Interconnected scientific applications can be seen as a collection + of computational tasks that are executed in a known order. + + In %YACS such a kind of application is described by a calculation schema. + %A calculation schema can be defined with an XML syntax and is mainly + a graph of nodes that refer to computational tasks or control structures. + Nodes are connected by control and data flow links. + + \section Features + + - Build calculation schemas from XML files + - Execute calculation schema (batch, step by step) + - Can manage mainly Salome component nodes, inline python nodes but + also to a lesser extent : C++ component nodes, XML component nodes + + \section Packages + + %YACS is composed of four packages + - \ref bases : common base classes (threads,...) and constants + - \ref engine : calculation schema generic classes (calculation nodes, control nodes, + control and data flow links, ...) + - \ref runtime : implementation of generic calculation nodes for Salome platform + - \ref xml_loader : XML reader for generic calculation schema + + A Python API is provided by wrapping with swig : \ref python + + \section Building + + For building %YACS, you need some prerequisites + - g++ 3.3 or more (mandatory) + - libxml2 (mandatory) + - expat (mandatory) + - omniorb (mandatory) + - python 2.3 and + (mandatory) + - swig 1.3.24 (optional) + - cppunits (optional, for unit tests only) + - Salome 3.2.x (optional) + - DSC Salome Extension (optional) + + If you want to install %YACS for SALOME, you need to set environment + variable: \b KERNEL_ROOT_DIR. + + If you want to install %YACS for Dsc Salome Extension, you need to set environment + variable: \b PARALLEL_KERNEL_ROOT_DIR. + + The building process is the traditional configure/make/make install: + - configure --prefix=path_to_install + - make + + Then you can run unit tests if cppunits is installed : + - make check + + Then you can run a small demo in Demo directory: + - cd Demo + - make + - launch the echoSrv server : echoSrv& (if the omniorb name server is not + running you need to launch it : omniNames& should be enough) + - run yacs supervisor with the schema.xml file : ../src/yacsloader/driver schema.xml + + Finally you can install yacs: + - make install + - read the doc in doc directory + - go to src/yacsloader/samples directory for XML examples + + \section TODOs + + Many things but mainly: + - add resource management features + - add GUIs + +*/ + +/*! \defgroup TypeCodes TypeCodes + */ + +/*! \defgroup Nodes Nodes + */ + +/*! \defgroup Ports Ports + */ + +/*! \defgroup AdaptorPorts AdaptorPorts + */ + +/*! \defgroup Executors Executor objects + */ + diff --git a/doc/yacsloader.dox b/doc/yacsloader.dox new file mode 100644 index 000000000..1309a0bc6 --- /dev/null +++ b/doc/yacsloader.dox @@ -0,0 +1,641 @@ +/*! \page xml_loader XML file loader + +\section toc Table of contents + + - \ref loader_intro + - \ref loader_programming + - \ref loader_use + - \ref loader_file + + +\section loader_intro Introduction + +The yacs loader is a class that can be used to load a calculation schema +in memory by reading and parsing a XML file describing it. + +\section loader_programming Programming with the yacs loader class + +To use the yacs loader class, first create a specific runtime (here a Salome one). + +Then you can create an instance of the yacsloader class and call +the load method with the name of the XML file as argument. + +The call to the method will return a calculation schema (instance of the Proc class). + +\code +#include "RuntimeSALOME.hxx" +#include "parser.hxx" + +YACS::ENGINE::RuntimeSALOME::setRuntime(); +YACS::YACSLoader loader; + +YACS::ENGINE::Proc* p=loader.load("file.xml"); + +\endcode + +You can then dump to a file a graphviz diagram by calling the writeDot +method on the schema. + +\code +#include + +std::ofstream f("proc.dot"); +p->writeDot(f); +f.close(); +\endcode + +You can display the diagram with: dot -Tpng proc.dot |display. + +And then execute the schema with an Executor. + +\code +#include "Executor.hxx" + +YACS::ENGINE::Executor executor; +executor.RunW(p); +\endcode + +\section loader_use Using the yacs driver + +The driver program is a program that loads a schema file and executes it +until its end. It is possible to display the schema state during the +execution by specifying the --display option. An exemple of use is: + +\code +driver --display=1 schema.xml +\endcode + +Internally, it uses the loader class, the Salome runtime, the standard +executor with all is necessary to catch exceptions. + +\section loader_file Writing a XML file + +To write a XML file describing a calculation schema, you need to define +several objects that are listed here : + + - the calculation schema + - data types + - elementary calculation nodes + - connections between nodes + - initialization parameters + - composed calculation nodes + + +\subsection loader_schema Defining calculation schema +To define a calculation schema, simply open a proc tag +\code + + +\endcode + +All following definitions must be put betwween these tags. + +\subsection loader_types Defining data types +A calculation schema is composed of interconnected calculation nodes. +These nodes exchange data through data ports (in and out). The first +thing you need to do is to define all types that can be exchanged +in the schema. + +Some types are already defined by the runtime you use. For example, the +Salome runtime defines : int, double, string and bool types. It can also +define all types used by the declared components. At the moment, the +Salome runtime knows nothing about the types used by the declared components +so it is mandatory to define all data types except the four basic ones. + +It is possible to define three kind of types : basic, sequence and objref. + +A basic type is an atomic one so it can only be int, double, string and bool. +They are already defined so what can be defined is only alias to these types. + +A definition of an alias to the double data type : +\code + +\endcode + +A sequence type is a constructed type that is built on already existing +types. A sequence type defines a list of elements. The definition +gives the name of the type and the type of the elements of the sequence. + +To define a sequence of double type, add : +\code + +\endcode + +All attributes in the sequence tag are mandatory. + +You can then define a sequence of sequence by : +\code + +\endcode + +An objref data type is an equivalent of a class in object languages. +Salome components use objects which have types such as Mesh, Field, ... +All these types can be related by inheritance relations. + +Defining a base objref : +\code + +\endcode + +Defining a derived objref from mesh : +\code + + mesh + +\endcode + +It is possible to derive an objref from multiple base objref and objref names +can use name spaces. Just use a / as separator. +\code + +\endcode +It is useful for Salome components because objref must be mapped to +CORBA types which can use name spaces. + +Finally, it is possible to define a sequence of objref : +\code + +\endcode + +\b RESTRICTION : struct type is not supported + +\subsection loader_nodes Defining elementary calculation nodes +The next step is to define calculation nodes : service nodes or inline +nodes. + +There are three kinds of inline nodes : script inline node, function +inline node and clone inline node, +and three kinds of service nodes : component service node, reference +service node and node service node. + +The definition of all these nodes is described below. + +- Script inline node + +This kind of node corresponds to the execution of a python script with input +and output parameters. Input and output parameters are passed to the +script through data ports. +A very simple example of an script inline node is : +\code + + + + +\endcode + +The inline node has a mandatory name as all kind of nodes. +The script tag indicates that it is a script inline node. +The python script appears in as much lines as necessary between code tags in the script +section. +If your script contains a lot of "<" or "&" characters - as program code often does - +the XML element can be defined as a CDATA section. +A CDATA section starts with "": + +In the example above the script calculates p1 that is an output parameter. +An output data port must then be defined. A output data port is defined +in an outport tag with two mandatory attributes : name and type that references +an already defined data type. +To define an input data port use the inport tag in place of outport. + +Example of an inline node with input and output arguments : +\code + + + + + +\endcode +Now the calculation node receives p1 as an input argument adds 10 to it +and sends it as an output argument. + +- Function inline node + +This kind of node corresponds to the execution of a python function with input +and output parameters. Input and output parameters are passed to the +script through data ports. +The main difference with the script node is the execution part. The definition +of input and output ports is unchanged. In the execution part use the function +tag in place of the script tag and add a name (mandatory) which must be the same +as that of the function. + +An example of an function inline node is : +\code + + + def f(p1): + p1=p1+10 + return p1 + + + + +\endcode + +- Clone inline node + +This node is a convenience node to avoid repeating an inline definion. +It allows to create an inline calculation by using the definition +of another inline node. Such a kind of node is defined in a node tag +with two mandatory attributes : name (the node name) and type that indicates the name +of the already existing inline node to use for the definition. Example : + +\code + +\endcode + +- Reference service node + +A service node corresponds to the execution of a service available from a +calculation server. It can thought of as the execution of an object method. +A service node is defined in a service tag in place of the inline tag for +the inline node. + +In a reference service node the calculation server is known by its address (which +is a string meaningful for the runtime) and is supposed to exists +before executing the calculation schema. The service is known by its name. +Then the service has input and output arguments that are passed through ports +in the same way as the inline nodes. +The server address is defined as a string in a ref tag and the service name is +defined in a method tag. +Example : +\code + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + +\endcode + +The service node node4 is a reference service node because it has a ref +section. The address of the calculation server to use is a CORBA address +that must be meaningful to the runtime. The service to use is the +CORBA operation echoDouble that just gets the input and returns it. + +- Component service node + +This kind of node is similar to the previous one but the server does not +exist before the beginning of the execution. It's the runtime that is in charge +of loading the calculation server or component for Salome platform. +Instead of defining the address of the server we give the name of the +component that will be loaded through the runtime by the platform. +This name is given in a component tag in place of the ref tag. +Example : +\code + + ECHO + echoDouble + + + +\endcode + +- Node service node + +It's a special node that gives the possibility to create a service node that calls +a service of an already loaded component. To define such a node you need to +indicate the name of an already existing component service node in a node tag +in place of the previous component tag. + +A short example is better than a long speech : +\code + + node4 + echoString + + + +\endcode +Here, node5 is a service node that executes the echoString service of the +component that has been loaded by the component service node node4. + +\subsection loader_connections Defining connections between nodes +After having defined all the calculation nodes needed, it is necessary +to connect them to define the order of execution (control flow) + and the exchanges of data (data flow). + +- Control flow + +The order of execution is defined by means of control links between +nodes. +These links are defined in a control tag with subtags fromnode and tonode +which give the names of precedent node and following node. +Example of control link : +\code + + node1 + node2 + +\endcode +This control link indicates that execution of node2 must be after complete +execution of node1. + +- Data flow + +Exchange of data between nodes is defined by means of data links between +output ports and input ports. +These links are defined in a datalink tag with subtags fromnode, tonode, fromport +and toport. The output port is specified with the node name and the output port +name. It's similar for the input port. + +Example of data link : +\code + + node1 p1 + node2 p1 + +\endcode +This data link indicates that the output argument p1 of node node1 +will be sent to node node2 and used as input argument p1. +By default, with this datalink definition, a control link is automatically defined between node1 and node2, +to ensure a complete execution of node1 before node2 starts. +Sometimes, this control link must not be created, for instance with loops (see below). +With most simple cases, yacs loader is able to decide to create or not the control link. It is always +possible to ask explicitely a data link without control link: +\code + + node1 p1 + node2 p1 + +\endcode + +So, it is equivalent to write: +\code + + node1 p1 + node2 p1 + +\endcode +Or: +\code + + node1 + node2 + + + node1 p1 + node2 p1 + +\endcode +Control links may be defined implicitely several times without problem. + +\subsection loader_parameters Defining initialization parameters +It is possible to initialize directly input ports with constants. +This is done with a definition put in a parameter tag with subtags tonode, +toport and value. +tonode is the name of the node and toport the name of the port to initialize. +value gives the constant to use to initialize the port. This constant is +given in XML-RPC coding convention (http://www.xmlrpc.com/). + +Example of parameter initialization : +\code + + node1 p1 + coucou + +\endcode + + +This parameter initialization indicates that the input argument p1 +of node1 is initialized with a string constant ("coucou"). + +\subsection loader_example1 Putting all this together +Now that we are able to define data types, calculation nodes and links, we +can define a complete calculation schema with interconnected calculation. + +\code + + + + + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + node1 node2 + + + node1 node4 + + + node1 p1 + node2 p1 + + + node1 p1 + node4 p1 + + + node1 p1 + 5 + + +\endcode +We have put together 2 inline nodes and one reference service node +with nodes node2 and node4 that will be concurrently executed as can +be seen on the control flow diagram below. + +\image html schema.jpeg + +\subsection loader_composed Defining composed calculation nodes +The next step is to define composed nodes either to modularize the calculation +schema or to introduce control nodes like loop or switch. + +- Using block to modularize the schema + +All the previously defined elements (except the data types) can be put +in block nodes. It is easy : create a bloc tag with an attribute name +that contains all the definitions and you have a composed node that is +a block. + +Example of block : +\code + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + node1 node4 + + + node1 p1 + node4 p1 + + +\endcode +This block can now be linked with other nodes of any kind in the same way +as elementary nodes. +The rules are : it is not possible to set control links that cross the boundary +of the block. On the other end, it is possible to set data links that cross +this boundary either on input or on output. + +- Defining a For Loop + +If you want to execute a calculation n times, you can use a ForLoop node +to define this kind of computation. +A for loop is defined in a forloop tag that has 2 attributes : name and nsteps. +name is as always the name of the node and nsteps is the number of steps of the +loop. The for loop must contain one and only one node that can be an elementary +calculation node or a composed node. It is possible to have a for loop in a for loop, for +example. If you want to put more than one calculation node in a for loop, use +a block. + +Example : +\code + + + + + + + +\endcode +The rules are the same as for the block node. But inside loops, to be able to perform +iterative computation, it is allowed to link an output port of an internal node +with an input port of a previous node in control flow. The only limitation is that +you have to put the node and the data link in a block node as links can't be defined +in a forloop section. + +Here is an example : +\code + + + + + + + + + node2 p1 + node2 p1 + + + +\endcode + +Last point : it is possible to link the nsteps entry of the for loop +with an output port that produces integer data. The input port +of the loop has the same name as the attribute (nsteps). + +- Defining a While Loop + +This kind of loop is mainly similar to the for loop. The only difference is that +the loop executes as long as a condition is true. A while loop is defined in +a whileloop tag and has only one attribute : name as usual. +The condition value is set through an input port (which name is condition) +that accepts boolean value. + +Example of a while loop: +\code + + + + + + + + + + node2 p1 + node2 p1 + + + + + l1.b.node2 condition + l1 condition + + + l1.b.node2 p1 + 23 + +\endcode + +It is here again possible to define composed node of any kind as internal +node to define loops in loops. + +- Defining a Switch Loop + +A switch node is equivalent to a switch C. It has an input port (which name +is select) that accepts integer data. According to the value in the select +port one or another case node is selected for execution. Each case is defined +in a case tag with one attribute id that must be an integer or default. If no case +is defined for the select value the switch node uses the default case. +A case can contain one and only one internal node. + +A minimal but almost complete example : +\code + + + + + + + + + + + + + + + + + + + + + + + n b1 + nselect + b1 select + + b1.3.n2 p1 + 54 + + + b1.default.n2 p1 + 54 + +\endcode + + +*/ diff --git a/idl/Makefile.am b/idl/Makefile.am new file mode 100644 index 000000000..0994d10e9 --- /dev/null +++ b/idl/Makefile.am @@ -0,0 +1,23 @@ + +include $(top_srcdir)/adm/unix/make_begin.am + +IDL_FILES = yacsgui.idl +IDL_SRC = yacsguiSK.cc +BUILT_SOURCES = $(IDL_SRC) yacsgui_idl.py + +OMNIORB_IDL+= -I$(KERNEL_ROOT_DIR)/idl/salome -I$(GUI_ROOT_DIR)/idl/salome + +IDLPYFLAGS = \ + -I$(KERNEL_ROOT_DIR)/idl/salome + +install-exec-local: install-pyidl + +install-pyidl: $(IDL_FILES) + $(INSTALL) -d $(pkgpythondir) + @for file in $^ dummy; do \ + if [ $$file != "dummy" ]; then \ + $(OMNIORB_IDL) -bpython $(IDLPYFLAGS) -C$(pkgpythondir) $$file ; \ + fi ; \ + done ; + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/idl/yacsgui.idl b/idl/yacsgui.idl new file mode 100644 index 000000000..d44727f38 --- /dev/null +++ b/idl/yacsgui.idl @@ -0,0 +1,52 @@ +#ifndef __YACSGUI_IDL__ +#define __YACSGUI_IDL__ + +#include "SALOME_Component.idl" +#include "SALOMEDS.idl" +#include "SALOME_Exception.idl" + + // SALOME Engine interface for execution in a SALOME Container + +module YACSGui_ORB +{ + enum executionMode { CONTINUE, STEPBYSTEP, STOPBEFORENODES }; + + typedef sequence stringArray; + typedef sequence longArray; + + interface Observer + { + void notifyObserver(in long numid , in string event); + }; + + interface ProcExec + { + long getNodeState(in long numid); + string getXMLState(in long numid); + long getExecutorState(); + void getIds(out longArray numids,out stringArray names); + longArray getNumIds(); + stringArray getNames(); + + void Run(); + void addObserver(in Observer obs,in long numid, in string event); + void setExecMode(in executionMode mode); + void setListOfBreakPoints(in stringArray listOfBreakPoints); + stringArray getTasksToLoad(); + boolean setStepsToExecute(in stringArray listToExecute); + boolean resumeCurrentBreakPoint(); + boolean isNotFinished(); + void stopExecution(); + boolean saveState(in string xmlFile); + void setStopOnError(in boolean dumpRequested, in string xmlFile); + }; + + interface YACSGui_Gen : Engines::Component, SALOMEDS::Driver + { + ProcExec LoadProc(in string xmlFile); + string convertSupervFile(in string xmlFile); + }; + +}; + +#endif diff --git a/root_clean b/root_clean index bb28a91fa..8d3180095 100755 --- a/root_clean +++ b/root_clean @@ -12,9 +12,11 @@ TO_CLEAN=${TO_CLEAN}' configure' TO_CLEAN=${TO_CLEAN}' configure.in' TO_CLEAN=${TO_CLEAN}' missing' TO_CLEAN=${TO_CLEAN}' install-sh' +TO_CLEAN=${TO_CLEAN}' ltmain.sh' TO_CLEAN=${TO_CLEAN}' config.guess' TO_CLEAN=${TO_CLEAN}' config.sub' TO_CLEAN=${TO_CLEAN}' depcomp' +TO_CLEAN=${TO_CLEAN}' yacs_config.h.in' rm -rf $TO_CLEAN > /dev/null diff --git a/src/Makefile.am b/src/Makefile.am index 1660ccb3b..08b52a4c9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,2 +1,5 @@ - -SUBDIRS = bases engine runtime +if HAS_GUI +SUBDIRS = bases engine runtime wrappergen yacsloader yacsorb pyqt lineconn2d prs gui +else +SUBDIRS = bases engine runtime wrappergen yacsloader yacsorb salomeloader +endif diff --git a/src/bases/Cstr2d.cxx b/src/bases/Cstr2d.cxx new file mode 100644 index 000000000..b515445c6 --- /dev/null +++ b/src/bases/Cstr2d.cxx @@ -0,0 +1,27 @@ + +#include "Cstr2d.hxx" +#include "Exception.hxx" + +#include +#include + +//! replacement for atof witch does not work everywhere +/*! + * When using xml parser (parser.cxx) from YACSGui_XMLDriver (in GUI context), + * instruction like double d = atof(content); where content = "0.8" + * gives d = 0 . + * the same binary code called from outside GUI context works fine... + */ + +double Cstr2d(const char* s) +{ + std::istringstream ss(s); + double d; + if (!(ss >> d)) + { + std::stringstream msg; + msg << "problem in conversion from string to double: " << s ; + throw YACS::Exception::Exception(msg.str()); + } + return d; +} diff --git a/src/bases/Cstr2d.hxx b/src/bases/Cstr2d.hxx new file mode 100644 index 000000000..6b7fcbeb6 --- /dev/null +++ b/src/bases/Cstr2d.hxx @@ -0,0 +1,7 @@ + +#ifndef __CSTR2D_HXX__ +#define __CSTR2D_HXX__ + +double Cstr2d(const char* s); + +#endif diff --git a/src/bases/DrivenCondition.cxx b/src/bases/DrivenCondition.cxx new file mode 100644 index 000000000..9d8cde622 --- /dev/null +++ b/src/bases/DrivenCondition.cxx @@ -0,0 +1,7 @@ +#include "DrivenCondition.hxx" + +#if defined(YACS_PTHREAD) +#include "DrivenConditionPT.cxx" +#else +#error +#endif diff --git a/src/bases/DrivenCondition.hxx b/src/bases/DrivenCondition.hxx new file mode 100644 index 000000000..0ecd2102d --- /dev/null +++ b/src/bases/DrivenCondition.hxx @@ -0,0 +1,35 @@ +#ifndef __DRIVENCONDITION_HXX__ +#define __DRIVENCONDITION_HXX__ + +// --- Interface is: + +// class DrivenCondition +// { +// public: +// DrivenCondition(); +// ~DrivenCondition(); +// //On master thread +// void waitForAWait(); +// void notifyOneSync(); +// //On slave thread +// void wait(); +// }; + + +#if defined(YACS_PTHREAD) +#include "DrivenConditionPT.hxx" + +namespace YACS +{ + namespace BASES + { + typedef DrivenConditionPT DrivenCondition; + } +} +#else +#error +#endif + + +#endif + diff --git a/src/bases/DrivenConditionPT.cxx b/src/bases/DrivenConditionPT.cxx new file mode 100644 index 000000000..c1d29e792 --- /dev/null +++ b/src/bases/DrivenConditionPT.cxx @@ -0,0 +1,42 @@ +#include "DrivenConditionPT.hxx" + +using namespace YACS::BASES; + +DrivenConditionPT::DrivenConditionPT() +{ + pthread_mutex_init(&_mutexDesc1, NULL); + pthread_mutex_init(&_mutexDesc2, NULL); + pthread_cond_init(&_cond1, NULL); + pthread_cond_init(&_cond2, NULL); + pthread_mutex_lock(&_mutexDesc1); + pthread_mutex_lock(&_mutexDesc2); +} + +DrivenConditionPT::~DrivenConditionPT() +{ + pthread_cond_destroy(&_cond1); + pthread_cond_destroy(&_cond2); + pthread_mutex_destroy(&_mutexDesc1); + pthread_mutex_destroy(&_mutexDesc2); +} + +void DrivenConditionPT::notifyOneSync() +{ + pthread_mutex_lock(&_mutexDesc1); + pthread_cond_signal(&_cond1); + pthread_mutex_unlock(&_mutexDesc1); + pthread_cond_wait(&_cond2, &_mutexDesc2); +} + +void DrivenConditionPT::waitForAWait() +{ + pthread_cond_wait(&_cond2, &_mutexDesc2); +} + +void DrivenConditionPT::wait() +{ + pthread_mutex_lock(&_mutexDesc2); + pthread_cond_signal(&_cond2); + pthread_mutex_unlock(&_mutexDesc2); + pthread_cond_wait(&_cond1,&_mutexDesc1); +} diff --git a/src/bases/DrivenConditionPT.hxx b/src/bases/DrivenConditionPT.hxx new file mode 100644 index 000000000..dff140ed0 --- /dev/null +++ b/src/bases/DrivenConditionPT.hxx @@ -0,0 +1,29 @@ +#ifndef __DRIVENCONDITIONPT_HXX__ +#define __DRIVENCONDITIONPT_HXX__ + +#include + +namespace YACS +{ + namespace BASES + { + class DrivenConditionPT + { + public: + DrivenConditionPT(); + ~DrivenConditionPT(); + //On master thread + void waitForAWait(); + void notifyOneSync(); + //On slave thread + void wait(); + private: + pthread_cond_t _cond1; + pthread_cond_t _cond2; + pthread_mutex_t _mutexDesc1; + pthread_mutex_t _mutexDesc2; + }; + } +} + +#endif diff --git a/src/bases/DynLibLoader.cxx b/src/bases/DynLibLoader.cxx new file mode 100644 index 000000000..9bd79ccf2 --- /dev/null +++ b/src/bases/DynLibLoader.cxx @@ -0,0 +1,7 @@ +#include "DynLibLoader.hxx" + +#if defined(YACS_PTHREAD) +#include "DynLibLoaderGNU.cxx" +#else +#error +#endif diff --git a/src/bases/DynLibLoader.hxx b/src/bases/DynLibLoader.hxx new file mode 100644 index 000000000..507d7c5f6 --- /dev/null +++ b/src/bases/DynLibLoader.hxx @@ -0,0 +1,38 @@ +#ifndef __DYNLIBLOADER_HXX__ +#define __DYNLIBLOADER_HXX__ + +#include + +// --- Interface is: + +// class DynLibLoader +// { +// public: +// DynLibLoader(const std::string& libNameWithoutExtension); +// ~DynLibLoader(); +// bool isLibFileFindable() const; +// int appendDirInSearchPath(const std::string& dirName); +// int removeDirInSearchPath(const std::string& dirName); +// void *getHandleOnSymbolWithName(const std::string& symbName); +// static const char *getExtensionForDynLib(); +// }; + + +#if defined(YACS_PTHREAD) +#include "DynLibLoaderGNU.hxx" + +namespace YACS +{ + namespace BASES + { + typedef DynLibLoaderGNU DynLibLoader; + } +} + +#else + +#error + +#endif + +#endif diff --git a/src/bases/DynLibLoaderGNU.cxx b/src/bases/DynLibLoaderGNU.cxx new file mode 100644 index 000000000..cc02eab44 --- /dev/null +++ b/src/bases/DynLibLoaderGNU.cxx @@ -0,0 +1,109 @@ +#include "DynLibLoaderGNU.hxx" +#include +#include + +using namespace YACS::BASES; + +const char DynLibLoaderGNU::_extForDynLib[]=".so"; + +DynLibLoaderGNU::DynLibLoaderGNU(const std::string& libNameWithoutExtension):_libName(libNameWithoutExtension), + _handleOnLoadedLib(0) +{ +} + +DynLibLoaderGNU::~DynLibLoaderGNU() +{ + if(_handleOnLoadedLib) + dlclose(_handleOnLoadedLib); +} + +bool DynLibLoaderGNU::isLibFileFindable() const +{ + return true; +} + +std::string DynLibLoaderGNU::getLibNameWithoutExt() const +{ + return _libName; +} + +/*! + Append a directory with name \b dirName to the searching paths. + \return If append succeeds 0 is returned. + If the directory does not exists 1 is returned. + If the addition of directory causes some troubles due to seach paths name 2 is returned. + */ +int DynLibLoaderGNU::appendDirInSearchPath(const std::string& dirName) +{ + return 0; +} + +/*! + Removes a directory with name \b dirName from the searching paths. + \return If removal succeeds 0 is returned. + If the directory does not exists 1 is returned. + If the path were not already in existing paths 2 is returned. + */ +int DynLibLoaderGNU::removeDirInSearchPath(const std::string& dirName) +{ + return 0; +} + +void *DynLibLoaderGNU::getHandleOnSymbolWithName(const std::string& symbName, bool stopOnError) +{ + if(!_handleOnLoadedLib) + if(!isLibFileFindable()) + { + std::cerr << "Dynamic library with name " << symbName << _extForDynLib; + std::cerr << " not existing in paths specified" << std::endl; + return 0; + } + else + loadLib(); + return resolveSymb(symbName, stopOnError); +} + +bool DynLibLoaderGNU::load() +{ + std::string fullLibName(_libName); + fullLibName+=_extForDynLib; + _handleOnLoadedLib=dlopen(fullLibName.c_str(),RTLD_LAZY | RTLD_GLOBAL); + return _handleOnLoadedLib != NULL; +} + +bool DynLibLoaderGNU::unload() +{ + if (_handleOnLoadedLib) + { + dlclose(_handleOnLoadedLib); + _handleOnLoadedLib = NULL; + } +} + +bool DynLibLoaderGNU::reload() +{ + unload(); + return load(); +} + +void *DynLibLoaderGNU::resolveSymb(const std::string& symbName, bool stopOnError) +{ + dlerror(); + void *ret=dlsym(_handleOnLoadedLib,symbName.c_str()); + char *message=dlerror(); + if(stopOnError && (NULL != message)) + { + std::cerr << "Error detected on symbol " << symbName << " search in library with name " << _libName << _extForDynLib; + std::cerr << " with the following internal message"<< std::endl; + std::cerr << message << std::endl; + return 0; + } + else + return ret; +} + +const char *DynLibLoaderGNU::getExtensionForDynLib() +{ + return _extForDynLib+1; +} + diff --git a/src/bases/DynLibLoaderGNU.hxx b/src/bases/DynLibLoaderGNU.hxx new file mode 100644 index 000000000..893972143 --- /dev/null +++ b/src/bases/DynLibLoaderGNU.hxx @@ -0,0 +1,36 @@ +#ifndef __DYNLIBLOADERGNU_HXX__ +#define __DYNLIBLOADERGNU_HXX__ + +#include + +namespace YACS +{ + namespace BASES + { + class DynLibLoaderGNU + { + private: + void *_handleOnLoadedLib; + std::string _libName; + static const char _extForDynLib[]; + public: + DynLibLoaderGNU(const std::string& libNameWithoutExtension); + ~DynLibLoaderGNU(); + bool isLibFileFindable() const; + std::string getLibNameWithoutExt() const; + int appendDirInSearchPath(const std::string& dirName); + int removeDirInSearchPath(const std::string& dirName); + void *getHandleOnSymbolWithName(const std::string& symbName, bool stopOnError=true); + static const char *getExtensionForDynLib(); + bool load(); + bool reload(); + bool unload(); + + private: + void loadLib() { load(); }//! load lib without regarding that _libName is reachable + void *resolveSymb(const std::string& symbName, bool stopOnError); + }; + } +} + +#endif diff --git a/src/bases/DynLibLoaderWin.cxx b/src/bases/DynLibLoaderWin.cxx new file mode 100644 index 000000000..b7a78195b --- /dev/null +++ b/src/bases/DynLibLoaderWin.cxx @@ -0,0 +1,78 @@ +#include "DynLibLoaderWin.hxx" +#include +#include + +using namespace YACS::BASES; + +const char DynLibLoaderWin::_extForDynLib[]=".dll"; + +DynLibLoaderWin::DynLibLoaderWin(const std::string& libNameWithoutExtension):_libName(libNameWithoutExtension), + _handleOnLoadedLib(0) +{ +} + +DynLibLoaderWin::~DynLibLoaderWin() +{ + if(_handleOnLoadedLib) + dlclose(_handleOnLoadedLib); +} + +bool DynLibLoaderWin::isLibFileFindable() const +{ + return true; +} + +/*! + Append a directory with name \b dirName to the searching paths. + \return If append succeeds 0 is returned. + If the directory does not exists 1 is returned. + If the addition of directory causes some troubles due to seach paths name 2 is returned. + */ +int DynLibLoaderWin::appendDirInSearchPath(const std::string& dirName) +{ + return 0; +} + +/*! + Removes a directory with name \b dirName from the searching paths. + \return If removal succeeds 0 is returned. + If the directory does not exists 1 is returned. + If the path were not already in existing paths 2 is returned. + */ +int DynLibLoaderWin::removeDirInSearchPath(const std::string& dirName) +{ + return 0; +} + +void *DynLibLoaderWin::getHandleOnSymbolWithName(const std::string& symbName) +{ + if(!_handleOnLoadedLib) + if(!isLibFileFindable()) + { + std::cerr << "Dynamic library with name " << symbName << _extForDynLib; + std::cerr << " not existing in paths specified" << std::endl; + return 0; + } + else + loadLib(); + return resolveSymb(symbName); +} + +void DynLibLoaderWin::loadLib() +{ + std::string fullLibName(_libName); + fullLibName+=_extForDynLib; + _handleOnLoadedLib=LoadLibrary(fullLibName.c_str()); +} + +void *DynLibLoaderWin::resolveSymb(const std::string& symbName) +{ + void *ret=GetProcAddress(_handleOnLoadedLib,symbName.c_str()); + return ret; +} + +const char *DynLibLoaderWin::getExtensionForDynLib() +{ + return _extForDynLib+1; +} + diff --git a/src/bases/DynLibLoaderWin.hxx b/src/bases/DynLibLoaderWin.hxx new file mode 100644 index 000000000..39eb59493 --- /dev/null +++ b/src/bases/DynLibLoaderWin.hxx @@ -0,0 +1,31 @@ +#ifndef __DYNLIBLOADERWIN_HXX__ +#define __DYNLIBLOADERWIN_HXX__ + +#include + +namespace YACS +{ + namespace BASES + { + class DynLibLoaderWin + { + private: + void *_handleOnLoadedLib; + std::string _libName; + static const char _extForDynLib[]; + public: + DynLibLoaderWin(const std::string& libNameWithoutExtension); + ~DynLibLoaderWin(); + bool isLibFileFindable() const; + int appendDirInSearchPath(const std::string& dirName); + int removeDirInSearchPath(const std::string& dirName); + void *getHandleOnSymbolWithName(const std::string& symbName); + static const char *getExtensionForDynLib(); + private: + void loadLib();//! load lib without regarding that _libName is reachable + void *resolveSymb(const std::string& symbName); + }; + } +} + +#endif diff --git a/src/bases/Exception.hxx b/src/bases/Exception.hxx index d4cde4032..8575f1215 100644 --- a/src/bases/Exception.hxx +++ b/src/bases/Exception.hxx @@ -13,7 +13,7 @@ namespace YACS public: Exception(const std::string& what); const char *what( void ) const throw (); - ~Exception() throw (); + virtual ~Exception() throw (); }; } diff --git a/src/bases/Makefile.am b/src/bases/Makefile.am index 5231ecfa4..8fbbbfff8 100644 --- a/src/bases/Makefile.am +++ b/src/bases/Makefile.am @@ -6,15 +6,37 @@ SUBDIRS = Test noinst_LTLIBRARIES = libYACSBases.la libYACSBases_la_SOURCES = Exception.cxx Thread.cxx Mutex.cxx Semaphore.cxx \ + DynLibLoader.cxx DrivenCondition.cxx \ + Cstr2d.cxx YacsTrace.cxx \ $(__dummy__) EXTRA_libYACSBases_la_SOURCES = Thread.hxx ThreadPT.hxx ThreadPT.cxx \ Mutex.hxx MutexPT.cxx MutexPT.hxx \ Semaphore.hxx SemaphorePT.cxx SemaphorePT.hxx \ + DynLibLoader.hxx DynLibLoaderGNU.hxx \ + DrivenCondition.hxx DrivenConditionPT.hxx \ Exception.hxx \ $(__dummy__) +salomeinclude_HEADERS = \ + Cstr2d.hxx \ + define.hxx \ + DrivenCondition.hxx \ + DrivenConditionPT.hxx \ + DynLibLoaderGNU.hxx \ + DynLibLoader.hxx \ + DynLibLoaderWin.hxx \ + Exception.hxx \ + Mutex.hxx \ + MutexPT.hxx \ + Semaphore.hxx \ + SemaphorePT.hxx \ + Thread.hxx \ + ThreadPT.hxx \ + YacsTrace.hxx \ + $(__dummy__) + AM_CXXFLAGS = $(THREAD_DEF) include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/bases/Mutex.hxx b/src/bases/Mutex.hxx index cfc250012..09ffab91d 100644 --- a/src/bases/Mutex.hxx +++ b/src/bases/Mutex.hxx @@ -1,15 +1,25 @@ #ifndef __MUTEX_HXX__ #define __MUTEX_HXX__ -/* Interface is : - class Mutex - { - public: - Mutex(); - void lock(); - void unlock(); - }; - */ +// --- Interface is: + +// class Mutex +// { +// public: +// Mutex(); +// void lock(); +// void unlock(); +// }; + +// class Condition +// { +// public: +// Condition(); +// void notify_one(); +// void notify_all(); +// void wait(Mutex& mutex); +// }; + #if defined(YACS_PTHREAD) #include "MutexPT.hxx" @@ -19,6 +29,7 @@ namespace YACS namespace BASES { typedef MutexPT Mutex; + typedef ConditionPT Condition; } } #else diff --git a/src/bases/MutexPT.cxx b/src/bases/MutexPT.cxx index 8233a3936..d1a5df7c8 100644 --- a/src/bases/MutexPT.cxx +++ b/src/bases/MutexPT.cxx @@ -4,8 +4,9 @@ using namespace YACS::BASES; MutexPT::MutexPT() { - pthread_mutexattr_settype(&_options, PTHREAD_MUTEX_FAST_NP); - pthread_mutex_init(&_mutexDesc, &_options); + //pthread_mutexattr_settype(&_options, PTHREAD_MUTEX_FAST_NP); + //pthread_mutex_init(&_mutexDesc, &_options); + pthread_mutex_init(&_mutexDesc, NULL); // potential hang up at start with commented init } MutexPT::~MutexPT() @@ -22,3 +23,29 @@ void MutexPT::unlock() { pthread_mutex_unlock(&_mutexDesc); } + +ConditionPT::ConditionPT() +{ + pthread_cond_init(&_cond, NULL); +} + +ConditionPT::~ConditionPT() +{ + pthread_cond_destroy(&_cond); +} + +void ConditionPT::notify_one() +{ + pthread_cond_signal(&_cond); +} + +void ConditionPT::notify_all() +{ + pthread_cond_broadcast(&_cond); +} + +void ConditionPT::wait(MutexPT& mutex) +{ + pthread_cond_wait(&_cond, &mutex._mutexDesc); +} + diff --git a/src/bases/MutexPT.hxx b/src/bases/MutexPT.hxx index ef7c94052..706de6ff2 100644 --- a/src/bases/MutexPT.hxx +++ b/src/bases/MutexPT.hxx @@ -7,6 +7,8 @@ namespace YACS { namespace BASES { + class ConditionPT; + class MutexPT { public: @@ -14,11 +16,24 @@ namespace YACS ~MutexPT(); void lock(); void unlock(); + friend class ConditionPT; private: pthread_mutex_t _mutexDesc; pthread_mutexattr_t _options; }; + + class ConditionPT + { + public: + ConditionPT(); + ~ConditionPT(); + void notify_one(); + void notify_all(); + void wait(MutexPT& mutex); + private: + pthread_cond_t _cond; + }; } } diff --git a/src/bases/Test/BasicMainTest.hxx b/src/bases/Test/BasicMainTest.hxx index 3794dcc1c..7111d3446 100644 --- a/src/bases/Test/BasicMainTest.hxx +++ b/src/bases/Test/BasicMainTest.hxx @@ -27,10 +27,12 @@ #include #include #include +#include #include #include #include +#include // ============================================================================ /*! @@ -39,12 +41,14 @@ */ // ============================================================================ +#include "UnitTestsResult.hxx" + int main(int argc, char* argv[]) { // --- Create the event manager and test controller CPPUNIT_NS::TestResult controller; - // --- Add a listener that colllects test result + // --- Add a listener that collects test result CPPUNIT_NS::TestResultCollector result; controller.addListener( &result ); @@ -64,13 +68,17 @@ int main(int argc, char* argv[]) // --- Adds the test to the list of test to run CPPUNIT_NS::TestRunner runner; + //CPPUNIT_NS::TextTestRunner runner; runner.addTest( suite ); runner.run( controller); + //bool wasSucessful = runner.run(); // --- Print test in a compiler compatible format. + system("mkdir -p /tmp/${USER}"); std::ofstream testFile; - testFile.open("UnitTestsResult", std::ios::out | std::ios::trunc); + testFile.open(UnitTestsResult.c_str(), std::ios::out | std::ios::app); + testFile << UNIT_TEST_HEADER << endl; //CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr ); CPPUNIT_NS::CompilerOutputter outputter( &result, testFile ); outputter.write(); diff --git a/src/bases/Test/DLTest.cxx b/src/bases/Test/DLTest.cxx new file mode 100644 index 000000000..60c17103c --- /dev/null +++ b/src/bases/Test/DLTest.cxx @@ -0,0 +1,4 @@ +extern "C" double myYacsFct(double d) +{ + return 7.*d*d; +} diff --git a/src/bases/Test/InitTests.cxx b/src/bases/Test/InitTests.cxx new file mode 100644 index 000000000..07b5c3c22 --- /dev/null +++ b/src/bases/Test/InitTests.cxx @@ -0,0 +1,15 @@ +#include "UnitTestsResult.hxx" +#include + +/*! + */ + +int main(int argc, char* argv[]) +{ + std::ofstream testFile; + system("mkdir -p /tmp/${USER}"); + testFile.open(YACS::UnitTestsResult.c_str(), std::ios::out | std::ios::trunc); + testFile << " --- YACS Unit Tests summary ---" << std::endl; + testFile.close(); + return 0; +} diff --git a/src/bases/Test/Makefile.am b/src/bases/Test/Makefile.am index 70c681e5a..16e0dae16 100644 --- a/src/bases/Test/Makefile.am +++ b/src/bases/Test/Makefile.am @@ -3,7 +3,17 @@ include $(top_srcdir)/adm/unix/make_begin.am AM_CXXFLAGS = $(THREAD_DEF) -I$(srcdir)/.. -check_PROGRAMS = TestBases +check_PROGRAMS = InitTests TestBases + +lib_LTLIBRARIES = libYACSDLTest.la + +libYACSDLTest_la_SOURCES = DLTest.cxx + +libYACSDLTest_la_CXXFLAGS = $(THREAD_DEF) + +InitTests_SOURCES = InitTests.cxx + +InitTests__CXXFLAGS = -I$(srcdir)/.. TestBases_SOURCES = \ TestBases.cxx \ @@ -15,6 +25,6 @@ TestBases_LDFLAGS = $(CPPUNIT_LIBS) -pthread -ldl TestBases_CXXFLAGS = $(THREAD_DEF) $(CPPUNIT_INCLUDES) -I$(srcdir)/.. -TESTS = TestBases +TESTS = InitTests TestBases include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/bases/Test/TestBases.cxx b/src/bases/Test/TestBases.cxx index 1f2d9a726..4f006fd2e 100644 --- a/src/bases/Test/TestBases.cxx +++ b/src/bases/Test/TestBases.cxx @@ -1,4 +1,6 @@ +#define UNIT_TEST_HEADER " --- TEST src/bases" + #include "basesTest.hxx" using namespace YACS::BASES; diff --git a/src/bases/Test/UnitTestsResult.hxx b/src/bases/Test/UnitTestsResult.hxx new file mode 100644 index 000000000..871e1db6b --- /dev/null +++ b/src/bases/Test/UnitTestsResult.hxx @@ -0,0 +1,20 @@ +#ifndef _UNITTESTSRESULT_HXX_ +#define _UNITTESTSRESULT_HXX_ + +#include +#include + +namespace YACS +{ + static inline std::string getResultFile() + { + std::string s = "/tmp/"; + s += std::getenv("USER"); + s += "/UnitTestsResult"; + return s; + } + + std::string UnitTestsResult = getResultFile(); +} + +#endif diff --git a/src/bases/Test/basesTest.cxx b/src/bases/Test/basesTest.cxx index bc16727b0..89cc86c78 100644 --- a/src/bases/Test/basesTest.cxx +++ b/src/bases/Test/basesTest.cxx @@ -1,15 +1,20 @@ #include "basesTest.hxx" +#include #include using namespace YACS::BASES; using namespace YACS; using namespace std; + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" Mutex BasesTest::_m; Semaphore BasesTest::_s1; Semaphore BasesTest::_s2; +Condition BasesTest::_cond; ostringstream BasesTest::_glob; int BasesTest::_var=7; @@ -17,7 +22,12 @@ const int BasesTest::THREAD_NUM=5; const int BasesTest::LOOPS=4; +const int BasesTest::MAX_RESOURCE=7; + int BasesTest::_value=0; +int BasesTest::_waiting=0; +int BasesTest::_resources=BasesTest::MAX_RESOURCE; +int BasesTest::_ownedResources[THREAD_NUM]; void *BasesTest::th1_1(void *st) { @@ -47,7 +57,7 @@ void *BasesTest::th1_3(void *st) void *BasesTest::th2_1(void *) { int i, tmp; - int rc = 0; + int rc = 0; for (i=0; i0; i--) + { + DEBTRACE("thread " << id << " asks for " << i << " resources"); + get_resources(id, i); + DEBTRACE("thread " << id << " has got " << i << " resources"); + CPPUNIT_ASSERT(count_resources() == BasesTest::MAX_RESOURCE); + Thread::sleep(10000); + CPPUNIT_ASSERT(count_resources() == BasesTest::MAX_RESOURCE); + DEBTRACE("thread " << id << " frees " << i << " resources"); + free_resources(id, i); + } +} + +void BasesTest::get_resources(int id, int amount) +{ + _m.lock(); + while (_resources < amount) + { + _waiting++; + _cond.wait(_m); // _m is unlocked during the wait + } + _resources -= amount; + _ownedResources[id] = amount; + _m.unlock(); +} + +void BasesTest::free_resources(int id, int amount) +{ + _m.lock(); + _resources += amount; + _ownedResources[id] = 0; + if (_waiting > 0) + { + _waiting = 0; + _cond.notify_all(); + } + _m.unlock(); +} + +int BasesTest::count_resources() +{ + int resources = 0; + int totOwned = 0; + { + _m.lock(); + resources = _resources; + for (int i=0; ijoin(); @@ -97,3 +168,45 @@ void BasesTest::test2() delete [] ths; CPPUNIT_ASSERT( _value == THREAD_NUM*LOOPS ); } + +void BasesTest::test3() +{ + int i; + void *ret; + Thread **ths=new Thread *[THREAD_NUM]; + + int id[THREAD_NUM]; + for (i=0; ijoin(); + delete ths[i]; + DEBTRACE("thread " << id[i] << " is finished"); + CPPUNIT_ASSERT(count_resources() == BasesTest::MAX_RESOURCE); + } +} + +typedef double (*FctPt)(double); + +void BasesTest::testDL() +{ + DynLibLoader *loader=new DynLibLoader(".libs/libYACSDLTest"); + void *symb=loader->getHandleOnSymbolWithName("myYacsFct"); + FctPt f=(FctPt) symb; + double res=f(1.7); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 20.23, res, 1e-13); + res=f(2.3); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 37.03, res, 1e-13); + delete loader; +} diff --git a/src/bases/Test/basesTest.hxx b/src/bases/Test/basesTest.hxx index dc974d647..b20b32a76 100644 --- a/src/bases/Test/basesTest.hxx +++ b/src/bases/Test/basesTest.hxx @@ -6,14 +6,17 @@ #include "Mutex.hxx" #include "Thread.hxx" #include "Semaphore.hxx" +#include "DynLibLoader.hxx" namespace YACS { class BasesTest: public CppUnit::TestFixture { CPPUNIT_TEST_SUITE( BasesTest ); - CPPUNIT_TEST(test1 ); - CPPUNIT_TEST(test2 ); + CPPUNIT_TEST( test1 ); + CPPUNIT_TEST( test2 ); + CPPUNIT_TEST( test3 ); + CPPUNIT_TEST( testDL ); CPPUNIT_TEST_SUITE_END(); public: @@ -23,7 +26,9 @@ namespace YACS void test1(); void test2(); - + void test3(); + void testDL(); + protected: private: @@ -31,16 +36,26 @@ namespace YACS static void *th1_2(void *); static void *th1_3(void *); static void *th2_1(void *); + + static void *myFunc(void *); + static void get_resources(int id, int amount); + static void free_resources(int id, int amount); + static int count_resources(); static int _var; static std::ostringstream _glob; static YACS::BASES::Mutex _m; static YACS::BASES::Semaphore _s1; static YACS::BASES::Semaphore _s2; + static YACS::BASES::Condition _cond; static const int THREAD_NUM; static const int LOOPS; + static const int MAX_RESOURCE; static int _value; + static int _waiting; + static int _resources; + static int _ownedResources[]; }; diff --git a/src/bases/ThreadPT.cxx b/src/bases/ThreadPT.cxx index c32b30d42..a6e78bf0f 100644 --- a/src/bases/ThreadPT.cxx +++ b/src/bases/ThreadPT.cxx @@ -1,12 +1,15 @@ #include "ThreadPT.hxx" +#include "Exception.hxx" #include using namespace YACS::BASES; ThreadPT::ThreadPT(ThreadJob funcPtr, void *stack) { + int err; void **stackT=(void **) stack; - pthread_create(&_threadId,0,funcPtr,stackT); + err=pthread_create(&_threadId,0,funcPtr,stackT); + if(err!=0)throw Exception("Error in thread creation"); } bool ThreadPT::operator==(const ThreadPT& other) @@ -14,6 +17,17 @@ bool ThreadPT::operator==(const ThreadPT& other) return pthread_equal(_threadId, other._threadId) != 0; } +//! Detach thread to release resources on exit +void ThreadPT::detach() +{ + pthread_detach(pthread_self()); +} + +void ThreadPT::exit(void *what) +{ + pthread_exit(what); +} + void ThreadPT::join() { void *ret; diff --git a/src/bases/ThreadPT.hxx b/src/bases/ThreadPT.hxx index 05ddc9595..18c045ee5 100644 --- a/src/bases/ThreadPT.hxx +++ b/src/bases/ThreadPT.hxx @@ -15,6 +15,8 @@ namespace YACS ThreadPT(ThreadJob funcPtr, void *stack); bool operator==(const ThreadPT& other); void join(); + static void detach(); + static void exit(void *what); static void sleep(unsigned long usec); private: pthread_t _threadId; diff --git a/src/bases/YacsTrace.cxx b/src/bases/YacsTrace.cxx new file mode 100644 index 000000000..399e98de1 --- /dev/null +++ b/src/bases/YacsTrace.cxx @@ -0,0 +1,15 @@ +#include +#include +#include "YacsTrace.hxx" + +void AttachDebugger() +{ + if(getenv ("YACSDEBUGGER")) + { + std::stringstream exec; + exec << "$YACSDEBUGGER " << getpid() << "&"; + std::cerr << exec.str() << std::endl; + system(exec.str().c_str()); + while(1); + } +} diff --git a/src/bases/YacsTrace.hxx b/src/bases/YacsTrace.hxx new file mode 100644 index 000000000..3147de71a --- /dev/null +++ b/src/bases/YacsTrace.hxx @@ -0,0 +1,12 @@ +#ifndef __YACSTRACE_HXX__ +#define __YACSTRACE_HXX__ + +#ifdef _DEVDEBUG_ +#define DEBTRACE(msg) {std::cerr< + +#undef PACKAGE_BUGREPORT +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION + +#endif + diff --git a/src/engine/Any.cxx b/src/engine/Any.cxx new file mode 100644 index 000000000..e77a310fc --- /dev/null +++ b/src/engine/Any.cxx @@ -0,0 +1,764 @@ +#include "Any.hxx" +#include "Runtime.hxx" +#include "TypeCode.hxx" +#include "InvalidExtractionException.hxx" + +#include + +using namespace YACS::ENGINE; +using namespace std; + +StringOnHeap::StringOnHeap(const char *val):_dealloc(0),_str(strdup(val)) +{ +} + +StringOnHeap::StringOnHeap(const std::string& val):_dealloc(0),_str(strdup(val.c_str())) +{ +} + +/*! + * \Note : no copy is performed if a deallocator is given. + * \param val : String in C format that is NOT copied if + * deAlloc != 0 + * \param deAlloc : pointer on function to deallocate val after + * last use. + */ +StringOnHeap::StringOnHeap(char *val, Deallocator deAlloc):_dealloc(deAlloc) +{ + if(deAlloc) + _str=val; + else + _str=strdup(val); +} + +bool StringOnHeap::operator ==(const StringOnHeap& other) const +{ + return strcmp(_str, other._str)==0; +} + +StringOnHeap *StringOnHeap::deepCopy() const +{ + return new StringOnHeap(_str); +} + +StringOnHeap::~StringOnHeap() +{ + if(_dealloc) + _dealloc(_str); + else + free(_str); +} + +Any::Any(TypeCode* type):_type(type) +{ + _type->incrRef(); +} + +Any::Any(const Any& other):_type(other._type) +{ + _type->incrRef(); +} + +Any::~Any() +{ + _type->decrRef(); +} + +AtomAny::AtomAny(int val):Any(Runtime::_tc_int) +{ + _value._i=val; +} + +AtomAny::AtomAny(bool val):Any(Runtime::_tc_bool) +{ + _value._b=val; +} + +AtomAny::AtomAny(double val):Any(Runtime::_tc_double) +{ + _value._d=val; +} + +AtomAny::AtomAny(const char *val):Any(Runtime::_tc_string) +{ + _value._s=new StringOnHeap(val); +} + +AtomAny::AtomAny(const std::string& val):Any(Runtime::_tc_string) +{ + _value._s=new StringOnHeap(val); +} + +AtomAny::AtomAny(const AtomAny& other):Any(other) +{ + if(_type->isA(Runtime::_tc_string)) + { + StringOnHeap *cpy=(other._value._s)->deepCopy(); + memcpy(&_value._s,&cpy,_type->getSizeInByteOfAnyReprInSeq()); + } + else if(_type->isA(Runtime::_tc_double)) + memcpy(&_value._d,&other._value._d,_type->getSizeInByteOfAnyReprInSeq()); + else if(_type->isA(Runtime::_tc_int)) + memcpy(&_value._i,&other._value._i,_type->getSizeInByteOfAnyReprInSeq()); + else if(_type->isA(Runtime::_tc_bool)) + memcpy(&_value._b,&other._value._b,_type->getSizeInByteOfAnyReprInSeq()); +} + +AtomAny::AtomAny(char *val, Deallocator deAlloc):Any(Runtime::_tc_string) +{ + _value._s=new StringOnHeap(val,deAlloc); +} + +AtomAny::AtomAny(char *data, TypeCode* type):Any(type) +{ + if(type->isA(Runtime::_tc_string)) + { + void **tmp=(void **)data; + StringOnHeap *cpy=((StringOnHeap *)(*tmp))->deepCopy(); + memcpy(&_value._s,&cpy,type->getSizeInByteOfAnyReprInSeq()); + } + else if(type->isA(Runtime::_tc_double)) + memcpy(&_value._d,data,type->getSizeInByteOfAnyReprInSeq()); + else if(type->isA(Runtime::_tc_int)) + memcpy(&_value._i,data,type->getSizeInByteOfAnyReprInSeq()); + else if(type->isA(Runtime::_tc_bool)) + memcpy(&_value._b,data,type->getSizeInByteOfAnyReprInSeq()); +} + +Any *AtomAny::clone() const +{ + return new AtomAny(*this); +} + +AtomAny *AtomAny::New(char *val,Deallocator dealloc) +{ + return new AtomAny(val,dealloc); +} + +AnyPtr AtomAny::operator[](int i) const +{ + throw InvalidExtractionException(_type->kind(),Sequence); +} + +bool AtomAny::operator ==(const Any& other) const +{ + if(!_type->isA(other.getType())) + return false; + const AtomAny& otherC=(const AtomAny&) other;//cast granted due to previous lines + if(_type->isA(Runtime::_tc_double)) + return _value._d==otherC._value._d; + else if(_type->isA(Runtime::_tc_int)) + return _value._i==otherC._value._i; + else if(_type->isA(Runtime::_tc_bool)) + return _value._b==otherC._value._b; + else if(_type->isA(Runtime::_tc_string)) + return (*_value._s)==*(otherC._value._s); + else + return false; +} + +int AtomAny::getIntValue() const throw(Exception) +{ + if(_type->isA(Runtime::_tc_int)) + return _value._i; + else + throw Exception("Value is not an Int"); +} + +bool AtomAny::getBoolValue() const throw(Exception) +{ + if(_type->isA(Runtime::_tc_bool)) + return _value._b; + else + throw Exception("Value is not a Bool"); +} + +double AtomAny::getDoubleValue() const throw(Exception) +{ + if(_type->isA(Runtime::_tc_double)) + return _value._d; + else + throw Exception("Value is not a Double"); +} + +std::string AtomAny::getStringValue() const throw(Exception) +{ + if(_type->isA(Runtime::_tc_string)) + return string(_value._s->cStr()); + else + throw Exception("Value is not a String"); +} + +/*! + * \note : This method put in data its zipped recursive content in data. + * The ownership of the recursive content is tranfered to data. + * So this owns nothing and its counter fall by 1. + * For memory space minimal use, not all of '*this' is pushed at data location. + * \param data : already allocated memory zone where to put compressed content of 'this' + */ +void AtomAny::putMyReprAtPlace(char *data) const +{ + if(_type->isA(Runtime::_tc_string)) + { + StringOnHeap *tmp=_value._s->deepCopy(); + memcpy(data,&tmp,_type->getSizeInByteOfAnyReprInSeq()); + } + else if(_type->isA(Runtime::_tc_double)) + memcpy(data,&_value._d,_type->getSizeInByteOfAnyReprInSeq()); + else if(_type->isA(Runtime::_tc_int)) + memcpy(data,&_value._i,_type->getSizeInByteOfAnyReprInSeq()); + else if(_type->isA(Runtime::_tc_bool)) + memcpy(data,&_value._b,_type->getSizeInByteOfAnyReprInSeq()); +} + +/*! + * \note : This method put in data its zipped recursive content in data. + * The ownership of the recursive content is tranfered to data. + * So this owns nothing and its counter fall by 1. + * For memory space minimal use, not all of '*this' is pushed at data location. + * 'deepCpy' param is not used here because by definition of AtomAny deep copy is performed. + * \param data : already allocated memory zone where to put compressed content of 'this' + */ +void AtomAny::putReprAtPlace(char *data, const char *src, const TypeCode *type, bool deepCpy) +{ + if(type->isA(Runtime::_tc_string)) + { + void **tmp1=(void **)src; + StringOnHeap *tmp=((const StringOnHeap *)(*tmp1))->deepCopy(); + memcpy(data,&tmp,type->getSizeInByteOfAnyReprInSeq()); + } + else if(type->isA(Runtime::_tc_double)) + memcpy(data,src,type->getSizeInByteOfAnyReprInSeq()); + else if(type->isA(Runtime::_tc_int)) + memcpy(data,src,type->getSizeInByteOfAnyReprInSeq()); + else if(type->isA(Runtime::_tc_bool)) + memcpy(data,src,type->getSizeInByteOfAnyReprInSeq()); +} + +/*! + * \note : Opposite method of putMyReprAtPlace. But static because due to data compression + * instance is lost. + */ +void AtomAny::destroyReprAtPlace(char *data, const TypeCode *type) +{ + DynType typ=type->kind(); + if(typ==String) + { + void **tmp=(void **)data; + delete ((StringOnHeap *)(*tmp)); + } +} + +AnyPtr AtomAny::getOrBuildFromData(char *data, const TypeCode *type) +{ + Any *ret; + ret=new AtomAny(data,(TypeCode *)type); + return AnyPtr(ret); +} + +bool AtomAny::takeInChargeStorageOf(TypeCode *type) +{ + DynType typ=type->kind(); + return (typ==Double || typ==Int || typ==Bool || typ==String); +} + +AtomAny::~AtomAny() +{ + if(_type->isA(Runtime::_tc_string)) + delete _value._s; +} + +ComposedAny::ComposedAny(const ComposedAny& other):Any(other) +{ +} + +ComposedAny::ComposedAny(TypeCode* type):Any(type) +{ + _type->decrRef(); +} + +int ComposedAny::getIntValue() const throw(Exception) +{ + throw InvalidExtractionException(_type->kind(),Runtime::_tc_int->kind()); +} + +bool ComposedAny::getBoolValue() const throw(Exception) +{ + throw InvalidExtractionException(_type->kind(),Runtime::_tc_bool->kind()); +} + +double ComposedAny::getDoubleValue() const throw(Exception) +{ + throw InvalidExtractionException(_type->kind(),Runtime::_tc_double->kind()); +} + +std::string ComposedAny::getStringValue() const throw(Exception) +{ + throw InvalidExtractionException(_type->kind(),Runtime::_tc_string->kind()); +} + +SeqAlloc::SeqAlloc(const SeqAlloc& other):_sizeOf1Elm(other._sizeOf1Elm),_notStdDeAlloc(0), + _start(0),_finish(0),_endOfStorage(0) +{ + _start=allocate(other._finish-other._start); + _finish=_start+(other._finish-other._start); + _endOfStorage=_finish; +} + +SeqAlloc::SeqAlloc(unsigned int sizeOf1Elm):_sizeOf1Elm(sizeOf1Elm),_notStdDeAlloc(0), + _start(0),_finish(0),_endOfStorage(0) +{ +} + +SeqAlloc::~SeqAlloc() +{ + deallocate(_start); +} + +void SeqAlloc::clear() +{ + deallocate(_start); + _start=0; + _finish=0; + _endOfStorage=0; +} + +/*! + * \note : This method is exclusively reserved for arrays of C++ built-in types because no + * constructor is applied atomically. + */ +void SeqAlloc::initCoarseMemory(char *mem, unsigned int size, Deallocator dealloc) +{ + unsigned sizeInByte=size*_sizeOf1Elm; + if(dealloc) + { + _notStdDeAlloc=dealloc; + _start=mem; + } + else + { + _start=allocate(sizeInByte); + if(mem) + memcpy(_start,mem,sizeInByte); + else + { + for(unsigned int i=0;iputMyReprAtPlace(pt); +} + +/*! + * \note: This performs the placement new or zip info into pt. + * \param val : the source from which the construction will be performed. + * \param deepCpy : If true in pt place a deep copy pointed by val will be put. + */ +void SeqAlloc::construct(char *pt, const char *val, const TypeCode *tc, bool deepCpy) +{ + tc->putReprAtPlace(pt,val,deepCpy); +} + +char *SeqAlloc::allocate(unsigned int nbOfByte) +{ + if(nbOfByte>0) + return (char *)::operator new(nbOfByte); + else + return 0; +} + +// pt is not permitted to be a null pointer. +void SeqAlloc::deallocate(char *pt) +{ + if(pt) + { + if(!_notStdDeAlloc) + ::operator delete(pt); + else + { + _notStdDeAlloc(pt); + _notStdDeAlloc=0; + } + } +} + +void SeqAlloc::destroy(char *pt, const TypeCode *tc) +{ + tc->destroyZippedAny(pt); +} + +unsigned int SeqAlloc::size() const +{ + return (_finish-_start)/_sizeOf1Elm; +} + +void SequenceAny::clear() +{ + for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm) + _alloc.destroy(cur,_type->contentType()); + _alloc.clear(); +} + +void SequenceAny::popBack() +{ + _alloc._finish-=_alloc._sizeOf1Elm; + _alloc.destroy(_alloc._finish,_type->contentType()); +} + +void SequenceAny::pushBack(const Any* elem) +{ + if(!elem->_type->isA(_type->contentType())) + throw InvalidExtractionException(elem->_type->kind(),_type->contentType()->kind()); + if(_alloc._finish != _alloc._endOfStorage) + { + _alloc.construct(_alloc._finish, elem); + _alloc._finish+=_alloc._sizeOf1Elm; + } + else + realloc(_alloc._finish, elem); +} + +bool SequenceAny::operator ==(const Any& other) const +{ + if(!_type->isA(other.getType())) + return false; + const SequenceAny& otherC=(const SequenceAny&) other;//cast granted due to previous lines + if(size()!=otherC.size()) + return false; + for(unsigned i=0;icontentType()); + _alloc.construct(_alloc._start+i*_alloc._sizeOf1Elm,elem); +} + +AnyPtr SequenceAny::operator[](int i) const +{ + return _type->contentType()->getOrBuildAnyFromZippedData(_alloc._start+i*_alloc._sizeOf1Elm); +} + +/*! + * \note : Contrary to AtomAny 'this' (ref) is put in data NOT a deep copy. + * \param data : already allocated memory zone where to put address of 'this' + */ +void SequenceAny::putMyReprAtPlace(char *data) const +{ + const void *tmp=(const void *)this; + memcpy(data,&tmp,_type->getSizeInByteOfAnyReprInSeq()); + const void **tmp2=(const void **) data; + ((SequenceAny *)(*tmp2))->incrRef(); + //::new((SequenceAny *)data) SequenceAny((SequenceAny&) (*this)); +} + +void SequenceAny::putReprAtPlace(char *data, const char *src, const TypeCode *type, bool deepCpy) +{ + void **tmp2=(void **) src; + if(!deepCpy) + { + ((SequenceAny *)(*tmp2))->incrRef(); + memcpy(data,src,type->getSizeInByteOfAnyReprInSeq()); + } + else + { + SequenceAny *cpy=new SequenceAny(*((SequenceAny *)(*tmp2))); + memcpy(data,&cpy,type->getSizeInByteOfAnyReprInSeq()); + } + //::new((SequenceAny *)data) SequenceAny((SequenceAny&) (*this)); +} + +void SequenceAny::destroyReprAtPlace(char *data, const TypeCode *type) +{ + void **tmp=(void **) data; + if(*tmp) + ((SequenceAny *)(*tmp))->decrRef(); + //((SequenceAny *)data)->~SequenceAny(); +} + +AnyPtr SequenceAny::getOrBuildFromData(char *data, const TypeCode *type) +{ + void **tmp=(void **) data; + ((SequenceAny *) (*tmp))->incrRef(); + return AnyPtr((SequenceAny *)(*tmp)); +} + +Any *SequenceAny::clone() const +{ + return new SequenceAny(*this); +} + +SequenceAny *SequenceAny::New(const TypeCode *typeOfContent) +{ + if(typeOfContent->kind() == Objref) + { + //In case of Objref, use a sequence of string + return new SequenceAny(Runtime::_tc_string); + } + else + return new SequenceAny(typeOfContent); +} + +SequenceAny *SequenceAny::New(const TypeCode *typeOfContent, unsigned lgth) +{ + if(typeOfContent->kind() == Objref) + { + //In case of Objref, use a sequence of string + return new SequenceAny(Runtime::_tc_string,lgth); + } + else + return new SequenceAny(typeOfContent,lgth); +} + +bool SequenceAny::takeInChargeStorageOf(TypeCode *type) +{ + DynType typ=type->kind(); + return (typ==Sequence); +} + +SequenceAny::SequenceAny(const SequenceAny& other):ComposedAny(other),_alloc(other._alloc) +{ + const char *srcCur=other._alloc._start; + for(char *cur=_alloc._start;srcCur != other._alloc._finish; srcCur+=_alloc._sizeOf1Elm, cur+=_alloc._sizeOf1Elm) + _alloc.construct(cur, srcCur, _type->contentType(),true); +} + +SequenceAny::~SequenceAny() +{ + for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm) + _alloc.destroy(cur,_type->contentType()); +} + +/*! + * \param typeOfContent : typeCode of the type of elements stored in sequence. + */ +SequenceAny::SequenceAny(const TypeCode *typeOfContent):ComposedAny(new TypeCodeSeq("","",typeOfContent)), + _alloc(typeOfContent->getSizeInByteOfAnyReprInSeq()) +{ +} + +SequenceAny::SequenceAny(const TypeCode *typeOfContent, unsigned lgth):ComposedAny(new TypeCodeSeq("","",typeOfContent)), + _alloc(typeOfContent->getSizeInByteOfAnyReprInSeq()) +{ + _alloc.initCoarseMemory(0,lgth,0); +} + +SequenceAny::SequenceAny(int *val, unsigned int lgth, Deallocator deAlloc):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_int)), + _alloc(Runtime::_tc_int->getSizeInByteOfAnyReprInSeq()) +{ + _alloc.initCoarseMemory((char *)val,lgth,deAlloc); +} + +SequenceAny::SequenceAny(bool *val, unsigned int lgth, Deallocator deAlloc):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_bool)), + _alloc(Runtime::_tc_bool->getSizeInByteOfAnyReprInSeq()) +{ + _alloc.initCoarseMemory((char *)val,lgth,deAlloc); +} + +SequenceAny::SequenceAny(double *val, unsigned int lgth, Deallocator deAlloc):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_double)), + _alloc(Runtime::_tc_double->getSizeInByteOfAnyReprInSeq()) +{ + _alloc.initCoarseMemory((char *)val,lgth,deAlloc); +} + +SequenceAny::SequenceAny(const std::vector& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_int)), + _alloc(Runtime::_tc_int->getSizeInByteOfAnyReprInSeq()) +{ + _alloc.initCoarseMemory((char *)&val[0],val.size(),0); +} + +SequenceAny::SequenceAny(const std::vector& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_bool)), + _alloc(Runtime::_tc_bool->getSizeInByteOfAnyReprInSeq()) +{ + for(vector::const_iterator iter=val.begin();iter!=val.end();iter++) + { + AtomAnyPtr tmp=AtomAny::New(*iter); + pushBack(tmp); + } +} + +SequenceAny::SequenceAny(const std::vector& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_double)), + _alloc(Runtime::_tc_double->getSizeInByteOfAnyReprInSeq()) +{ + _alloc.initCoarseMemory((char *)&val[0],val.size(),0); +} + +SequenceAny::SequenceAny(const std::vector& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_string)), + _alloc(Runtime::_tc_string->getSizeInByteOfAnyReprInSeq()) +{ + for(vector::const_iterator iter=val.begin();iter!=val.end();iter++) + { + AtomAnyPtr tmp=AtomAny::New(*iter); + pushBack(tmp); + } +} + +void SequenceAny::realloc(char *endOfCurrentAllocated, const Any *elem) +{ + unsigned int oldSize=_alloc._finish-_alloc._start; + unsigned int newSize = oldSize != 0 ? 2 * oldSize : _alloc._sizeOf1Elm; + char *newStart=_alloc.allocate(newSize); + // + char *newFinish=performCpy(_alloc._start, endOfCurrentAllocated,newStart); + _alloc.construct(newFinish, elem); + newFinish+=_alloc._sizeOf1Elm; + newFinish=performCpy(endOfCurrentAllocated, _alloc._finish, newFinish); + // + for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm) + _alloc.destroy(cur,_type->contentType()); + _alloc.deallocate(_alloc._start); + _alloc._start = newStart; + _alloc._finish = newFinish; + _alloc._endOfStorage=newStart+newSize; +} + +char *SequenceAny::performCpy(char *srcStart, char *srcFinish, char *destStart) +{ + char *cur=destStart; + for (;srcStart != srcFinish; srcStart+=_alloc._sizeOf1Elm, cur+=_alloc._sizeOf1Elm) + _alloc.construct(cur, srcStart, _type->contentType(),false); + return cur; +} + +ArrayAny::~ArrayAny() +{ + delete [] _data; +} + +ArrayAny::ArrayAny(char *data, TypeCodeArray * type):ComposedAny(type),_data(0) +{ + _data=new char[_type->getSizeInByteOfAnyReprInSeq()]; + const TypeCode *subType=_type->contentType(); + unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq(); + for(unsigned i=0;igetStaticLgth();i++) + subType->putReprAtPlace(_data+i*sizePerContent,data+i*sizePerContent,true); +} + +ArrayAny::ArrayAny(const ArrayAny& other):ComposedAny(other) +{ + _data=new char[_type->getSizeInByteOfAnyReprInSeq()]; + const TypeCode *subType=_type->contentType(); + unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq(); + for(unsigned i=0;i<((TypeCodeArray *)_type)->getStaticLgth();i++) + subType->putReprAtPlace(_data+i*sizePerContent,other._data+i*sizePerContent,true); +} + +ArrayAny::ArrayAny(const int *val, unsigned int lgth):ComposedAny(new TypeCodeArray("","",Runtime::_tc_int,lgth)), + _data(0) +{ + _data=new char[_type->getSizeInByteOfAnyReprInSeq()]; + memcpy(_data,val,_type->getSizeInByteOfAnyReprInSeq()); +} + +ArrayAny::ArrayAny(const bool *val, unsigned int lgth):ComposedAny(new TypeCodeArray("","",Runtime::_tc_bool,lgth)), + _data(0) +{ + _data=new char[_type->getSizeInByteOfAnyReprInSeq()]; + memcpy(_data,val,_type->getSizeInByteOfAnyReprInSeq()); +} + +ArrayAny::ArrayAny(const double *val, unsigned int lgth):ComposedAny(new TypeCodeArray("","",Runtime::_tc_double,lgth)), + _data(0) +{ + _data=new char[_type->getSizeInByteOfAnyReprInSeq()]; + memcpy(_data,val,_type->getSizeInByteOfAnyReprInSeq()); +} + +ArrayAny::ArrayAny(const std::vector& val):ComposedAny(new TypeCodeArray("","",Runtime::_tc_int,val.size())), + _data(0) +{ + _data=new char[_type->getSizeInByteOfAnyReprInSeq()]; + memcpy(_data,&val[0],_type->getSizeInByteOfAnyReprInSeq()); +} + +ArrayAny::ArrayAny(const std::vector& val):ComposedAny(new TypeCodeArray("","",Runtime::_tc_double,val.size())), + _data(0) +{ + _data=new char[_type->getSizeInByteOfAnyReprInSeq()]; + memcpy(_data,&val[0],_type->getSizeInByteOfAnyReprInSeq()); +} + +ArrayAny::ArrayAny(const std::vector& val):ComposedAny(new TypeCodeArray("","",Runtime::_tc_string,val.size())), + _data(0) +{ + _data=new char[_type->getSizeInByteOfAnyReprInSeq()]; + unsigned i=0; + const TypeCode *subType=_type->contentType(); + unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq(); + for(vector::const_iterator iter=val.begin();iter!=val.end();iter++,i++) + { + StringOnHeap *st=new StringOnHeap(*iter); + memcpy(_data+i*sizePerContent,&st,sizePerContent); + } +} + +bool ArrayAny::operator ==(const Any& other) const +{ + if(!_type->isA(other.getType())) + return false; + const ArrayAny& otherC=(const ArrayAny&) other;//cast granted due to previous lines + for(unsigned i=0;i<((const TypeCodeArray *)_type)->getStaticLgth();i++) + if(!((*(*this)[i])==(*otherC[i]))) + return false; + return true; +} + +AnyPtr ArrayAny::operator[](int i) const +{ + const TypeCode *subType=_type->contentType(); + unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq(); + if(i<0 || i>=((TypeCodeArray *)_type)->getStaticLgth()) + throw Exception("Trying to access to an invalid index in an Any Tuple"); + return _type->getOrBuildAnyFromZippedData(_data+i*sizePerContent); +} + +Any *ArrayAny::clone() const +{ + return new ArrayAny(*this); +} + +void ArrayAny::putMyReprAtPlace(char *data) const +{ + const TypeCode *subType=_type->contentType(); + unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq(); + for(unsigned i=0;i<((const TypeCodeArray *)_type)->getStaticLgth();i++) + subType->putReprAtPlace(data+i*sizePerContent,_data+i*sizePerContent,false); +} + +void ArrayAny::putReprAtPlace(char *data, const char *src, const TypeCodeArray *type, bool deepCpy) +{ + const TypeCode *subType=type->contentType(); + unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq(); + for(unsigned i=0;igetStaticLgth();i++) + subType->putReprAtPlace(data+i*sizePerContent,src+i*sizePerContent,deepCpy); +} + +void ArrayAny::destroyReprAtPlace(char *data, const TypeCodeArray *type) +{ + const TypeCode *subType=type->contentType(); + unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq(); + for(unsigned i=0;igetStaticLgth();i++) + subType->destroyZippedAny(data+i*sizePerContent); +} + +AnyPtr ArrayAny::getOrBuildFromData(char *data, const TypeCodeArray *type) +{ + Any *ret; + type->incrRef(); + ret=new ArrayAny(data,(TypeCodeArray *)type); + return AnyPtr(ret); +} + +bool ArrayAny::takeInChargeStorageOf(TypeCode *type) +{ + DynType typ=type->kind(); + return (typ==Array); +} diff --git a/src/engine/Any.hxx b/src/engine/Any.hxx new file mode 100644 index 000000000..bff224ec0 --- /dev/null +++ b/src/engine/Any.hxx @@ -0,0 +1,254 @@ +#ifndef __YACSANY_HXX__ +#define __YACSANY_HXX__ + +#include "RefCounter.hxx" +#include "Exception.hxx" +#include "SharedPtr.hxx" + +#include + +namespace YACS +{ + namespace ENGINE + { + class Any; + class AtomAny; + class TypeCode; + class SeqAlloc; + class ArrayAny; + class SequenceAny; + class TypeCodeArray; + typedef void (*Deallocator)(void *); + + class StringOnHeap + { + friend class Any; + friend class AtomAny; + friend class ArrayAny; + private: + StringOnHeap(const char *val); + StringOnHeap(const std::string& val); + StringOnHeap(char *val, Deallocator deAlloc); + bool operator ==(const StringOnHeap& other) const; + StringOnHeap *deepCopy() const; + const char *cStr() const { return _str; } + ~StringOnHeap(); + private: + char *_str; + Deallocator _dealloc; + }; + + typedef SharedPtr AnyPtr; + + /*! + * \brief: Interface for management of storage of data formated dynamically in its TypeCode. + * Warning virtual inheritance on Any daughter classes NOT supported. + */ + class Any : public RefCounter + { + friend class SeqAlloc; + friend class SequenceAny; + public: + const TypeCode *getType() const { return _type; } + //for convenience methods + virtual Any *clone() const = 0; + virtual AnyPtr operator[](int i) const = 0; + virtual bool operator ==(const Any& other) const = 0; + virtual int getIntValue() const throw(Exception) = 0; + virtual bool getBoolValue() const throw(Exception) = 0; + virtual double getDoubleValue() const throw(Exception) = 0; + virtual std::string getStringValue() const throw(Exception) = 0; + // + protected: + virtual ~Any(); + Any(TypeCode* type); + Any(const Any& other); + virtual void putMyReprAtPlace(char *data) const = 0; + static AnyPtr buildAnyFromCoarseData(char *data, TypeCode* type); //Factory Method + protected: + TypeCode* _type; + }; + + typedef SharedPtr AtomAnyPtr; + + class AtomAny : public Any + { + friend class TypeCode; + + union ValueContainer + { + int _i; + bool _b; + double _d; + StringOnHeap *_s; + }; + public: + Any *clone() const; + template + static AtomAny *New(T val) { return new AtomAny(val); } + static AtomAny *New(char *val, Deallocator dealloc); + AnyPtr operator[](int i) const; + bool operator ==(const Any& other) const; + int getIntValue() const throw(Exception); + bool getBoolValue() const throw(Exception); + double getDoubleValue() const throw(Exception); + std::string getStringValue() const throw(Exception); + protected: + void putMyReprAtPlace(char *data) const; + static void putReprAtPlace(char *data, const char *src, const TypeCode *type, bool deepCpy); + static void destroyReprAtPlace(char *data, const TypeCode *type); + static AnyPtr getOrBuildFromData(char *data, const TypeCode *type); + static bool takeInChargeStorageOf(TypeCode *type); + private: + ~AtomAny(); + AtomAny(int val); + AtomAny(bool val); + AtomAny(double val); + AtomAny(const char *val); + AtomAny(const std::string& val); + AtomAny(const AtomAny& other); + AtomAny(char *data, TypeCode* type); + AtomAny(char *val, Deallocator deAlloc); + protected: + ValueContainer _value; + }; + + class SeqAlloc + { + friend class SequenceAny; + + char *_start; + char *_finish; + char *_endOfStorage; + Deallocator _notStdDeAlloc; + const unsigned int _sizeOf1Elm; + private: + SeqAlloc(const SeqAlloc& other); + SeqAlloc(unsigned int sizeOf1Elm); + ~SeqAlloc(); + void clear(); + void initCoarseMemory(char *mem, unsigned int size, Deallocator dealloc); + void construct(char *pt, const Any *val); + void construct(char *pt, const char *val, const TypeCode *tc, bool deepCpy); + char *allocate(unsigned int nbOfByte); + void destroy(char *pt, const TypeCode *tc); + void deallocate(char *pt); + unsigned int size() const; + }; + + class ComposedAny : public Any + { + protected: + ComposedAny(const ComposedAny& other); + ComposedAny(TypeCode* type); + private://error methods called during incorrect runtime extraction + int getIntValue() const throw(Exception); + bool getBoolValue() const throw(Exception); + double getDoubleValue() const throw(Exception); + std::string getStringValue() const throw(Exception); + }; + + typedef SharedPtr SequenceAnyPtr; + + class SequenceAny : public ComposedAny + { + friend class TypeCodeSeq; + public: + void clear(); + void popBack(); + unsigned int size() const { return _alloc.size(); } + void pushBack(const Any *elem); + bool operator ==(const Any& other) const; + void setEltAtRank(int i, const Any *elem); + AnyPtr operator[](int i) const; + Any *clone() const; + template + static SequenceAny *New(const std::vector& vec); + static SequenceAny *New(const TypeCode *typeOfContent); + static SequenceAny *New(const TypeCode *typeOfContent, unsigned lgth); + template + static SequenceAny *New(T *val, unsigned int lgth, Deallocator deAlloc); + protected: + void putMyReprAtPlace(char *data) const; + static void putReprAtPlace(char *data, const char *src, const TypeCode *type, bool deepCpy); + static void destroyReprAtPlace(char *data, const TypeCode *type); + static AnyPtr getOrBuildFromData(char *data, const TypeCode *type); + static bool takeInChargeStorageOf(TypeCode *type); + private: + ~SequenceAny(); + SequenceAny(const SequenceAny& other); + SequenceAny(const TypeCode *typeOfContent); + SequenceAny(const TypeCode *typeOfContent, unsigned lgth); + SequenceAny(int *val, unsigned int lgth, Deallocator deAlloc); + SequenceAny(bool *val, unsigned int lgth, Deallocator deAlloc); + SequenceAny(double *val, unsigned int lgth, Deallocator deAlloc); + SequenceAny(const std::vector& val); + SequenceAny(const std::vector& val); + SequenceAny(const std::vector& val); + SequenceAny(const std::vector& val); + void realloc(char *endOfCurrentAllocated, const Any *elem); + char *performCpy(char *srcStart, char *srcFinish, char *destStart); + protected: + SeqAlloc _alloc; + }; + + typedef SharedPtr ArrayAnyPtr; + + class ArrayAny : public ComposedAny + { + friend class TypeCodeArray; + public: + bool operator ==(const Any& other) const; + AnyPtr operator[](int i) const; + Any *clone() const; + template + static ArrayAny *New(const std::vector& vec); + template + static ArrayAny *New(const T *val, unsigned int lgth); + protected: + void putMyReprAtPlace(char *data) const; + static void putReprAtPlace(char *data, const char *src, const TypeCodeArray *type, bool deepCpy); + static void destroyReprAtPlace(char *data, const TypeCodeArray *type); + static AnyPtr getOrBuildFromData(char *data, const TypeCodeArray *type); + static bool takeInChargeStorageOf(TypeCode *type); + private: + ~ArrayAny(); + ArrayAny(char *data, TypeCodeArray * type); + ArrayAny(const ArrayAny& other); + ArrayAny(const int *val, unsigned int lgth); + ArrayAny(const bool *val, unsigned int lgth); + ArrayAny(const double *val, unsigned int lgth); + ArrayAny(const std::vector& val); + ArrayAny(const std::vector& val); + ArrayAny(const std::vector& val); + protected: + char *_data; + }; + + template + SequenceAny *SequenceAny::New(T *val, unsigned int lgth, Deallocator deAlloc) + { + return new SequenceAny(val,lgth,deAlloc); + } + + template + SequenceAny *SequenceAny::New(const std::vector& vec) + { + return new SequenceAny(vec); + } + + template + ArrayAny *ArrayAny::New(const std::vector& vec) + { + return new ArrayAny(vec); + } + + template + ArrayAny *ArrayAny::New(const T *val, unsigned int lgth) + { + return new ArrayAny(val,lgth); + } + } +} + +#endif diff --git a/src/engine/AnyInputPort.cxx b/src/engine/AnyInputPort.cxx new file mode 100644 index 000000000..3a0e898c4 --- /dev/null +++ b/src/engine/AnyInputPort.cxx @@ -0,0 +1,116 @@ +#include "AnyInputPort.hxx" +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +AnyInputPort::AnyInputPort(const std::string& name, Node *node, TypeCode* type):InputPort(name,node,type),DataPort(name,node,type),Port(node),_value(0) +{ +} + +AnyInputPort::AnyInputPort(const AnyInputPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder),_value(0) +{ + if(other._value) + _value=other._value->clone(); +} + +AnyInputPort::~AnyInputPort() +{ + if(_value) + { + DEBTRACE("_value ref count: " << _value->getRefCnt()); + _value->decrRef(); + } +} + +//! Save the current data value for further reinitialization of the port +/*! + * + */ +void AnyInputPort::exSaveInit() +{ + if(_initValue) _initValue->decrRef(); + _initValue=_value; + _initValue->incrRef(); +} + +//! Restore the saved data value to current data value +/*! + * If no data has been saved (_initValue == 0) don't restore + */ +void AnyInputPort::exRestoreInit() +{ + if(!_initValue) + return; + if(_value) + _value->decrRef(); + _value=_initValue; + _value->incrRef(); +} + +void AnyInputPort::put(Any *data) +{ + if(_value) + _value->decrRef(); + _value=data; + _value->incrRef(); + DEBTRACE("value ref count: " << _value->getRefCnt()); +} + +bool AnyInputPort::isEmpty() +{ + return !_value; +} + +void *AnyInputPort::get() const throw(Exception) +{ + if(!_value) + { + std::string what="AnyInputPort::get : no value currently in input whith name \""; what+=_name; what+="\""; + throw Exception(what); + } + return (void *)_value; +} + +void AnyInputPort::put(const void *data) throw(ConversionException) +{ + put((Any *)data); +} + +InputPort *AnyInputPort::clone(Node *newHelder) const +{ + return new AnyInputPort(*this,newHelder); +} + +std::string AnyInputPort::dump() +{ + if(!_value) + { + std::string what="AnyInputPort::get : no value currently in input whith name \""; what+=_name; what+="\""; + throw Exception(what); + } + stringstream xmldump; + switch (_value->getType()->kind()) + { + case Double: + xmldump << "" << _value->getDoubleValue() << "" << endl; + break; + case Int: + xmldump << "" << _value->getIntValue() << "" << endl; + break; + case Bool: + xmldump << "" << _value->getBoolValue() << "" << endl; + break; + case String: + xmldump << "" << _value->getStringValue() << "" << endl; + break; + default: + xmldump << " NO_SERIALISATION_AVAILABLE " << endl; + break; + } + return xmldump.str(); +} diff --git a/src/engine/AnyInputPort.hxx b/src/engine/AnyInputPort.hxx new file mode 100644 index 000000000..074172c5d --- /dev/null +++ b/src/engine/AnyInputPort.hxx @@ -0,0 +1,33 @@ +#ifndef __ANYINPUTPORT_HXX__ +#define __ANYINPUTPORT_HXX__ + +#include "InputPort.hxx" +#include + +namespace YACS +{ + namespace ENGINE + { + class AnyInputPort : public InputPort + { + public: + AnyInputPort(const std::string& name, Node *node, TypeCode* type); + AnyInputPort(const AnyInputPort& other, Node *newHelder); + virtual ~AnyInputPort(); + void exSaveInit(); + void exRestoreInit(); + Any *getValue() const { return _value; } + int getIntValue() const { return _value->getIntValue(); } + void put(Any *data); + void *get() const throw(Exception); + virtual bool isEmpty(); + void put(const void *data) throw(ConversionException); + InputPort *clone(Node *newHelder) const; + std::string dump(); + protected: + Any *_value; + }; + } +} + +#endif diff --git a/src/engine/Bloc.cxx b/src/engine/Bloc.cxx index b25477be8..129d88aa9 100644 --- a/src/engine/Bloc.cxx +++ b/src/engine/Bloc.cxx @@ -1,10 +1,36 @@ #include "Bloc.hxx" +#include "LinkInfo.hxx" +#include "InputPort.hxx" +#include "OutputPort.hxx" #include "ElementaryNode.hxx" +#include "Visitor.hxx" + +#include using namespace YACS::ENGINE; using namespace std; -Bloc::Bloc(const string& name):ComposedNode(name) +Bloc::Bloc(const Bloc& other, ComposedNode *father, bool editionOnly):StaticDefinedComposedNode(other,father),_fwLinks(0),_bwLinks(0) +{ + for(set::const_iterator iter=other._setOfNode.begin();iter!=other._setOfNode.end();iter++) + _setOfNode.insert((*iter)->simpleClone(this,editionOnly)); + //CF Linking + vector< pair > cfLinksToReproduce=other.getSetOfInternalCFLinks(); + vector< pair >::iterator iter1=cfLinksToReproduce.begin(); + for(;iter1!=cfLinksToReproduce.end();iter1++) + edAddCFLink(getChildByName(other.getChildName((*iter1).first->getNode())),getChildByName(other.getChildName((*iter1).second->getNode()))); + //Data + DataStream linking + vector< pair > linksToReproduce=other.getSetOfInternalLinks(); + vector< pair >::iterator iter2=linksToReproduce.begin(); + for(;iter2!=linksToReproduce.end();iter2++) + edAddLink(getOutPort(other.getPortName((*iter2).first)),getInPort(other.getPortName((*iter2).second))); +} + +//! Create a Bloc node with a given name +/*! + * \param name : the given name + */ +Bloc::Bloc(const std::string& name):StaticDefinedComposedNode(name),_fwLinks(0),_bwLinks(0) { } @@ -12,91 +38,108 @@ Bloc::~Bloc() { for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) delete *iter; + delete _fwLinks; + delete _bwLinks; } -void Bloc::init() +//! Initialize the bloc +/*! + * \param start : a boolean flag indicating the kind of initialization + * If start is true, it's a complete initialization with reinitialization of port values + * If start is false, there is no initialization of port values + */ +void Bloc::init(bool start) { - _inGate.exReset(); + Node::init(start); for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) - (*iter)->init(); - if(_inGate.exIsReady()) - _state=YACS::TOACTIVATE; - else - _state=YACS::INITED; + (*iter)->init(start); } +//! Indicate if the bloc execution is finished +/*! + * The execution bloc is finished if all its child nodes + * are finished with or without error or if it is disabled (not to execute) + */ bool Bloc::isFinished() { - return _state==YACS::DONE; + if(_state==YACS::DONE)return true; + if(_state==YACS::ERROR)return true; + if(_state==YACS::FAILED)return true; + if(_state==YACS::DISABLED)return true; + return false; } int Bloc::getNumberOfCFLinks() const { int ret=0; for(set::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) - { - ret+=(*iter)->getOutGate()->getNbOfInGatesConnected(); - } + ret+=(*iter)->getOutGate()->getNbOfInGatesConnected(); return ret; } -vector Bloc::getNextTasks(bool& isMore) +Node *Bloc::simpleClone(ComposedNode *father, bool editionOnly) const { - vector ret; - isMore=false; - if(_state==YACS::DONE || _state==YACS::INITED) - return ret; - for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) - (*iter)->getReadyTasks(ret); - isMore=!ret.empty(); - return ret; + return new Bloc(*this,father,editionOnly); } -void Bloc::getReadyTasks(vector& tasks) +//! Collect all nodes that are ready to execute +/*! + * \param tasks : vector of tasks to collect ready nodes + */ +void Bloc::getReadyTasks(std::vector& tasks) { + /* + * ComposedNode state goes to ACTIVATED when one of its child has been ACTIVATED + * To change this uncomment the following line + * Then the father node will go to ACTIVATED state before its child node + */ + if(_state==YACS::TOACTIVATE ) setState(YACS::ACTIVATED); if(_state==YACS::TOACTIVATE || _state==YACS::ACTIVATED) for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) (*iter)->getReadyTasks(tasks); } -set Bloc::getRecursiveConstituents() -{ - set ret; - for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) - { - set myCurrentSet=(*iter)->getRecursiveConstituents(); - ret.insert(myCurrentSet.begin(),myCurrentSet.end()); - } - return ret; -} - -/** +//! Update the bloc state +/*! * Update the '_state' attribute. - * Typically called by 'this->_inGate' when 'this->_inGate' is ready. Contrary to Node::exUpdateState no check done on inputs + * 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(_state == YACS::DISABLED)return; if(_inGate.exIsReady()) - _state=YACS::TOACTIVATE; + { + setState(YACS::TOACTIVATE); + for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) + if((*iter)->exIsControlReady()) + (*iter)->exUpdateState(); + } } -/** -* 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. -*/ - +//! Add a child node to the bloc +/*! + * \param node: the node to add to the bloc + * \return a boolean flag indicating if the node has been added + * + * 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)) { if(node->_father==this) - return false; + return false; else - throw Exception("Bloc::edAddChild : Internal error occured"); + { + string what = "Bloc::edAddChild : node "; what += node->getName(); + what += " is already grand children of node"; + throw Exception(what); + } } if(node->_father) @@ -107,76 +150,80 @@ bool Bloc::edAddChild(Node *node) throw(Exception) if(isNameAlreadyUsed(node->getName())) { - 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; _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; } /** * 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'. + * @exception If 'node' is NOT the son of 'this'. */ void Bloc::edRemoveChild(Node *node) throw(Exception) { - if(node->_father!=this) - throw Exception("Bloc::edRemoveChild : node is NOT managed by this"); - if(!isNodeAlreadyAggregated(node)) - throw Exception("Bloc::edRemoveChild : Internal error occured"); - ComposedNode *myRootNode=getRootNode(); - myRootNode->disconnectAllLinksConnectedTo(node); + StaticDefinedComposedNode::edRemoveChild(node); _setOfNode.erase(node); - delete node; } -void Bloc::selectRunnableTasks(vector& tasks) +std::set Bloc::edGetDirectDescendants() const { + return _setOfNode; } -bool Bloc::areAllSubNodesFinished() const +Node *Bloc::getChildByShortName(const std::string& name) const throw(Exception) { - bool ret=true; - for(set::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end() && ret;iter++) - if((*iter)->_state!=YACS::DONE) - ret=false; - return ret; + for (set::const_iterator iter = _setOfNode.begin(); iter != _setOfNode.end(); iter++) + if ((*iter)->getName() == name) + return (*iter); + string what("node "); what+= name ; what+=" is not a child of Bloc "; what += getName(); + throw Exception(what); } -bool Bloc::isNodeAlreadyAggregated(Node *node) const +void Bloc::selectRunnableTasks(std::vector& tasks) +{ +} + +bool Bloc::areAllSubNodesDone() const { for(set::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) { - if((*iter)==node) - return true; + if((*iter)->_state == YACS::DONE)continue; + if((*iter)->_state == YACS::DISABLED)continue; + return false; } - return false; + return true; } -bool Bloc::isNameAlreadyUsed(const string& name) const +bool Bloc::areAllSubNodesFinished() const +{ + for(set::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) + { + if((*iter)->_state == YACS::DONE)continue; + if((*iter)->_state == YACS::FAILED)continue; + if((*iter)->_state == YACS::DISABLED)continue; + if((*iter)->_state == YACS::ERROR)continue; + if((*iter)->_state == YACS::INTERNALERR)continue; + return false; + } + return true; +} + +bool Bloc::isNameAlreadyUsed(const std::string& name) const { for(set::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) - if((*iter)->getName()==name) - return true; + if((*iter)->getName()==name) + return true; return false; } -bool insertNodeChildrenInSet(Node *node, set nodeSet) +bool insertNodeChildrenInSet(Node *node, std::set& nodeSet) { bool verdict=true; set outNodes=node->getOutNodes(); @@ -184,59 +231,435 @@ bool insertNodeChildrenInSet(Node *node, set nodeSet) { 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. - * WARNING : When using this method 'node' has to be checked in order to be part of direct children of 'this'. +/*! + * \note Checks that in the forest from 'node' there are NO back-edges. + * \b 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) { set currentNodesToTest; - currentNodesToTest.insert(node); - if (!insertNodeChildrenInSet(node,currentNodesToTest)) + //don't insert node to test in set. + //If it is present after insertion of connected nodes we have a loop + //collect all connected nodes + insertNodeChildrenInSet(node,currentNodesToTest); + //try to insert node + if(!(currentNodesToTest.insert(node)).second) throw Exception("Cycle has been detected"); } -void Bloc::initChildrenForDFS() const +std::vector< std::pair > Bloc::getSetOfInternalCFLinks() const { + vector< pair > ret; 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 - * 'when event == START'. - * WARNING Precondition : '_state == Running' and 'node->_father==this'(garanteed by ComposedNode::notifyFrom) - * - */ -YACS::Event Bloc::updateStateOnStartEventFrom(Node *node) -{ - _state=YACS::ACTIVATED; - return YACS::START; + { + set outCFLinksOfCurNode=(*iter)->_outGate.edSetInGate(); + for(set::iterator iter2=outCFLinksOfCurNode.begin();iter2!=outCFLinksOfCurNode.end();iter2++) + ret.push_back(pair(&(*iter)->_outGate,*iter2)); + } + return ret; } -/** +/*! * - * @note : Runtime called method. Indirectly called by ComposedNode::updateStateFrom which has dispatch to this method + * @note : Runtime called method. Indirectly called by StaticDefinedComposedNode::updateStateFrom which has dispatch to this method * 'when event == FINISH'. - * WARNING Precondition : '_state == Running' and 'node->_father==this'(garanteed by ComposedNode::notifyFrom) + * WARNING Precondition : '_state == Running' and 'node->_father==this'(garanteed by StaticDefinedComposedNode::notifyFrom) * + * Calls the node's outgate OutGate::exNotifyDone if all nodes are not finished */ YACS::Event Bloc::updateStateOnFinishedEventFrom(Node *node) { //ASSERT(node->_father==this) if(areAllSubNodesFinished()) { - _state=YACS::DONE; + setState(YACS::DONE); + if(!areAllSubNodesDone()) + { + setState(YACS::FAILED); + return YACS::ABORT; + } return YACS::FINISH;//notify to father node that 'this' has becomed finished. } - //more job to do in 'this' - node->_outGate.exNotifyDone(); + //more job to do in 'this' bloc + //Conversion exceptions can be thrown so catch them to control errors + try + { + //notify the finished node to propagate to its following nodes + node->exForwardFinished(); + } + catch(YACS::Exception& ex) + { + //The node has failed to propagate. It must be put in error + std::cerr << "Bloc::updateStateOnFinishedEventFrom: " << ex.what() << std::endl; + // notify the node it has failed + node->exForwardFailed(); + setState(YACS::FAILED); + return YACS::ABORT; + } return YACS::NOEVENT;//no notification to father needed because from father point of view nothing happened. } + +//! Notify this bloc that a node has failed +/*! + * \param node : node that has emitted the event + * \return the event to notify to bloc's father + */ +YACS::Event Bloc::updateStateOnFailedEventFrom(Node *node) +{ + node->exForwardFailed(); + if(areAllSubNodesFinished()) + { + setState(YACS::DONE); + if(!areAllSubNodesDone()){ + setState(YACS::FAILED); + return YACS::ABORT; + } + return YACS::FINISH;//notify to father node that 'this' has becomed finished. + } + return YACS::NOEVENT; +} + +void Bloc::writeDot(std::ostream &os) +{ + os << " subgraph cluster_" << getId() << " {\n" ; + setnodes=getChildren(); + for(set::const_iterator iter=nodes.begin();iter!=nodes.end();iter++) + { + (*iter)->writeDot(os); + string p=(*iter)->getId(); + //not connected node + if((*iter)->_inGate._backLinks.size() == 0) os << getId() << " -> " << p << ";\n"; + setoutnodes = (*iter)->getOutNodes(); + for(set::const_iterator itout=outnodes.begin();itout!=outnodes.end();itout++) + { + os << p << " -> " << (*itout)->getId() << ";\n"; + } + } + os << "}\n" ; + os << getId() << "[fillcolor=\"" ; + YACS::StatesForNode state=getEffectiveState(); + os << getColorState(state); + os << "\" label=\"" << "Bloc:" ; + os << getQualifiedName() <<"\"];\n"; +} + +void Bloc::accept(Visitor* visitor) +{ + visitor->visitBloc(this); +} + +/*! + * Updates mutable structures _fwLinks and _bwLinks with the result of computation. + * CPU consumer. + */ +void Bloc::performCFComputations(LinkInfo& info) const +{ + StaticDefinedComposedNode::performCFComputations(info); + delete _fwLinks;//Normally useless + delete _bwLinks;//Normally useless + _fwLinks=new map >; + _bwLinks=new map >; + map > accelStr; + for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) + findAllNodesStartingFrom(*iter,(*_fwLinks)[*iter],accelStr,info); + accelStr.clear(); + for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) + findAllNodesStartingFrom(*iter,(*_bwLinks)[*iter],accelStr,info); +} + +void Bloc::destructCFComputations(LinkInfo& info) const +{ + StaticDefinedComposedNode::destructCFComputations(info); + delete _fwLinks; _fwLinks=0; + delete _bwLinks; _bwLinks=0; +} + +/*! + * \b WARNING \b Needs call of performCFComputations before beeing called. + * Perform updates of containers regarding attributes of link 'start' -> 'end' and check the correct linking. + * The output is in info struct. + * + * \param fw out parameter beeing append if start -> end link is a forward link \b without cross type DF/DS. + * \param fwCross out parameter beeing append if start -> end link is a forward link \b with cross type DF/DS. + * \param bw out parameter beeing append if start -> end link is a backward link. + * \param info out parameter beeing informed about eventual errors. + */ +void Bloc::checkControlDependancy(OutPort *start, InPort *end, bool cross, + std::map < ComposedNode *, std::list < OutPort * > >& fw, + std::vector& fwCross, + std::map< ComposedNode *, std::list < OutPort *> >& bw, + LinkInfo& info) const +{ + if(!cross) + { + Node *startN=isInMyDescendance(start->getNode()); + Node *endN=isInMyDescendance(end->getNode()); + if(startN==endN) + bw[(ComposedNode *)this].push_back(start); + else if(areLinked(startN,endN,true)) + fw[(ComposedNode *)this].push_back(start); + else + if(areLinked(startN,endN,false)) + bw[(ComposedNode *)this].push_back(start); + else + info.pushErrLink(start,end,E_UNPREDICTABLE_FED); + } + else//DFDS detected + if(arePossiblyRunnableAtSameTime(isInMyDescendance(start->getNode()),isInMyDescendance(end->getNode()))) + fwCross.push_back(start); + else + info.pushErrLink(start,end,E_DS_LINK_UNESTABLISHABLE); +} + +/*! + * 'start' and 'end' \b must be direct son of 'this'. + * Typically used for data link. + * \param fw indicates if it is a forward link searched (true : default value) or a backward link serach. + */ +bool Bloc::areLinked(Node *start, Node *end, bool fw) const +{ + set& nexts=fw ? (*_fwLinks)[start] : (*_bwLinks)[start]; + return nexts.find(end)!=nexts.end(); +} + +/*! + * Typically used for stream link. + * 'start' and 'end' \b must be direct son of 'this'. + */ +bool Bloc::arePossiblyRunnableAtSameTime(Node *start, Node *end) const +{ + set& nexts=(*_fwLinks)[start]; + set& preds=(*_bwLinks)[start]; + return nexts.find(end)==nexts.end() && preds.find(end)==preds.end(); +} + +/*! + * \param starts If different of 0, must aggregate at leat \b 1 element. + * \param alreadyFed in/out parameter. Indicates if 'end' ports is already and surely set or fed by an another port. + * \param direction If true : forward direction else backward direction. + */ +void Bloc::checkCFLinks(const std::list< OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const +{ + if(alreadyFed==FREE_ST || alreadyFed==FED_ST) + { + map > classPerNodes; + for(list< OutPort *>::const_iterator iter1=starts.begin();iter1!=starts.end();iter1++) + classPerNodes[isInMyDescendance((*iter1)->getNode())].push_back(*iter1); + set allNodes; + for(map >::iterator iter2=classPerNodes.begin();iter2!=classPerNodes.end();iter2++) + allNodes.insert((*iter2).first); + vector okAndUseless1,useless2; + seekOkAndUseless1(okAndUseless1,allNodes); + seekUseless2(useless2,allNodes);//after this point allNodes contains collapses + verdictForOkAndUseless1(classPerNodes,end,okAndUseless1,alreadyFed,direction,info); + verdictForCollapses(classPerNodes,end,allNodes,alreadyFed,direction,info); + verdictForOkAndUseless1(classPerNodes,end,useless2,alreadyFed,direction,info); + } + else if(alreadyFed==FED_DS_ST) + for(list< OutPort *>::const_iterator iter1=starts.begin();iter1!=starts.end();iter1++) + info.pushErrLink(*iter1,end,E_COLLAPSE_DFDS); +} + +void Bloc::initComputation() const +{ + for(set::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) + { + (*iter)->_colour=White; + (*iter)->getInGate()->exReset(); + (*iter)->getOutGate()->exReset(); + } +} + +/*! + * Part of final step for CF graph anylizing. This is the part of non collapse nodes. + * \param alreadyFed in/out parameter. Indicates if 'end' ports is already and surely set or fed by an another port. + */ +void Bloc::verdictForOkAndUseless1(const std::map >& pool, InputPort *end, const std::vector& candidates, unsigned char& alreadyFed, + bool direction, LinkInfo& info) +{ + for(vector::const_iterator iter=candidates.begin();iter!=candidates.end();iter++) + { + const list& mySet=(*pool.find(*iter)).second; + if(mySet.size()==1) + { + if(alreadyFed==FREE_ST) + { + alreadyFed=FED_ST;//This the final choice. General case ! + if(!direction) + info.pushInfoLink(*(mySet.begin()),end,I_BACK); + } + else if(alreadyFed==FED_ST) + info.pushInfoLink(*(mySet.begin()),end,direction ? I_USELESS : I_BACK_USELESS);//Second or more turn in case of alreadyFed==FREE_ST before call of this method + } + else + { + if(dynamic_cast(*iter)) + { + WarnReason reason; + if(alreadyFed==FREE_ST) + reason=direction ? W_COLLAPSE_EL : W_BACK_COLLAPSE_EL; + else if(alreadyFed==FED_ST) + reason=direction ? W_COLLAPSE_EL_AND_USELESS : W_BACK_COLLAPSE_EL_AND_USELESS; + for(list::const_iterator iter2=mySet.begin();iter2!=mySet.end();iter2++) + info.pushWarnLink(*iter2,end,reason); + } + else + ((ComposedNode *)(*iter))->checkCFLinks(mySet,end,alreadyFed,direction,info);//Thanks to recursive model! + } + } +} + +/*! + * Part of final step for CF graph anylizing. This is the part of collapses nodes. + * \param alreadyFed in/out parameter. Indicates if 'end' ports is already and surely set or fed by an another port. + */ +void Bloc::verdictForCollapses(const std::map >& pool, InputPort *end, const std::set& candidates, unsigned char& alreadyFed, + bool direction, LinkInfo& info) +{ + info.startCollapseTransac(); + for(set::const_iterator iter=candidates.begin();iter!=candidates.end();iter++) + { + const list& mySet=(*pool.find(*iter)).second; + if(mySet.size()==1) + { + if(alreadyFed==FREE_ST) + info.pushWarnLink(*(mySet.begin()),end,direction ? W_COLLAPSE : W_BACK_COLLAPSE); + else if(alreadyFed==FED_ST) + info.pushWarnLink(*(mySet.begin()),end,direction ? W_COLLAPSE_AND_USELESS : W_BACK_COLLAPSE_EL_AND_USELESS); + } + else + { + if(dynamic_cast(*iter)) + { + WarnReason reason; + if(alreadyFed==FREE_ST) + reason=direction ? W_COLLAPSE_EL : W_BACK_COLLAPSE_EL; + else if(alreadyFed==FED_ST) + reason=direction ? W_COLLAPSE_EL_AND_USELESS : W_BACK_COLLAPSE_EL_AND_USELESS; + for(list::const_iterator iter2=mySet.begin();iter2!=mySet.end();iter2++) + info.pushWarnLink(*iter2,end,reason); + } + else + { + ((ComposedNode *)(*iter))->checkCFLinks(mySet,end,alreadyFed,direction,info);//Thanks to recursive model! + WarnReason reason; + if(alreadyFed==FREE_ST) + reason=direction ? W_COLLAPSE : W_BACK_COLLAPSE; + else if(alreadyFed==FED_ST) + reason=direction ? W_COLLAPSE_AND_USELESS : W_BACK_COLLAPSE_AND_USELESS; + for(list::const_iterator iter2=mySet.begin();iter2!=mySet.end();iter2++) + info.pushWarnLink(*iter2,end,reason); + } + } + } + if(!candidates.empty()) + if(alreadyFed==FREE_ST) + alreadyFed=FED_ST; + info.endCollapseTransac(); +} + +/*! + * \b WARNING use this method only after having called Bloc::performCFComputations method. + * \param okAndUseless1 out param contains at the end, the nodes without any collapse. + * \param allNodes in/out param. At the end, all the nodes in 'okAndUseless1' are deleted from 'allNodes'. + */ +void Bloc::seekOkAndUseless1(std::vector& okAndUseless1, std::set& allNodes) const +{ + set::iterator iter=allNodes.begin(); + while(iter!=allNodes.end()) + { + set& whereToFind=(*_bwLinks)[*iter]; + std::set::iterator iter2; + for(iter2=allNodes.begin();iter2!=allNodes.end();iter2++) + if((*iter)!=(*iter2)) + if(whereToFind.find(*iter2)==whereToFind.end()) + break; + if(iter2!=allNodes.end()) + iter++; + else + { + okAndUseless1.push_back((*iter)); + allNodes.erase(iter); + iter=allNodes.begin(); + } + } +} + +/*! + * \b WARNING use this method only after having called Bloc::performCFComputations method. + * For params see Bloc::seekOkAndUseless1. + */ +void Bloc::seekUseless2(std::vector& useless2, std::set& allNodes) const +{ + set::iterator iter=allNodes.begin(); + while(iter!=allNodes.end()) + { + set& whereToFind=(*_fwLinks)[*iter]; + std::set::iterator iter2; + for(iter2=allNodes.begin();iter2!=allNodes.end();iter2++) + if((*iter)!=(*iter2)) + if(whereToFind.find(*iter2)==whereToFind.end()) + break; + if(iter2!=allNodes.end()) + { + iter++; + } + else + { + useless2.push_back((*iter)); + allNodes.erase(iter); + iter=allNodes.begin(); + } + } +} + +/*! + * Internal method : Given a succeful path : updates 'fastFinder' + */ +void Bloc::updateWithNewFind(const std::vector& path, map >& fastFinder) +{ + if(path.size()>=3) + { + vector::const_iterator iter=path.begin(); iter++; + vector::const_iterator iter2=path.end(); iter2-=1; + for(;iter!=iter2;iter++) + fastFinder[*iter].insert(*(iter+1)); + } +} + +/*! + * Internal method : After all paths have been found, useless CF links are searched + */ +void Bloc::findUselessLinksIn(const std::list< std::vector >& res , LinkInfo& info) +{ + unsigned maxSize=0; + list< vector >::const_iterator whereToPeerAt; + for(list< vector >::const_iterator iter=res.begin();iter!=res.end();iter++) + if((*iter).size()>maxSize) + { + maxSize=(*iter).size(); + whereToPeerAt=iter; + } + // + if(maxSize>1) + { + vector::const_iterator iter2=(*whereToPeerAt).begin(); + map::iterator iter4; + set searcher(iter2+1,(*whereToPeerAt).end());//to boost research + for(;iter2!=((*whereToPeerAt).end()-2);iter2++) + { + map::iterator iter4; + map& nexts=(*iter2)->getOutGate()->edMapInGate(); + for(iter4=nexts.begin();iter4!=nexts.end();iter4++) + if((*iter4).first->getNode()!=*(iter2+1)) + if(searcher.find((*iter4).first->getNode())!=searcher.end()) + info.pushUselessCFLink(*iter2,(*iter4).first->getNode()); + searcher.erase(*iter2); + } + } +} diff --git a/src/engine/Bloc.hxx b/src/engine/Bloc.hxx index 2edf8bdeb..cdf5daee6 100644 --- a/src/engine/Bloc.hxx +++ b/src/engine/Bloc.hxx @@ -1,41 +1,239 @@ #ifndef __BLOC_HXX__ #define __BLOC_HXX__ -#include "ComposedNode.hxx" +#include "StaticDefinedComposedNode.hxx" namespace YACS { namespace ENGINE { - class Bloc : public ComposedNode +/*! \brief Class for bloc node + * + * \ingroup Nodes + * + * + * \see ComposedNode + */ + class Bloc : public StaticDefinedComposedNode { protected: std::set _setOfNode;//OWNERSHIP OF ALL NODES + //! For internal calculations + mutable std::map > *_fwLinks; + //! For internal calculations + mutable std::map > *_bwLinks; + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; public: + Bloc(const Bloc& other, ComposedNode *father, bool editionOnly); Bloc(const std::string& name); - ~Bloc(); - void init(); + virtual ~Bloc(); bool isFinished(); int getNumberOfCFLinks() const; - std::vector getNextTasks(bool& isMore); + void init(bool start=true); void getReadyTasks(std::vector& tasks); - std::set getRecursiveConstituents(); void exUpdateState(); bool edAddChild(Node *node) throw(Exception); void edRemoveChild(Node *node) throw(Exception); std::set getChildren() { return _setOfNode; } + std::set edGetDirectDescendants() const; + Node *getChildByShortName(const std::string& name) const throw(Exception); void selectRunnableTasks(std::vector& tasks); + virtual void writeDot(std::ostream &os); + void accept(Visitor *visitor); + template + void findAllPathsStartingFrom(Node *start, std::list< std::vector >& vec, std::map >& accelStr) const; + template + void findAllNodesStartingFrom(Node *start, std::set& result, std::map >& accelStr, LinkInfo& info) const; protected: bool areAllSubNodesFinished() const; - bool isNodeAlreadyAggregated(Node *node) const; + bool areAllSubNodesDone() const; bool isNameAlreadyUsed(const std::string& name) const; void checkNoCyclePassingThrough(Node *node) throw(Exception); - YACS::Event updateStateOnStartEventFrom(Node *node); + std::vector< std::pair > getSetOfInternalCFLinks() const; YACS::Event updateStateOnFinishedEventFrom(Node *node); + YACS::Event updateStateOnFailedEventFrom(Node *node); + void initComputation() const; + void performCFComputations(LinkInfo& info) const; + void destructCFComputations(LinkInfo& info) const; + void checkControlDependancy(OutPort *start, InPort *end, bool cross, + std::map < ComposedNode *, std::list < OutPort * > >& fw, + std::vector& fwCross, + std::map< ComposedNode *, std::list < OutPort *> >& bw, + LinkInfo& info) const; + bool areLinked(Node *start, Node *end, bool fw) const; + bool arePossiblyRunnableAtSameTime(Node *start, Node *end) const; + void checkCFLinks(const std::list< OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const; + static void verdictForOkAndUseless1(const std::map >& pool, InputPort *end, const std::vector& candidates, + unsigned char& alreadyFed, bool direction, LinkInfo& info); + static void verdictForCollapses(const std::map >& pool, InputPort *end, const std::set& candidates, + unsigned char& alreadyFed, bool direction, LinkInfo& info); + void seekOkAndUseless1(std::vector& okAndUseless1, std::set& allNodes) const; + void seekUseless2(std::vector& useless2, std::set& allNodes) const; private: - void initChildrenForDFS() const; + static void findUselessLinksIn(const std::list< std::vector >& res , LinkInfo& info); + template + static unsigned appendIfAlreadyFound(std::list< std::vector >& res, const std::vector& startRes, Node *node, std::map >& fastFinder); + static void updateWithNewFind(const std::vector& path, std::map >& fastFinder); + }; + + template + struct CFDirectionVisTraits + { + }; + + template<> + struct CFDirectionVisTraits + { + typedef std::map::iterator Iterator; + typedef std::map& Nexts; + static Nexts getNexts(Node *node) { return node->getOutGate()->edMapInGate(); } + }; + + + template<> + struct CFDirectionVisTraits + { + typedef std::map::iterator Iterator; + typedef std::map& Nexts; + static Nexts getNexts(Node *node) { return node->getInGate()->edMapOutGate(); } }; + + /*! + * Internal method for CF computation. Given 'fastFinder' it searched 'node' to see if an already found path in 'res' go through 'node'. + * If true all paths are deduced and append to res and 'fastFinder' is updated for next turn. + */ + template + unsigned Bloc::appendIfAlreadyFound(std::list< std::vector >& res, const std::vector& startRes, Node *node, std::map >& fastFinder) + { + std::map >::const_iterator iter=fastFinder.find(node); + if(iter==fastFinder.end()) + return 0; + unsigned ret=0; + std::vector::iterator, std::set::iterator > > li; + li.push_back(std::pair::iterator, std::set::iterator>(((*iter).second).begin(),((*iter).second).end())); + std::vector work(startRes); + std::list< std::vector >::iterator where=res.end(); where--; + std::list< std::vector >::iterator updates=where; + while(!li.empty()) + { + if(li.back().first!=li.back().second) + { + work.push_back(*(li.back().first)); + if(CFDirectionVisTraits::getNexts(work.back()).empty()) + { + where=res.insert(where,work); + ret++; + li.back().first++; + work.pop_back(); + } + else + { + const std::set& s=fastFinder[*(li.back().first)]; + li.push_back(std::pair::iterator, std::set::iterator>(s.begin(),s.end())); + } + } + else + { + work.pop_back(); + li.pop_back(); + if(!li.empty()) + li.back().first++; + } + } + updates--; + for(unsigned i=0;i + void Bloc::findAllNodesStartingFrom(Node *start, std::set& result, std::map >& accelStr, LinkInfo& info) const + { + std::list< std::vector > li; + findAllPathsStartingFrom(start,li,accelStr); + for(std::list< std::vector >::const_iterator iter=li.begin();iter!=li.end();iter++) + for(std::vector::const_iterator iter2=(*iter).begin()+1;iter2!=(*iter).end();iter2++) + result.insert(*iter2); + if(direction) + findUselessLinksIn(li,info); + } + + /*! + * Method for CF computation.DFS visitor is used. + * \param start \b must be a direct descendant of 'this'. + * \param direction if true forward visiting is perform, false backward is used. + */ + template + void Bloc::findAllPathsStartingFrom(Node *start, std::list< std::vector >& vec, std::map >& accelStr) const + { + initComputation(); + Node *current=start; + int caseId=0; + int idInCase=0; + vec.push_back(std::vector()); + typename CFDirectionVisTraits::Iterator iter; + std::list< std::vector >::iterator curLine=vec.begin(); + while(start->_colour!=YACS::Black) + { + (*curLine).push_back(current); + idInCase++; + // + if(CFDirectionVisTraits::getNexts(current).empty()) + { + + vec.push_back(std::vector((*curLine))); + updateWithNewFind(*curLine,accelStr); + current->_colour=YACS::Black; + curLine++; + if(idInCase>1) + { + idInCase-=2; + current=(*curLine)[idInCase]; + (*curLine).pop_back(); + (*curLine).pop_back(); + } + continue; + } + if(current->_colour==YACS::Black) + { + appendIfAlreadyFound(vec,(*curLine),current,accelStr); + curLine=vec.end(); curLine--; + current->_colour=YACS::Black; + if(idInCase>1) + { + idInCase-=2; + current=(*curLine)[idInCase]; + (*curLine).pop_back(); + (*curLine).pop_back(); + } + continue; + } + for(iter=CFDirectionVisTraits::getNexts(current).begin();iter!=CFDirectionVisTraits::getNexts(current).end();iter++) + if(!(*iter).second) + break; + if(iter==CFDirectionVisTraits::getNexts(current).end()) + {//Fail this branch should be forgotten go rev + current->_colour=YACS::Black; + (*curLine).pop_back(); + if(idInCase>1) + { + idInCase-=2; + current=(*curLine)[idInCase]; + (*curLine).pop_back(); + } + } + else + { + //Nothing to signal continuing in this direction hoping to find + current=(*iter).first->getNode(); + (*iter).second=true; + } + } + vec.pop_back(); + } } } + #endif diff --git a/src/engine/ComponentInstance.cxx b/src/engine/ComponentInstance.cxx new file mode 100644 index 000000000..374c0cb37 --- /dev/null +++ b/src/engine/ComponentInstance.cxx @@ -0,0 +1,76 @@ +#include "ComponentInstance.hxx" +#include "Container.hxx" + +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +const char ComponentInstance::KIND[]=""; + +const char ComponentInstance::NULL_FILE_REPR[]="No repr specified for ComponentInstance"; + +void ComponentInstance::setContainer(Container *cont) +{ + if (cont == _container) return; + + if(cont) + cont->checkCapabilityToDealWith(this); + if(_container) + _container->decrRef(); + _container=cont; + if(_container) + _container->incrRef(); +} + +ComponentInstance::ComponentInstance(const std::string& name):_name(name),_isAttachedOnCloning(false),_container(0) +{ +} + +ComponentInstance::ComponentInstance(const ComponentInstance& other):_name(other._name), + _container(0), + _isAttachedOnCloning(other._isAttachedOnCloning) +{ + if(other._container) + _container=other._container->clone(); +} + +ComponentInstance::~ComponentInstance() +{ + if(_container) + _container->decrRef(); +} + +/*! + * By calling this method the current container 'this' is not destined to be deeply copied on clone call. + */ +void ComponentInstance::attachOnCloning() const +{ + _isAttachedOnCloning=true; +} + +std::string ComponentInstance::getFileRepr() const +{ + return NULL_FILE_REPR; +} + +/*! + * By calling this method the current container 'this' will be deeply copied on clone call. + */ +void ComponentInstance::dettachOnCloning() const +{ + _isAttachedOnCloning=false; +} + +bool ComponentInstance::isAttachedOnCloning() const +{ + return _isAttachedOnCloning; +} + +string ComponentInstance::getKind() const +{ + return KIND; +} diff --git a/src/engine/ComponentInstance.hxx b/src/engine/ComponentInstance.hxx new file mode 100644 index 000000000..4ffc12273 --- /dev/null +++ b/src/engine/ComponentInstance.hxx @@ -0,0 +1,72 @@ +#ifndef __COMPONENTINSTANCE_HXX__ +#define __COMPONENTINSTANCE_HXX__ + +#include "RefCounter.hxx" + +#include +#include + +namespace YACS +{ + namespace ENGINE + { + class Container; + class ServiceNode; + +/*! \brief Base class for all component instances. + * + * \ingroup Nodes + * + * This is an abstract class that must be specialized in runtime. + * Specialized classes must provide implementation for loading of + * a component (load method) unloading (unload method) and an + * information method (isLoaded) about the state of the component + * + * A component instance is used by one or more ServiceNode to execute + * services of this component instance + * + * \see ServiceNode + */ + class ComponentInstance : public RefCounter + { + protected: + virtual ~ComponentInstance(); + public: + ComponentInstance(const std::string& name); + ComponentInstance(const ComponentInstance& other); + const std::string& getName() const { return _name; } + void setContainer(Container *cont); + Container *getContainer() const { return _container; } +//! Load the component instance + virtual void load() = 0; +//! Unload the component instance + virtual void unload() = 0; +//! Indicate if the component instance is loaded (true) or not + virtual bool isLoaded() = 0; + virtual void attachOnCloning() const; + virtual void dettachOnCloning() const; + bool isAttachedOnCloning() const; +//! For dump in file + virtual std::string getFileRepr() const; + virtual ServiceNode* createNode(const std::string& name)=0; + virtual ComponentInstance *clone() const = 0; +//! Return the component kind +/*! + * A runtime can provide several implementations of a component instance. + * Each implementation has a different kind. A ComponentInstance can be + * associated to a ServiceNode is they have the same kind. + */ + virtual std::string getKind() const; + static const char KIND[]; + protected: + //! \b WARNING : _name has a strong semantic. It discriminates ComponentInstance instances each other. + std::string _name; + Container *_container; + mutable bool _isAttachedOnCloning; + protected: + static const char NULL_FILE_REPR[]; + }; + } +} + +#endif diff --git a/src/engine/ComposedNode.cxx b/src/engine/ComposedNode.cxx index c19bdc05d..37ef52c88 100644 --- a/src/engine/ComposedNode.cxx +++ b/src/engine/ComposedNode.cxx @@ -1,35 +1,188 @@ #include "ComposedNode.hxx" +#include "LinkInfo.hxx" +#include "Container.hxx" #include "InputPort.hxx" #include "OutputPort.hxx" +#include "ServiceNode.hxx" +#include "DataFlowPort.hxx" +#include "DataStreamPort.hxx" #include "ElementaryNode.hxx" +#include "ComponentInstance.hxx" +#include #include #include +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + using namespace YACS::ENGINE; using namespace std; -ComposedNode::ComposedNode(const string& name):Node(name) +const char ComposedNode::SEP_CHAR_BTW_LEVEL[]="."; + +ComposedNode::ComposedNode(const std::string& name):Node(name) +{ +} + +ComposedNode::ComposedNode(const ComposedNode& other, ComposedNode *father):Node(other,father) +{ +} + +ComposedNode::~ComposedNode() +{ +} + +void ComposedNode::performDuplicationOfPlacement(const Node& other) +{ + const ComposedNode &otherC=*(dynamic_cast(&other)); + DeploymentTree treeToDup=otherC.getDeploymentTree(); + set< ElementaryNode * > clones=otherC.getRecursiveConstituents(); + vector conts=treeToDup.getAllContainers(); + for(vector::iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++) + { + vector comps=treeToDup.getComponentsLinkedToContainer(*iterCt); + Container *contCloned=0; + if((*iterCt)) + contCloned=(*iterCt)->clone(); + for(vector::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++) + { + vector tasks=treeToDup.getTasksLinkedToComponent(*iterCp); + ComponentInstance *curCloned=(*iterCp)->clone(); + curCloned->setContainer(contCloned); + for(vector::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++) + { + //No risk for static cast : appendTask called by ComposedNode. + set< ElementaryNode * >::iterator res=clones.find((ElementaryNode *)(*iterT)); + //No risk here to because called only on cloning process... + ServiceNode *nodeC=(ServiceNode *)getChildByName(otherC.getChildName(*res)); + nodeC->setComponent(curCloned); + } + curCloned->decrRef(); + } + if(contCloned) + contCloned->decrRef(); + } +} + +bool ComposedNode::isFinished() +{ + if(_state==YACS::DONE)return true; + if(_state==YACS::ERROR)return true; + if(_state==YACS::FAILED)return true; + if(_state==YACS::DISABLED)return true; + return false; +} + +void ComposedNode::init(bool start) +{ + Node::init(start); +} + +std::string ComposedNode::getName() const +{ + return Node::getName(); +} + +std::string ComposedNode::getTaskName(Task *task) const +{ + return getChildName(dynamic_cast(task)); +} + +bool ComposedNode::operator>(const ComposedNode& other) const +{ + const ComposedNode *iter=_father; + while(iter!=0 && iter!=&other) + iter=iter->_father; + return iter==0; +} + +bool ComposedNode::operator<(const ComposedNode& other) const +{ + const ComposedNode *iter=other._father; + while(iter!=0 && iter!=this) + iter=iter->_father; + return iter==0; +} + +//! Essentially for test. Use checkDeploymentTree instead to be sure that returned DeploymentTree is consistent. +DeploymentTree ComposedNode::getDeploymentTree() const +{ + DeploymentTree ret; + set< ElementaryNode * > tasks=getRecursiveConstituents(); + for(set< ElementaryNode * >::iterator iter=tasks.begin();iter!=tasks.end();iter++) + ret.appendTask(*iter,(*iter)->getDynClonerIfExists(this)); + return ret; +} + +//! Perform check of deployment consistency of the current graph. +/*! + * \param deep if \b true a deep check is perfomed. Typically has to be called by an executor before any attempt to launch an execution. + */ +DeploymentTree ComposedNode::checkDeploymentTree(bool deep) const throw(Exception) +{ + DeploymentTree ret; + set< ElementaryNode * > tasks=getRecursiveConstituents(); + for(set< ElementaryNode * >::iterator iter=tasks.begin();iter!=tasks.end();iter++) + { + switch(ret.appendTask(*iter,(*iter)->getDynClonerIfExists(this))) + { + case DeploymentTree::DUP_TASK_NOT_COMPATIBLE_WITH_EXISTING_TREE: + { + string what("ComposedNode::checkDeploymentTree : ServiceNode with name \""); what+=(*iter)->getName(); + what+="\" coexists in a component with an another Task which context is incorrect with it."; + throw Exception(what); + } + case DeploymentTree::DEPLOYABLE_BUT_NOT_SPECIFIED : + { + if(deep) + { + string what("ComposedNode::checkDeploymentTree : ServiceNode with name \""); what+=(*iter)->getName(); + what+="\" is deployable but no component is specified on it."; + throw Exception(what); + } + } + } + } + return ret; +} + +std::vector ComposedNode::getNextTasks(bool& isMore) { + vector ret; + isMore=false; + getReadyTasks(ret); + isMore=!ret.empty(); + return ret; } -/** - * 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'. +//! Notify the node a task has emitted an event +/*! + * TO COMMENT MORE + * \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 levels may exist between 'sender' and 'this'. * + * \param sender : task emitting event + * \param event : event emitted + * + * Called by Executor::functionForTaskExecution on YACS::FINISH event + * + * Called by Executor::launchTask on YACS::START event + * + * Calls ComposedNode::updateStateFrom to update state from task to root node */ void ComposedNode::notifyFrom(const Task *sender, //* I : task emitting event - YACS::Event event //* I : event emitted - ) + YACS::Event event //* I : event emitted + ) { ElementaryNode *taskTyped=dynamic_cast((Task *)sender); - //ASSERT(taskTyped != 0) YACS::Event curEvent=event; Node *lminus1LevelNode=taskTyped; ComposedNode *curLevelNode=taskTyped->_father; + if(!curLevelNode)//Specific case of loop when 0 turn is specified without any enclosing bloc. + return ; curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent); while(curEvent!=YACS::NOEVENT && curLevelNode!=this) { @@ -39,61 +192,120 @@ void ComposedNode::notifyFrom(const Task *sender, //* I : task emitting event } } -/** - * Add a dataflow link. +//! Add a dataflow link between two data ports. +/*! * 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. + * \exception Exception : if 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) +bool ComposedNode::edAddLink(OutPort *start, InPort *end) throw(Exception) { + set represented; + + start->getAllRepresented(represented); + if(represented.size()!=1) + { + bool ret=false; + for(set::iterator iter=represented.begin();iter!=represented.end();iter++) + ret|=edAddLink(*iter,end); + return ret; + } + if(start->isAlreadyLinkedWith(end)) + return false; ComposedNode* lwstCmnAnctr=getLowestCommonAncestor(start->getNode(),end->getNode()); set allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr); set allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr); checkInMyDescendance(lwstCmnAnctr); - ComposedNode *iterS=start->getNode()->_father; - - OutPort *currentPortO=start; + lwstCmnAnctr->checkLinkPossibility(start,allAscendanceOfNodeStart,end,allAscendanceOfNodeEnd); + ComposedNode *iterS; + if(dynamic_cast(start->getNode())) + iterS=(ComposedNode *)start->getNode(); + else + iterS=start->getNode()->_father; + pair pO(start,start); while(iterS!=lwstCmnAnctr) { - currentPortO=iterS->buildDelegateOf(currentPortO, allAscendanceOfNodeStart); + iterS->buildDelegateOf(pO, end, allAscendanceOfNodeEnd); iterS=iterS->_father; } - iterS=end->getNode()->_father; + if(dynamic_cast(end->getNode())) + iterS=(ComposedNode *)end->getNode(); + else + iterS=end->getNode()->_father; InPort *currentPortI=end; while(iterS!=lwstCmnAnctr) { - currentPortI=iterS->buildDelegateOf(currentPortI, allAscendanceOfNodeEnd); + iterS->buildDelegateOf(currentPortI, start, allAscendanceOfNodeStart); iterS=iterS->_father; } + bool ret=(pO.first)->addInPort(currentPortI); + end->edNotifyReferencedBy(pO.second); + return ret; +} - bool linkDone = currentPortO->addInPort(currentPortI); - if (linkDone) +//! Connect an OutPort to an InPort and add the necessary control link +/*! + * Connect the ports with a data link (edAddLink) and add + * a control flow link between the children of the lowest common ancestor node. + * + * \param start : the OutPort to connect + * \param end : the InPort to connect + * \return true if a new link has been created, false otherwise. + */ +bool ComposedNode::edAddDFLink(OutPort *start, InPort *end) throw(Exception) +{ + Node* n1=start->getNode(); + Node* n2=end->getNode(); + DEBTRACE( n1->getName() << ":" << n2->getName()) + ComposedNode* father=getLowestCommonAncestor(n1,n2); + DEBTRACE( "ComposedNode::edAddDFLink: this="<getName() + << " father=" << father->getName() ) + DEBTRACE( "ComposedNode::edAddDFLink: OutPort=" << start->getName() + << " InPort=" << end->getName() ) + if (father != this) { - ComposedNode *iter=end->getNode()->_father; - while(iter) - { - iter->unpublishInputPort(end); - iter=iter->_father; - } + bool ret = father->edAddDFLink(start,end); // special treatement for loop + return ret; } - - return linkDone; + if(n2 == father) + throw Exception("Back link authorized only in special context (loop for example)"); + if(n1 != father) + { + //add a control link only if nodes are not in the same descendance + //if n1 == father (n2 is after n1) : the control link is not needed + //if n2 == father (n1 is after n2) : it's a back link authorized only in loop context + while(n1->getFather() != father) + n1=n1->getFather(); + while(n2->getFather() != father) + n2=n2->getFather(); + edAddCFLink(n1,n2); + } + return edAddLink(start,end); } -/** - * @note : Add a controlflow link. - * Precondition : 'start' AND 'end' are in/outGate contained in a node in DIRECT descendance of 'this'. - * @exception : If a cycle has been detected, or incompatibility between input and output, or 'start'/'end' is/are NOT in/outputPort - * contained in a node in descendance of 'this', or a mutilple link to an input not supporting it. - * @return : true if a new link has been created, false otherwise. +//! Add a controlflow link between two control ports. +/*! + * \note Precondition : 'start' AND 'end' are in/outGate contained in a node + * in DIRECT descendance of 'this'. + * \exception Exception : If a cycle has been detected, or incompatibility + * between input and output, or 'start'/'end' is/are NOT in/outputPort contained + * in a node in descendance of 'this', or a mutilple link to an input not + * supporting it. + * \return true if a new link has been created, false otherwise. */ bool ComposedNode::edAddLink(OutGate *start, InGate *end) throw(Exception) { + Node* n1=start->getNode(); + Node* n2=end->getNode(); + if(n1==n2) + throw Exception("ComposedNode::edAddLink: can not add a control link to a node with itself"); ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode()); + if(father==0) + throw Exception("ComposedNode::edAddLink: Trying to add CF link on orphan nodes."); if(father!=this) { checkInMyDescendance(father); @@ -105,29 +317,34 @@ bool ComposedNode::edAddLink(OutGate *start, InGate *end) throw(Exception) return ret; } +//! Add a controlflow link between two nodes. +/*! + * Add a controlflow link between two nodes by calling edAddLink on their control ports + */ bool ComposedNode::edAddCFLink(Node *nodeS, Node *nodeE) throw(Exception) { - ComposedNode* father=checkHavingCommonFather(nodeS,nodeE); - if(father!=this) - { - checkInMyDescendance(father); - return father->edAddLink(nodeS->getOutGate(),nodeE->getInGate()); - } - bool ret=nodeS->getOutGate()->edAddInGate(nodeE->getInGate()); - if(ret) - checkNoCyclePassingThrough(nodeE); - return ret; + return edAddLink(nodeS->getOutGate(),nodeE->getInGate()); } -/** - * Remove a dataflow link. +//! Remove a controlflow link. +void ComposedNode::edRemoveCFLink(Node *nodeS, Node *nodeE) throw(Exception) +{ + edRemoveLink(nodeS->getOutGate(),nodeE->getInGate()); +} + +//! 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. + * + * \exception Exception : If 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) +void ComposedNode::edRemoveLink(OutPort *start, InPort *end) throw(Exception) { + if(!start->isAlreadyLinkedWith(end)) + throw Exception("ComposedNode::edRemoveLink : unexisting link"); ComposedNode* lwstCmnAnctr=getLowestCommonAncestor(start->getNode(),end->getNode()); checkInMyDescendance(lwstCmnAnctr); set allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr); @@ -136,76 +353,337 @@ void ComposedNode::edRemoveLink(OutputPort *start, InputPort *end) throw(Excepti // --- 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; + pair currentPortO(start,start); + vector > > needsToDestroyO; while(iterS!=lwstCmnAnctr) { - currentPortO=iterS->getDelegateOf(currentPortO, allAscendanceOfNodeEnd); + OutPort *tmp=currentPortO.first; + iterS->getDelegateOf(currentPortO, end, allAscendanceOfNodeEnd); + needsToDestroyO.push_back(pair< ComposedNode * , pair < OutPort* , OutPort *> >(iterS,pair (tmp,currentPortO.first))); iterS=iterS->_father; } iterS=end->getNode()->_father; - InPort *currentPortI=end; + InPort * currentPortI=end; while(iterS!=lwstCmnAnctr) { - currentPortI=iterS->getDelegateOf(currentPortI, allAscendanceOfNodeStart); + iterS->getDelegateOf(currentPortI, start, allAscendanceOfNodeStart); iterS=iterS->_father; } // --- End of test for evt intermediate ports created - - currentPortO->removeInPort(currentPortI); + + (currentPortO.first)->removeInPort(currentPortI,false); + set repr; + (currentPortO.second)->getAllRepresented(repr); + if(repr.size()==1) + end->edNotifyDereferencedBy(currentPortO.second); // --- Performing deletion of intermediate ports - + iterS=start->getNode()->_father; - currentPortO=start; currentPortI=end; + vector > >::reverse_iterator iter; + for(iter=needsToDestroyO.rbegin();iter!=needsToDestroyO.rend();iter++) + (*iter).first->releaseDelegateOf(((*iter).second).first, ((*iter).second).second, end,allAscendanceOfNodeEnd); + iterS=end->getNode()->_father; + currentPortI=end; while(iterS!=lwstCmnAnctr) { - currentPortO=iterS->releaseDelegateOf(currentPortO, allAscendanceOfNodeEnd); + iterS->releaseDelegateOf(currentPortI, start, allAscendanceOfNodeStart); iterS=iterS->_father; } +} - iterS=end->getNode()->_father; - while(iterS!=lwstCmnAnctr) +//! Remove a controlflow link. +void ComposedNode::edRemoveLink(OutGate *start, InGate *end) throw(Exception) +{ + ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode()); + if(father!=this) + throw Exception("edRemoveLink : nodes not in direct descendance of this"); + start->edRemoveInGate(end); +} + +//! Remove a child node. +void ComposedNode::edRemoveChild(Node *node) throw(Exception) +{ + if(!node) + return; + if (node->_father!=this) { - currentPortI=iterS->releaseDelegateOf(currentPortI, allAscendanceOfNodeStart); - iterS=iterS->_father; + string what("node "); what+= node->getName() ; what+=" is not a child of node "; what += getName(); + throw Exception(what); } + node->edDisconnectAllLinksWithMe(); + node->_father = 0; +} - // --- publish inputPort in ancestors +//! Splits name globalName in 2 parts using separator. +/*! + * \note 'priority' specifies if during search process of 'separator' the max part is + * for 'firstPart' (priority=true) or 'lastPart' (priority=false). + * + * \throw Exception : 'lastPart' or 'firstPart' is empty. + * \return true if split process succeeds false otherwise (typically when character + * separator was not found). + */ +bool ComposedNode::splitNamesBySep(const std::string& globalName, const char separator[], + std::string& firstPart, std::string& lastPart, bool priority) throw(Exception) +{ + const string delims(separator); + string portName, nodeName; + string::size_type idx; + if(priority) + idx = globalName.find_last_of(delims); + else + idx = globalName.find_first_of(delims); + if (idx == string::npos) + { + firstPart=globalName; + lastPart=""; + return false; + } + firstPart = globalName.substr(0,idx); + lastPart = globalName.substr(idx+1); + if ((firstPart.empty()) or (lastPart.empty())) + { + string what("the name "); what+= globalName ; what+=" is not a valid port name"; + throw Exception(what); + } + return true; +} - ComposedNode *iter=end->getNode()->_father; - while(iter) +std::vector< std::pair > ComposedNode::getSetOfInternalLinks() const +{ + vector< pair > ret; + list temp=getSetOfOutPort(); + for(list::const_iterator iter2=temp.begin();iter2!=temp.end();iter2++) { - iter->publishInputPort(end); - iter=iter->_father; + set temp2=(*iter2)->edSetInPort(); + for(set::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++) + if(isInMyDescendance((*iter3)->getNode())) + ret.push_back(pair((*iter2),(*iter3))); } + return ret; } -void ComposedNode::edRemoveLink(OutGate *start, InGate *end) throw(Exception) +std::vector< std::pair > ComposedNode::getSetOfLinksLeavingCurrentScope() const { - ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode()); - if(father!=this) - throw Exception("edRemoveLink : nodes not in direct descendance of this"); - start->edRemoveInGate(end); + vector< pair > ret; + std::set ports=getAllOutPortsLeavingCurrentScope(); + for(set::iterator iter2=ports.begin();iter2!=ports.end();iter2++) + { + set temp2=(*iter2)->edSetInPort(); + for(set::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++) + if(!isInMyDescendance((*iter3)->getNode())) + ret.push_back(pair(*iter2,*iter3)); + } + return ret; } -void ComposedNode::publishOutputPort(OutputPort *port) throw(Exception) +void ComposedNode::checkConsistency(LinkInfo& info) const throw(Exception) { - checkInMyDescendance(port->getNode()); - _setOfOutputPort.insert(port); + info.clearAll(); + info.setPointOfView((ComposedNode *)this); + performCFComputations(info); + list setOfInToTest=getSetOfInputPort(); + for(list::iterator iter1=setOfInToTest.begin();iter1!=setOfInToTest.end();iter1++) + { + map > candidateForAdvCheck;//key is physical OutPort, value semantic OutPort behind. + set outPorts=(*iter1)->edSetOutPort(); + //Filtering among outPorts, which of them, are candidates to fill *iter1 at the current scope. + for(set::iterator iter2=outPorts.begin();iter2!=outPorts.end();iter2++) + { + set repr; + (*iter2)->getAllRepresented(repr); + for(set::iterator iter3=repr.begin();iter3!=repr.end();iter3++) + { + ComposedNode *manager=getLowestCommonAncestor((*iter3)->getNode(),(*iter1)->getNode()); + if(isInMyDescendance(manager)) + candidateForAdvCheck[*iter2].push_back(*iter3); + } + } + if(!candidateForAdvCheck.empty()) + //End of filtering. Now regarding CF constraints for the current InPutPort. + checkLinksCoherenceRegardingControl(candidateForAdvCheck,*iter1,info); + else + //No backlinks + if(!(*iter1)->edIsManuallyInitialized()) + info.pushErrLink(0,*iter1,E_NEVER_SET_INPUTPORT); + } + destructCFComputations(info); +} + +//! perform \b recursively all CF computations. +void ComposedNode::performCFComputations(LinkInfo& info) const +{ + set nodes=edGetDirectDescendants(); + for(set::iterator iter=nodes.begin();iter!=nodes.end();iter++) + if(dynamic_cast(*iter)) + ((ComposedNode *)(*iter))->performCFComputations(info); +} + +//! destroy \b recursively all results of initial computations. +void ComposedNode::destructCFComputations(LinkInfo& info) const +{ + set nodes=edGetDirectDescendants(); + for(set::iterator iter=nodes.begin();iter!=nodes.end();iter++) + if(dynamic_cast(*iter)) + ((ComposedNode *)(*iter))->destructCFComputations(info); +} + +/*! + * call it only for 'starts' to 'end' links \b DEALED by 'this'. + */ +void ComposedNode::checkLinksCoherenceRegardingControl(const std::map >& starts, InputPort *end, LinkInfo& info) const throw(Exception) +{ + map < ComposedNode *, list > outputs;//forward link classical + vector outputsCross;//forward link cross + map < ComposedNode *, list > outputsBw;//backward + map >::const_iterator iter1; + vector::const_iterator iter2; + for(iter1=starts.begin();iter1!=starts.end();iter1++) + { + DataPort *cross; + if((*iter1).second[0]==(*iter1).first)//Little optimisation. Representant (key) is equal to first value -> crossing impossible. + { + ComposedNode *manager=getLowestCommonAncestor(((*iter1).first)->getNode(),end->getNode()); + manager->checkControlDependancy((*iter1).first, end, false, outputs, outputsCross, outputsBw, info); + } + else + for(iter2=(*iter1).second.begin();iter2!=(*iter1).second.end();iter2++) + { + ComposedNode *manager=getLowestCommonAncestor(((*iter1).first)->getNode(),end->getNode()); + vector history=((*iter1).second)[0]->calculateHistoryOfLinkWith(end); + cross=DataPort::isCrossingType(history); + manager->checkControlDependancy(*iter2, end, cross!=0, outputs, outputsCross, outputsBw, info); + } + } + //Ok now let's regarding outputs all combinations : (outputs.size())*(outputs.size()-1)/2 + unsigned char isAlreadyFed=FREE_ST; + //Dealing excusively with DS. Level is useless here because simultaneity is required for DS. + if(outputsCross.size()>0) + { + isAlreadyFed=FED_DS_ST; + if(outputsCross.size()>1) + for(vector< OutPort *>::const_iterator iter1=outputsCross.begin();iter1!=(outputsCross.end()-2);iter1++) + info.pushErrLink(*iter1,end,E_COLLAPSE_DS); + } + map < ComposedNode *, list >::iterator iter3=outputs.begin(); + for(;iter3!=outputs.end();iter3++) + ((*iter3).first)->checkCFLinks((*iter3).second,end,isAlreadyFed,true,info); + if(isAlreadyFed==FREE_ST) + if(!end->edIsManuallyInitialized()) + info.pushErrLink(0,end,E_ONLY_BACKWARD_DEFINED); + isAlreadyFed=FREE_ST; + // + map < ComposedNode *, list >::reverse_iterator iter5=outputsBw.rbegin(); + for(;iter5!=outputsBw.rend();iter5++) + ((*iter5).first)->checkCFLinks((*iter5).second,end,isAlreadyFed,false,info); } -void ComposedNode::publishInputPort(InputPort *port) +/*! + * \param cross indicates if start -> end link is a DS link behind. + * \param fw out parameter. + * \param fwCross out parameter storing links where a cross has been detected. + * \param bw out parameter where backward links are stored. + */ +void ComposedNode::checkControlDependancy(OutPort *start, InPort *end, bool cross, + std::map < ComposedNode *, std::list < OutPort * > >& fw, + std::vector& fwCross, + std::map< ComposedNode *, std::list < OutPort *> >& bw, + LinkInfo& info) const { - _setOfInputPort.insert(port); + throw Exception("ComposedNode::checkControlDependancy : Internal error occured - should never been called !"); } -void ComposedNode::unpublishInputPort(InputPort *port) +/*! + * \param starts If different of 0, must aggregate at leat \b 1 element. + * \param alreadyFed in/out parameter. Indicates if 'end' ports is already and surely set or fed by an another port. + * \param direction If true : forward direction else backward direction. + */ +void ComposedNode::checkCFLinks(const std::list< OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const { - _setOfInputPort.erase(port); + throw Exception("ComposedNode::checkCFLinks : Internal error occured - should never been called !"); +} + +std::vector< std::pair > ComposedNode::getSetOfLinksComingInCurrentScope() const +{ + vector< pair > ret; + set ports=getAllInPortsComingFromOutsideOfCurrentScope(); + for(set::iterator iter2=ports.begin();iter2!=ports.end();iter2++) + { + set temp2=(*iter2)->edSetOutPort(); + for(set::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++) + if(!isInMyDescendance((*iter3)->getNode())) + ret.push_back(pair(*iter2,*iter3)); + } + return ret; +} + +//! List all output ports of children nodes that are linked to out of scope input ports +/*! + * \note List all output ports of nodes sons of 'this' that are linked to input ports + * of nodes not in descendance of 'this'. + * This method contrary to getAllInPortsComingFromOutsideOfCurrentScope is NOT virtual + * because for the moment all daughter classes have no more hidden YACS::ENGINE::OutPort. + */ +std::set ComposedNode::getAllOutPortsLeavingCurrentScope() const +{ + set ret; + list temp=getSetOfOutPort(); + for(list::iterator iter2=temp.begin();iter2!=temp.end();iter2++) + { + set temp2=(*iter2)->edSetInPort(); + for(set::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++) + if(!isInMyDescendance((*iter3)->getNode())) + { + ret.insert(*iter2); + break; + } + } + return ret; +} + +//! List all input ports that are linked to out of scope ports +/*! + * + * List all input ports of 'this' so that, for each it exists at least 1 link coming + * from outside to it. + * + */ +std::set ComposedNode::getAllInPortsComingFromOutsideOfCurrentScope() const +{ + set ret; + list temp=getSetOfInPort(); + for(list::iterator iter2=temp.begin();iter2!=temp.end();iter2++) + { + set temp2=(*iter2)->edSetOutPort(); + for(set::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++) + if(*iter3) + if(!isInMyDescendance((*iter3)->getNode())) + { + ret.insert(*iter2); + break; + } + } + return ret; } +void ComposedNode::edDisconnectAllLinksWithMe() +{ + //CF + Node::edDisconnectAllLinksWithMe(); + //Leaving part + vector< pair > linksToDestroy=getSetOfLinksLeavingCurrentScope(); + vector< pair >::iterator iter; + for(iter=linksToDestroy.begin();iter!=linksToDestroy.end();iter++) + (*iter).first->removeInPort((*iter).second,true); + //Arriving part + vector< pair > linksToDestroy2=getSetOfLinksComingInCurrentScope(); + vector< pair >::iterator iter2; + for(iter2=linksToDestroy2.begin();iter2!=linksToDestroy2.end();iter2++) + (*iter2).second->removeInPort((*iter2).first,true); +} ComposedNode *ComposedNode::getRootNode() throw(Exception) { @@ -214,41 +692,122 @@ ComposedNode *ComposedNode::getRootNode() throw(Exception) return Node::getRootNode(); } -/** - * @note : perform the disconnection of all links under the scope of 'this' connected to an input (dataflow or datastream) of node 'node'. - * This method is quite heavy because the links are stored in one direction. +bool ComposedNode::isNodeAlreadyAggregated(Node *node) const +{ + set nodeAncestors = node->getAllAscendanceOf(); + if ( nodeAncestors.find((ComposedNode*)this) == nodeAncestors.end() ) + return false; + else + return true; +} + +//! Returns the parent of a node that is the direct child of this node +/*! + * \note if 'nodeToTest'=='this' this is returned. Else if 'nodeToTest' is in descendance of + * 'this' the direct son is returned. + * Else 0 is returned. + * + * \param nodeToTest : the node to check */ -void ComposedNode::disconnectAllLinksConnectedTo(Node *node) +Node *ComposedNode::isInMyDescendance(Node *nodeToTest) const { - set setOfAllNodes=getRecursiveConstituents(); - for(set::iterator iter=setOfAllNodes.begin();iter!=setOfAllNodes.end();iter++) - (*iter)->disconnectAllLinksConnectedTo(node); + if(nodeToTest==0) + return 0; + if((ComposedNode *)nodeToTest==this) + return (Node *)this; + Node *iterBack=nodeToTest; + ComposedNode *iter=nodeToTest->_father; + while(iter!=0 && iter!=this) + { + iterBack=iter; + iter=iter->_father; + } + if(iter!=0) + return iterBack; + else + return 0; } -/** - * @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' +string ComposedNode::getChildName(Node* node) const throw(Exception) +{ + string nodeName = node->getQualifiedName(); + if (!isNodeAlreadyAggregated(node)) + { + if (node->getName() == "thisIsAFakeNode") + { + string child = node->getName()+".thisIsAFakeNode"; + return child; + } + else + { + string what("node "); what+= node->getName() ; what+=" is not a child of node "; what += getName(); + throw Exception(what); + } + } + + Node *father = node->_father; + while (father != this) + { + nodeName = father->getQualifiedName() + SEP_CHAR_BTW_LEVEL + nodeName; + father = father->_father; + } + return nodeName; +} + +std::string ComposedNode::getMyQualifiedName(const Node *directSon) const +{ + return directSon->getName(); +} + +Node *ComposedNode::getChildByName(const std::string& name) const throw(Exception) +{ + string potentiallyDirectSonName, remainsPath; + bool forwardNeeded=ComposedNode::splitNamesBySep(name, SEP_CHAR_BTW_LEVEL, + potentiallyDirectSonName,remainsPath,false); + Node *child=getChildByShortName(potentiallyDirectSonName); + if(!forwardNeeded) + return child; + else + return child->getChildByName(remainsPath); +} + +//! Check if a node is in the descendance of this node +/*! + * \note Check that 'nodeToTest' is in descendance of 'this' OR equal to 'this' + * \exception Exception : If 'nodeToTest' is NOT in descendance of 'this' AND not equal to 'this' + * \param nodeToTest : the node to check */ void ComposedNode::checkInMyDescendance(Node *nodeToTest) const throw(Exception) { - const char what[]="check failed : node is not in the correct descendance"; + const char whatC[]=" is not the descendance of node "; if(nodeToTest==0) - throw Exception(what); + { + string what("node "); what+= nodeToTest->getName(); what+=" "; + what+=whatC; what+=_name; + throw Exception(what); + } if((ComposedNode *)nodeToTest==this) return; ComposedNode *iter=nodeToTest->_father; while(iter!=0 && iter!=this) iter=iter->_father; if(iter==0) - throw Exception(what); + { + string what("node "); what+= nodeToTest->getName(); what+=" "; + what+=whatC; what+=_name; + throw Exception(what); + } } -/** +//! Retrieves the lowest common ancestor of 2 nodes +/*! * - * @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. + * \note Retrieves the lowest common ancestor of 'node1' AND 'node2'. + * If 'node1' or 'node2' are both or indiscriminately instances of ComposedNode and that + * 'node1' is in descendance of 'node2' (resp. 'node2' in descendance of 'node1') + * 'node2' is returned (resp. 'node1'). + * \exception Exception : if 'node1' and 'node2' do not share the same genealogy. + * \return The lowest common ancestor if it exists. * */ ComposedNode *ComposedNode::getLowestCommonAncestor(Node *node1, Node *node2) throw(Exception) @@ -256,7 +815,11 @@ ComposedNode *ComposedNode::getLowestCommonAncestor(Node *node1, Node *node2) th const char what[]="2 nodes does not share the same genealogy"; if(node1==0 || node2==0) throw Exception(what); - ComposedNode *temp=node1->_father; + ComposedNode *temp; + if(dynamic_cast(node1)) + temp=(ComposedNode *)node1;//->_father; + else + temp=(ComposedNode *)node1->_father; set s; while(temp) { @@ -264,7 +827,10 @@ ComposedNode *ComposedNode::getLowestCommonAncestor(Node *node1, Node *node2) th temp=temp->_father; } // - temp=node2->_father; + if(dynamic_cast(node2)) + temp=(ComposedNode *)node2;//->_father; + else + temp=(ComposedNode *)node2->_father; set::iterator iter=s.find(temp); while(temp && iter==s.end()) { @@ -276,88 +842,369 @@ 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. +set ComposedNode::getRecursiveConstituents() const +{ + set ret; + set setOfNode=edGetDirectDescendants(); + for(set::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++) + { + set myCurrentSet=(*iter)->getRecursiveConstituents(); + ret.insert(myCurrentSet.begin(),myCurrentSet.end()); + } + return ret; +} + +set ComposedNode::getAllRecursiveConstituents() +{ + set ret; + set setOfNode=edGetDirectDescendants(); + for(set::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++) + { + if ( dynamic_cast (*iter) ) + { + set myCurrentSet=((ComposedNode*)(*iter))->getAllRecursiveConstituents(); + ret.insert(myCurrentSet.begin(),myCurrentSet.end()); + ret.insert(*iter); + } + else + { + set myCurrentSet=(*iter)->getRecursiveConstituents(); + ret.insert(myCurrentSet.begin(),myCurrentSet.end()); + } + } + return ret; +} + +//! Get all children nodes elementary and composed including this node +set ComposedNode::getAllRecursiveNodes() +{ + set ret; + set setOfNode=edGetDirectDescendants(); + for(set::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++) + { + if ( dynamic_cast (*iter) ) + { + set myCurrentSet=(*iter)->getRecursiveConstituents(); + ret.insert(myCurrentSet.begin(),myCurrentSet.end()); + //ret.insert(*iter); + } + else + { + set myCurrentSet=((ComposedNode*)(*iter))->getAllRecursiveNodes(); + ret.insert(myCurrentSet.begin(),myCurrentSet.end()); + //ret.insert(*iter); + } + } + ret.insert(this); + return ret; +} + +//! Get the input port name +/*! + * get the input port name used by the current node, recursively built with children names. */ -const string ComposedNode::getInputPortName(const InputPort * inputPort) throw (Exception) +string ComposedNode::getInPortName(const InPort * inPort) const throw (Exception) +{ + return getPortName(inPort); +} + +string ComposedNode::getOutPortName(const OutPort *outPort) const throw (Exception) +{ + return getPortName(outPort); +} + +int ComposedNode::getNumberOfInputPorts() const +{ + set constituents=edGetDirectDescendants(); + int ret=0; + for(set::iterator iter=constituents.begin();iter!=constituents.end();iter++) + ret+=(*iter)->getNumberOfInputPorts(); + return ret; +} + +int ComposedNode::getNumberOfOutputPorts() const +{ + set constituents=edGetDirectDescendants(); + int ret=0; + for(set::iterator iter=constituents.begin();iter!=constituents.end();iter++) + ret+=(*iter)->getNumberOfOutputPorts(); + return ret; +} + +list ComposedNode::getSetOfInputPort() const +{ + set constituents=edGetDirectDescendants(); + list ret; + for(set::iterator iter=constituents.begin();iter!=constituents.end();iter++) + { + list currentsPorts=(*iter)->getSetOfInputPort(); + ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end()); + } + return ret; +} + +list ComposedNode::getSetOfOutputPort() const +{ + set constituents=edGetDirectDescendants(); + list ret; + for(set::iterator iter=constituents.begin();iter!=constituents.end();iter++) + { + list currentsPorts=(*iter)->getSetOfOutputPort(); + ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end()); + } + return ret; +} + +list ComposedNode::getSetOfInputDataStreamPort() const { - Node *node = inputPort->getNode(); - string portName = inputPort->getName(); - string nodeName = node->getName(); + set constituents=edGetDirectDescendants(); + list ret; + for(set::iterator iter=constituents.begin();iter!=constituents.end();iter++) + { + list currentsPorts=(*iter)->getSetOfInputDataStreamPort(); + ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end()); + } + return ret; +} - set nodePortAncestors = node->getAllAscendanceOf(); +list ComposedNode::getSetOfOutputDataStreamPort() const +{ + set constituents=edGetDirectDescendants(); + list ret; + for(set::iterator iter=constituents.begin();iter!=constituents.end();iter++) + { + list currentsPorts=(*iter)->getSetOfOutputDataStreamPort(); + ret.insert(ret.end(),currentsPorts.begin(),currentsPorts.end()); + } + return ret; +} - if ( nodePortAncestors.find(this) == nodePortAncestors.end() ) +OutPort *ComposedNode::getOutPort(const std::string& name) const throw(Exception) +{ + string portName, nodeName; + if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false)) + { + Node *child = getChildByShortName(nodeName); + return child->getOutPort(portName); + } + else { - string what("InputPort "); what+= portName; what+=" does not belong to node "; what += nodeName; + string what("ComposedNode::getOutPort : the port with name "); what+=name; what+=" does not exist on the current level"; throw Exception(what); } +} - Node *father = node; - while (father != this) +//! Get an input port given its name +/*! + * Contrary to YACS::ENGINE::ComposedNode::getOutputPort, this method is \b NOT recursive + * and so the leaf of type ElementaryNode aggregating + * this InputPort is directly invoked. + */ +InputPort * ComposedNode::getInputPort(const std::string& name) const throw(Exception) +{ + string portName, nodeName; + if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true)) { - portName = father->getName() + '.' + portName; - father = father->_father; + Node *child = getChildByName(nodeName); + return child->getInputPort(portName); + } + else + { + string what("ComposedNode::getInputPort : the port with name "); what+=name; what+=" does not exist on the current level"; + throw Exception(what); + } +} + +//! Get an output port given its name +/*! + * Contrary to YACS::ENGINE::ComposedNode::getInputPort, this method is recursive and go + * down hierarchy step by step to complete its work. + */ +OutputPort * ComposedNode::getOutputPort(const std::string& name) const throw(Exception) +{ + string portName, nodeName; + if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false)) + { + Node *child = getChildByShortName(nodeName); + return child->getOutputPort(portName); + } + else + { + string what("ComposedNode::getOutputPort : the port with name "); what+=name; what+=" does not exist on the current level"; + throw Exception(what); + } +} + +InputDataStreamPort *ComposedNode::getInputDataStreamPort(const std::string& name) const throw(Exception) +{ + string portName, nodeName; + if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true)) + { + Node *child = getChildByName(nodeName); + return child->getInputDataStreamPort(portName); + } + else + { + string what("ComposedNode::getInputDataStreamPort : the port with name "); what+=name; what+=" does not exist on the current level"; + throw Exception(what); } - return portName; } -const string ComposedNode::getOutputPortName(const OutputPort *outputPort) throw (Exception) +OutputDataStreamPort *ComposedNode::getOutputDataStreamPort(const std::string& name) const throw(Exception) { + string portName, nodeName; + if(splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true)) + { + Node *child = getChildByName(nodeName); + return child->getOutputDataStreamPort(portName); + } + else + { + string what("ComposedNode::getOutputDataStreamPort : the port with name "); what+=name; what+=" does not exist on the current level"; + throw Exception(what); + } } -/** +//! Update node state on receiving event from a node +/*! + * + * \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. * - * @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. + * Calls ComposedNode::updateStateOnStartEventFrom if event is YACS::START * + * Calls ComposedNode::updateStateOnFinishedEventFrom if event is YACS::FINISH + * + * Called by ComposedNode::notifyFrom */ YACS::Event ComposedNode::updateStateFrom(Node *node, //* I : node emitting event - YACS::Event event //* I : event emitted - ) + YACS::Event event //* I : event emitted + ) { - switch(event) + DEBTRACE("updateStateFrom: " << node->getName() << " " << event); + try + { + switch(event) + { + case YACS::START: + return updateStateOnStartEventFrom(node); + break; + case YACS::FINISH: + return updateStateOnFinishedEventFrom(node); + break; + case YACS::ABORT: + return updateStateOnFailedEventFrom(node); + break; + default: + return YACS::NOEVENT;//TODO unexpected type of event + break; + } + } + catch(YACS::Exception& ex) + { + //unexpected exception: probably a bug in engine + //try to keep a consistent global state + DEBTRACE( "updateStateFrom: " << ex.what() ); + setState(YACS::ERROR); + exForwardFailed(); + return YACS::ABORT; + } + catch(...) { - case YACS::START: - return updateStateOnStartEventFrom(node); - break; - case YACS::FINISH: - return updateStateOnFinishedEventFrom(node); - break; - default: - return YACS::NOEVENT;//TODO unexpected type of event - break; + //unexpected exception: probably a bug in engine + //try to keep a consistent global state + setState(YACS::ERROR); + exForwardFailed(); + return YACS::ABORT; } } -InPort *ComposedNode::buildDelegateOf(InPort *port, const set& pointsOfView) +//! Method used to notify the node that a child node has started +/*! + * Update the ComposedNode state and return the ComposedNode change state + * + * \param node : the child node that has started + * \return the loop state change + */ +YACS::Event ComposedNode::updateStateOnStartEventFrom(Node *node) +{ + setState(YACS::ACTIVATED); + return YACS::START; +} + +//! Method used to notify the node that a child node has failed +YACS::Event ComposedNode::updateStateOnFailedEventFrom(Node *node) { - return port; + setState(YACS::FAILED); + return YACS::ABORT; } -OutPort *ComposedNode::buildDelegateOf(OutPort *port, const set& pointsOfView) +void ComposedNode::checkLinkPossibility(OutPort *start, const std::set& pointsOfViewStart, + InPort *end, const std::set& pointsOfViewEnd) throw(Exception) { - return port; + if((dynamic_cast(start) or dynamic_cast(end)) + and (dynamic_cast(start) or dynamic_cast(end))) + {//cross protocol required : deeper check needed + bool isOK=false; + set::iterator iter; + for(iter=pointsOfViewStart.begin();iter!=pointsOfViewStart.end() and !isOK;iter++) + isOK=(*iter)->isRepeatedUnpredictablySeveralTimes(); + for(iter=pointsOfViewEnd.begin();iter!=pointsOfViewEnd.end() and !isOK;iter++) + isOK=(*iter)->isRepeatedUnpredictablySeveralTimes(); + if(!isOK) + throw Exception("ComposedNode::checkLinkPossibility : Request for cross protocol link impossible."); + } } -InPort *ComposedNode::getDelegateOf(InPort *port, const set& pointsOfView) throw(Exception) +void ComposedNode::buildDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView) { - return port; } -OutPort *ComposedNode::getDelegateOf(OutPort *port, const set& pointsOfView) throw(Exception) +void ComposedNode::buildDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) { - return port; } -InPort *ComposedNode::releaseDelegateOf(InPort *port, const set& pointsOfView) throw(Exception) +void ComposedNode::getDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView) throw(Exception) +{ +} + +void ComposedNode::getDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) throw(Exception) +{ +} + +void ComposedNode::releaseDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView) throw(Exception) +{ +} + +void ComposedNode::releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::set& pointsOfView) throw(Exception) +{ +} + +void ComposedNode::loaded() +{ +} + +void ComposedNode::accept(Visitor *visitor) +{ + set constituents=edGetDirectDescendants(); + for(set::iterator iter=constituents.begin(); iter!=constituents.end(); iter++) + { + (*iter)->accept(visitor); + } +} + +//! redefined on derived class of ComposedNode. by default a ComposedNode has no port by itself +std::list ComposedNode::getLocalInputPorts() const { - return port; + std::list lip; return lip; // empty list } -OutPort *ComposedNode::releaseDelegateOf(OutPort *port, const set& pointsOfView) throw(Exception) +//! redefined on derived class of ComposedNode. by default a ComposedNode has no port by itself +std::list ComposedNode::getLocalOutputPorts() const { - return port; + std::list lop; return lop; // empty list } diff --git a/src/engine/ComposedNode.hxx b/src/engine/ComposedNode.hxx index b70b7ef94..1082ae90b 100644 --- a/src/engine/ComposedNode.hxx +++ b/src/engine/ComposedNode.hxx @@ -4,6 +4,10 @@ #include "Node.hxx" #include "Scheduler.hxx" +#include +#include +#include + namespace YACS { namespace ENGINE @@ -11,43 +15,131 @@ namespace YACS class Bloc; class InPort; class OutPort; + class LinkInfo; class ElementaryNode; class ComposedNode : public Node, public Scheduler { friend class Bloc; + friend class OutPort; friend class ElementaryNode; + protected: + static const char SEP_CHAR_BTW_LEVEL[]; protected: ComposedNode(const std::string& name); + ComposedNode(const ComposedNode& other, ComposedNode *father); + void performDuplicationOfPlacement(const Node& other); public: + virtual ~ComposedNode(); + bool isFinished(); + void init(bool start=true); + std::string getName() const; + std::string getTaskName(Task *task) const; + DeploymentTree getDeploymentTree() const; + bool operator>(const ComposedNode& other) const; + bool operator<(const ComposedNode& other) const; + DeploymentTree checkDeploymentTree(bool deep) const throw(Exception); + std::vector getNextTasks(bool& isMore); + virtual bool isPlacementPredictableB4Run() const = 0; void notifyFrom(const Task *sender, YACS::Event event); - bool edAddLink(OutputPort *start, InputPort *end) throw(Exception); + bool edAddLink(OutPort *start, InPort *end) throw(Exception); + virtual bool edAddDFLink(OutPort *start, InPort *end) throw(Exception); bool edAddLink(OutGate *start, InGate *end) throw(Exception); bool edAddCFLink(Node *nodeS, Node *nodeE) throw(Exception); - void edRemoveLink(OutputPort *start, InputPort *end) throw(Exception); + void edRemoveCFLink(Node *nodeS, Node *nodeE) throw(Exception); + void edRemoveLink(OutPort *start, InPort *end) throw(Exception); 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: + virtual std::set edGetDirectDescendants() const = 0; + std::set getRecursiveConstituents() const; + std::set getAllRecursiveNodes(); + virtual std::set getAllRecursiveConstituents(); // first implementation + std::string getInPortName(const InPort *) const throw (Exception); + std::string getOutPortName(const OutPort *) const throw (Exception); + // + int getNumberOfInputPorts() const; + int getNumberOfOutputPorts() const; + std::list getSetOfInputPort() const; + std::list getSetOfOutputPort() const; + std::list getLocalInputPorts() const; + std::list getLocalOutputPorts() const; + std::set getAllOutPortsLeavingCurrentScope() const; + std::set getAllInPortsComingFromOutsideOfCurrentScope() const; + std::list getSetOfInputDataStreamPort() const; + std::list getSetOfOutputDataStreamPort() const; + OutPort *getOutPort(const std::string& name) const throw(Exception); + InputPort *getInputPort(const std::string& name) const throw(Exception); + OutputPort *getOutputPort(const std::string& name) const throw(Exception); + InputDataStreamPort *getInputDataStreamPort(const std::string& name) const throw(Exception); + OutputDataStreamPort *getOutputDataStreamPort(const std::string& name) const throw(Exception); + std::vector< std::pair > getSetOfInternalLinks() const; + std::vector< std::pair > getSetOfLinksLeavingCurrentScope() const; + void checkConsistency(LinkInfo& info) const throw(Exception); + virtual std::vector< std::pair > getSetOfLinksComingInCurrentScope() const; + // ComposedNode *getRootNode() throw(Exception); - void disconnectAllLinksConnectedTo(Node *node); - virtual void publishInputPort(InputPort *port); - virtual void unpublishInputPort(InputPort *port); + bool isNodeAlreadyAggregated(Node *node) const; + Node *isInMyDescendance(Node *nodeToTest) const; + std::string getChildName(Node* node) const throw(Exception); + virtual std::string getMyQualifiedName(const Node *directSon) const; + Node *getChildByName(const std::string& name) const throw(Exception); + static ComposedNode *getLowestCommonAncestor(Node *node1, Node *node2) throw(Exception); + void loaded(); + void accept(Visitor *visitor); + protected: + void edDisconnectAllLinksWithMe(); + static bool splitNamesBySep(const std::string& globalName, const char separator[], + std::string& firstPart, std::string& lastPart, bool priority) throw(Exception); + virtual void edRemoveChild(Node *node) throw(Exception); + virtual Node *getChildByShortName(const std::string& name) const throw(Exception) = 0; 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 updateStateOnStartEventFrom(Node *node);//transition 3 doc P.R virtual YACS::Event updateStateOnFinishedEventFrom(Node *node) = 0;//transition 9 doc P.R. - 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 YACS::Event updateStateOnFailedEventFrom(Node *node);//transition 9 doc P.R. + virtual void checkLinkPossibility(OutPort *start, const std::set& pointsOfViewStart, + InPort *end, const std::set& pointsOfViewEnd) throw(Exception); + virtual void buildDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView); + virtual void buildDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView); + virtual void getDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView) throw(Exception); + virtual void getDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) throw(Exception); + virtual void releaseDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView) throw(Exception); + virtual void releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, 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); + template + std::string getPortName(const PORT * port) const throw (Exception); + //For CF Computations + virtual void performCFComputations(LinkInfo& info) const; + virtual void destructCFComputations(LinkInfo& info) const; + void checkLinksCoherenceRegardingControl(const std::map >& starts, + InputPort *end, LinkInfo& info) const throw(Exception); + virtual void checkControlDependancy(OutPort *start, InPort *end, bool cross, + std::map < ComposedNode *, std::list < OutPort * > >& fw, + std::vector& fwCross, + std::map< ComposedNode *, std::list < OutPort *> >& bw, + LinkInfo& info) const; + virtual void checkCFLinks(const std::list< OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const; + protected: + //For internal calculations. + static const unsigned char FED_ST = 2; + static const unsigned char FREE_ST = 0; + static const unsigned char FED_DS_ST = 1; }; + + template + std::string ComposedNode::getPortName(const PORT * port) const throw (Exception) + { + Node *node = port->getNode(); + std::string portName = port->getName(); + checkInMyDescendance(node); + Node *father = node; + while (father != this) + { + portName = father->getQualifiedName() + Node::SEP_CHAR_IN_PORT + portName; + father = father->_father; + } + return portName; + } } } diff --git a/src/engine/ConditionInputPort.cxx b/src/engine/ConditionInputPort.cxx new file mode 100644 index 000000000..41c215e08 --- /dev/null +++ b/src/engine/ConditionInputPort.cxx @@ -0,0 +1,106 @@ +#include "ConditionInputPort.hxx" +#include "WhileLoop.hxx" +#include "OutputPort.hxx" +#include +#include + +using namespace YACS::ENGINE; +using namespace std; + +ConditionInputPort::ConditionInputPort(const std::string& name, WhileLoop *node):InputPort(name,node,Runtime::_tc_bool), + DataPort(name,node,Runtime::_tc_bool), + Port(node),_outOfScopeBackLink(0),_value(0) +{ +} + +ConditionInputPort::ConditionInputPort(const ConditionInputPort& other, Node *newHelder):InputPort(other,newHelder), + DataPort(other,newHelder),Port(other,newHelder), + _outOfScopeBackLink(0),_value(0) +{ + if(other._value) + _value=other._value->clone(); +} + +ConditionInputPort::~ConditionInputPort() +{ + if(_value) + _value->decrRef(); +} + +void ConditionInputPort::exSaveInit() +{ + if(_initValue) _initValue->decrRef(); + _initValue=_value; + _initValue->incrRef(); +} + +void ConditionInputPort::exRestoreInit() +{ + if(!_initValue) + return; + if(_value) + _value->decrRef(); + _value=_initValue; + _value->incrRef(); +} + +InputPort *ConditionInputPort::clone(Node *newHelder) const +{ + return new ConditionInputPort(*this,newHelder); +} + +bool ConditionInputPort::isLinkedOutOfScope() const +{ + return _outOfScopeBackLink!=0; +} + +void ConditionInputPort::edNotifyReferencedBy(OutPort *fromPort) +{ + if(!((ComposedNode*)(_node))->isInMyDescendance(fromPort->getNode())) + { + if(_outOfScopeBackLink) + throw Exception("ConditionInputPort::edNotifyReferenced : already linked from outside"); + _outOfScopeBackLink=fromPort; + return ; + } + InputPort::edNotifyReferencedBy(fromPort); +} + +void ConditionInputPort::edNotifyDereferencedBy(OutPort *fromPort) +{ + if(fromPort==_outOfScopeBackLink) + _outOfScopeBackLink=0; + else + if(!((ComposedNode*)(_node))->isInMyDescendance(fromPort->getNode())) + throw Exception("ConditionInputPort::edNotifyDereferencedBy link does not exists"); + InputPort::edNotifyDereferencedBy(fromPort); +} + +void *ConditionInputPort::get() const throw(Exception) +{ + if(!_value) + { + std::string what="ConditionInputPort::get : no value currently in input whith name \""; what+=_name; what+="\""; + throw Exception(what); + } + return (void *)_value; +} + +void ConditionInputPort::put(const void *data) throw(ConversionException) +{ + Any *dataCst=(Any *)data; + if(_value) + _value->decrRef(); + _value=dataCst; + _value->incrRef(); +} + +std::string ConditionInputPort::dump() +{ + string xmldump; + if (_value->getBoolValue()) + xmldump="true\n"; + else + xmldump="false\n"; + return xmldump; +} diff --git a/src/engine/ConditionInputPort.hxx b/src/engine/ConditionInputPort.hxx new file mode 100644 index 000000000..468bb5cb9 --- /dev/null +++ b/src/engine/ConditionInputPort.hxx @@ -0,0 +1,37 @@ +#ifndef __CONDITIONINPUTPORT_HXX__ +#define __CONDITIONINPUTPORT_HXX__ + +#include "InputPort.hxx" + +namespace YACS +{ + namespace ENGINE + { + class WhileLoop; + + class ConditionInputPort : public InputPort // public inheritance for correct dynamic cast from Port to ConditionInputPort in GUI part + { + friend class WhileLoop; + OutPort *_outOfScopeBackLink; + + ConditionInputPort(const std::string& name, WhileLoop *node); + ConditionInputPort(const ConditionInputPort& other, Node *newHelder); + ~ConditionInputPort(); + void exSaveInit(); + void exRestoreInit(); + InputPort *clone(Node *newHelder) const; + bool isLinkedOutOfScope() const; + void edNotifyReferencedBy(OutPort *fromPort); + void edNotifyDereferencedBy(OutPort *fromPort); + void *get() const throw(Exception); + void put(const void *data) throw(ConversionException); + std::string dump(); + protected: + Any *_value; + public: + bool getValue() const { return _value->getBoolValue(); } + }; + } +} + +#endif diff --git a/src/engine/Container.cxx b/src/engine/Container.cxx new file mode 100644 index 000000000..802fe1dda --- /dev/null +++ b/src/engine/Container.cxx @@ -0,0 +1,54 @@ +#include "Container.hxx" +#include "ComponentInstance.hxx" + +using namespace std; +using namespace YACS::ENGINE; + +Container::Container():_isAttachedOnCloning(false) +{ +} + +Container::~Container() +{ +} + +/*! + * By calling this method the current container 'this' is not destined to be deeply copied on clone call. + */ +void Container::attachOnCloning() const +{ + _isAttachedOnCloning=true; +} + +/*! + * By calling this method the current container 'this' will be deeply copied on clone call. + */ +void Container::dettachOnCloning() const +{ + _isAttachedOnCloning=false; +} + +bool Container::isAttachedOnCloning() const +{ + return _isAttachedOnCloning; +} + +/*! + * This method informs about the capability of the container to deal with CT an unpredictably number of components. + * By default : True + */ +bool Container::isSupportingRTODefNbOfComp() const +{ + return true; +} + +void Container::setProperty(const std::string& name, const std::string& value) +{ + _propertyMap[name]=value; +} + +std::string Container::getProperty(const std::string& name) +{ + return _propertyMap[name]; +} + diff --git a/src/engine/Container.hxx b/src/engine/Container.hxx new file mode 100644 index 000000000..afa558ab9 --- /dev/null +++ b/src/engine/Container.hxx @@ -0,0 +1,45 @@ +#ifndef __CONTAINER_HXX__ +#define __CONTAINER_HXX__ + +#include "Exception.hxx" +#include "RefCounter.hxx" + +#include +#include + +namespace YACS +{ + namespace ENGINE + { + class ComponentInstance; + /*! + * This is an abstract class, that represents an abstract process in which ComponentInstances can be launched and run. + */ + class Container : public RefCounter + { + protected: + Container(); + virtual ~Container(); + public: + //Execution only methods + virtual bool isAlreadyStarted() const = 0; + virtual void start() throw(Exception) = 0; + virtual std::string getPlacementId() const = 0; + //Edition only methods + virtual void attachOnCloning() const; + virtual void dettachOnCloning() const; + bool isAttachedOnCloning() const; + //! \b WARNING ! clone behaviour \b MUST be in coherence with what is returned by isAttachedOnCloning() method + virtual Container *clone() const = 0; + virtual bool isSupportingRTODefNbOfComp() const; + virtual void checkCapabilityToDealWith(const ComponentInstance *inst) const throw(Exception) = 0; + virtual void setProperty(const std::string& name,const std::string& value); + virtual std::string getProperty(const std::string& name); + protected: + mutable bool _isAttachedOnCloning; + std::map _propertyMap; + }; + } +} + +#endif diff --git a/src/engine/ConversionException.cxx b/src/engine/ConversionException.cxx index 06b839cf6..5aacc9e34 100644 --- a/src/engine/ConversionException.cxx +++ b/src/engine/ConversionException.cxx @@ -10,3 +10,7 @@ ConversionException::ConversionException(const std::string& what):Exception(TYPE _what=TYPEOFEXCEPTION; _what+=what; } + +ConversionException::~ConversionException() throw () +{ +} diff --git a/src/engine/ConversionException.hxx b/src/engine/ConversionException.hxx index a9d2c2323..58a94182f 100644 --- a/src/engine/ConversionException.hxx +++ b/src/engine/ConversionException.hxx @@ -13,6 +13,7 @@ namespace YACS { public: ConversionException(const std::string& what); + virtual ~ConversionException() throw(); private: static const char TYPEOFEXCEPTION[]; }; diff --git a/src/engine/DataFlowPort.cxx b/src/engine/DataFlowPort.cxx index bc5825446..6e749ff79 100644 --- a/src/engine/DataFlowPort.cxx +++ b/src/engine/DataFlowPort.cxx @@ -5,28 +5,24 @@ using namespace std; const char DataFlowPort::NAME[]="DataFlowPort"; -DataFlowPort::DataFlowPort(const string& name, Node *node, TypeCode* type):Port(node),_name(name) +DataFlowPort::DataFlowPort(const DataFlowPort& other, Node *newHelder):DataPort(other,newHelder),Port(other,newHelder) { - _type = type; } -string DataFlowPort::getNameOfTypeOfCurrentInstance() const +DataFlowPort::DataFlowPort(const std::string& name, Node *node, TypeCode* type):DataPort(name,node,type),Port(node) { - return NAME; } -TypeCode* DataFlowPort::edGetType() const +DataFlowPort::~DataFlowPort() { - return _type; } -TypeCode * DataFlowPort::type() +string DataFlowPort::getNameOfTypeOfCurrentInstance() const { - return _type; + return NAME; } -void DataFlowPort::edSetType(TypeCode* type) +bool DataFlowPort::isDifferentTypeOf(const DataPort *other) const { - _type = type; + return (dynamic_cast(other))==0; } - diff --git a/src/engine/DataFlowPort.hxx b/src/engine/DataFlowPort.hxx index 3237b72ae..77ba805f5 100644 --- a/src/engine/DataFlowPort.hxx +++ b/src/engine/DataFlowPort.hxx @@ -1,7 +1,7 @@ #ifndef __DATAFLOWPORT_HXX__ #define __DATAFLOWPORT_HXX__ -#include "Port.hxx" +#include "DataPort.hxx" #include @@ -9,21 +9,17 @@ namespace YACS { namespace ENGINE { - class DataFlowPort : public virtual Port + class DataFlowPort : public virtual DataPort { - protected: - void* _data; - std::string _name; public: static const char NAME[]; protected: + DataFlowPort(const DataFlowPort& other, Node *newHelder); DataFlowPort(const std::string& name, Node *node, TypeCode* type); public: std::string getNameOfTypeOfCurrentInstance() const; - TypeCode* edGetType() const; - virtual TypeCode * type(); - virtual void edSetType(TypeCode* type); - std::string getName() const { return _name; } + bool isDifferentTypeOf(const DataPort *other) const; + virtual ~DataFlowPort(); }; } } diff --git a/src/engine/DataPort.cxx b/src/engine/DataPort.cxx new file mode 100644 index 000000000..ef679fea9 --- /dev/null +++ b/src/engine/DataPort.cxx @@ -0,0 +1,51 @@ +#include "DataPort.hxx" +#include + +using namespace YACS::ENGINE; +using namespace std; + +const char DataPort::NAME[]="DataPort"; + +DataPort::~DataPort() +{ + _type->decrRef(); +} + +DataPort::DataPort(const std::string& name, Node *node, TypeCode* type):Port(node),_name(name),_type(type) +{ + _type->incrRef(); +} + +DataPort::DataPort(const DataPort& other, Node *newHelder):Port(other,newHelder),_name(other._name),_type(other._type) +{ + _type->incrRef(); +} + +void DataPort::edSetType(TypeCode* type) +{ + if(_type) + _type->decrRef(); + _type=type; + if(_type) + _type->incrRef(); +} + +string DataPort::getNameOfTypeOfCurrentInstance() const +{ + return NAME; +} + + +/*! + * If in historyOfLink different type of Port are detected : The first one (by starting from the end of 'historyOfLink') + * is returned. Else 0 is returned if they are all of the same type. + */ +DataPort *DataPort::isCrossingType(const std::vector& historyOfLink) +{ + vector::const_reverse_iterator iter=historyOfLink.rbegin()+1; + const DataPort *base=historyOfLink.back(); + for(;iter!=historyOfLink.rend();iter++) + if(base->isDifferentTypeOf(*iter)) + return *iter; + return 0; +} diff --git a/src/engine/DataPort.hxx b/src/engine/DataPort.hxx new file mode 100644 index 000000000..96b546412 --- /dev/null +++ b/src/engine/DataPort.hxx @@ -0,0 +1,34 @@ +#ifndef __DATAPORT_HXX__ +#define __DATAPORT_HXX__ + +#include "Port.hxx" + +namespace YACS +{ + namespace ENGINE + { + class DataPort : public virtual Port + { + protected: + TypeCode *_type; + std::string _name; + public: + static const char NAME[]; + protected: + virtual ~DataPort(); + DataPort(const DataPort& other, Node *newHelder); + DataPort(const std::string& name, Node *node, TypeCode* type); + public: + TypeCode* edGetType() const { return _type; } + void edSetType(TypeCode* type); + std::string getName() const { return _name; } + std::string getNameOfTypeOfCurrentInstance() const; + virtual bool isDifferentTypeOf(const DataPort *other) const = 0; + virtual void edRemoveAllLinksLinkedWithMe() throw(Exception) = 0; + public: + static DataPort *isCrossingType(const std::vector& historyOfLink); + }; + } +} + +#endif diff --git a/src/engine/DataStreamPort.cxx b/src/engine/DataStreamPort.cxx index 50f4efb69..016471985 100644 --- a/src/engine/DataStreamPort.cxx +++ b/src/engine/DataStreamPort.cxx @@ -1,11 +1,20 @@ #include "DataStreamPort.hxx" +#include using namespace YACS::ENGINE; using namespace std; const char DataStreamPort::NAME[]="DataStreamPort"; -DataStreamPort::DataStreamPort(const string& name, Node *node, TypeCode* type):Port(node),_name(name),_edType(type) +DataStreamPort::DataStreamPort(const DataStreamPort& other, Node *newHelder):DataPort(other,newHelder),Port(other,newHelder),_propertyMap(other._propertyMap) +{ +} + +DataStreamPort::DataStreamPort(const std::string& name, Node *node, TypeCode* type):DataPort(name,node,type),Port(node) +{ +} + +DataStreamPort::~DataStreamPort() { } @@ -13,3 +22,22 @@ string DataStreamPort::getNameOfTypeOfCurrentInstance() const { return NAME; } + +bool DataStreamPort::isDifferentTypeOf(const DataPort *other) const +{ + return (dynamic_cast(other))==0; +} + +void DataStreamPort::setProperty(const std::string& name, const std::string& value) +{ + _propertyMap[name]=value; +} + +std::string DataStreamPort::getProperty(const std::string& name) +{ + return _propertyMap[name]; +} +void DataStreamPort::initPortProperties() +{ +} + diff --git a/src/engine/DataStreamPort.hxx b/src/engine/DataStreamPort.hxx index 9aef868f3..2556d8ad8 100644 --- a/src/engine/DataStreamPort.hxx +++ b/src/engine/DataStreamPort.hxx @@ -1,28 +1,32 @@ #ifndef __DATASTREAMPORT_HXX__ #define __DATASTREAMPORT_HXX__ -#include "Port.hxx" +#include "DataPort.hxx" #include "TypeCode.hxx" #include +#include namespace YACS { namespace ENGINE { - class DataStreamPort : public virtual Port + class DataStreamPort : public virtual DataPort { - protected: - std::string _name; - TypeCode* _edType; public: static const char NAME[]; protected: + DataStreamPort(const DataStreamPort& other, Node *newHelder); DataStreamPort(const std::string& name, Node *node, TypeCode* type); + std::map _propertyMap; public: std::string getNameOfTypeOfCurrentInstance() const; - std::string getName() const { return _name; } - TypeCode* edGetType() const { return _edType; } + bool isDifferentTypeOf(const DataPort *other) const; + virtual void setProperty(const std::string& name,const std::string& value); + virtual std::string getProperty(const std::string& name); + std::map getPropertyMap() const { return _propertyMap; } + virtual void initPortProperties(); + virtual ~DataStreamPort(); }; } } diff --git a/src/engine/DeploymentTree.cxx b/src/engine/DeploymentTree.cxx new file mode 100644 index 000000000..6a689871c --- /dev/null +++ b/src/engine/DeploymentTree.cxx @@ -0,0 +1,446 @@ +#include "DeploymentTree.hxx" +#include "ComponentInstance.hxx" +#include "Container.hxx" +#include "Scheduler.hxx" +#include "Task.hxx" + +using namespace std; +using namespace YACS::ENGINE; + +DeploymentTreeOnHeap::DeploymentTreeOnHeap():_cnt(1) +{ +} + +DeploymentTreeOnHeap::~DeploymentTreeOnHeap() +{ +} + +bool DeploymentTreeOnHeap::decrRef() +{ + bool ret=(--_cnt==0); + if(ret) + delete this; + return ret; +} + +void DeploymentTreeOnHeap::incrRef() const +{ + _cnt++; +} + +unsigned char DeploymentTreeOnHeap::appendTask(Task *task, Scheduler *cloner) +{ + if(!task) + return DeploymentTree::NULL_TASK; + if(!task->isDeployable())//Task not needed to be placed. + return DeploymentTree::NOT_DEPLOYABLE_TASK; + ComponentInstance *ci=task->getComponent(); + if(!ci)//Task is not attached to a Component -> not needed to be placed. + { + _freePlacableTasks.push_back(pair(task,cloner)); + return DeploymentTree::DEPLOYABLE_BUT_NOT_SPECIFIED; + } + Container *cont=ci->getContainer(); + vector< vector< vector< pair > > >::iterator iter1; + vector< vector< pair > >::iterator iter2; + vector< pair >::iterator iter3; + for(iter1=_tree.begin();iter1!=_tree.end();iter1++) + if(((*iter1)[0][0]).first->getComponent()->getContainer()==cont) + break; + if(iter1==_tree.end()) + { + _tree.push_back(vector< vector< pair< Task *, Scheduler *> > >()); + iter1=_tree.end(); + iter1--; + } + for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + if(((*iter2)[0]).first->getComponent()==ci) + break; + if(iter2==(*iter1).end()) + { + (*iter1).push_back(vector< pair< Task *, Scheduler *> >()); + iter2=(*iter1).end(); + iter2--; + } + for(iter3=(*iter2).begin();iter3!=(*iter2).end();iter3++) + if((*iter3).first==task) + return DeploymentTree::ALREADY_IN_TREE; + if(!isConsistentTaskRegardingShCompInst(*iter2,cloner)) + return DeploymentTree::DUP_TASK_NOT_COMPATIBLE_WITH_EXISTING_TREE; + (*iter2).push_back(pair(task,cloner)); + return DeploymentTree::APPEND_OK; +} + +unsigned DeploymentTreeOnHeap::getNumberOfCTDefContainer() const +{ + vector< vector< vector< pair > > >::const_iterator iter1; + vector< vector< pair > >::const_iterator iter2; + vector< pair >::const_iterator iter3; + unsigned ret=0; + for(iter1=_tree.begin();iter1!=_tree.end();iter1++) + { + bool isCTDefSurely1=true; + for(iter2=(*iter1).begin();iter2!=(*iter1).end() && isCTDefSurely1;iter2++) + { + bool isCTDefSurely2=true; + for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isCTDefSurely2;iter3++) + if((*iter3).second!=0) + isCTDefSurely2=false; + if(isCTDefSurely2) + isCTDefSurely1=true; + else + isCTDefSurely1=(((*iter2)[0].first)->getComponent()->isAttachedOnCloning()); + } + Container *cont=((*iter1)[0][0].first)->getComponent()->getContainer(); + if(isCTDefSurely1) + { + if(cont) + ret++; + } + else + if(cont) + if(cont->isAttachedOnCloning()) + ret++; + else + { + unsigned val; + if((*iter1)[0][0].second->isMultiplicitySpecified(val)) + ret+=val; + } + } + return ret; +} + +unsigned DeploymentTreeOnHeap::getNumberOfRTODefContainer() const +{ + vector< vector< vector< pair > > >::const_iterator iter1; + vector< vector< pair > >::const_iterator iter2; + vector< pair >::const_iterator iter3; + unsigned ret=0; + for(iter1=_tree.begin();iter1!=_tree.end();iter1++) + { + bool isRTODefSurely1=true; + for(iter2=(*iter1).begin();iter2!=(*iter1).end() && isRTODefSurely1;iter2++) + { + bool isRTODefSurely2=true; + for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isRTODefSurely2;iter3++) + if((*iter3).second==0) + isRTODefSurely2=false; + if(isRTODefSurely2) + isRTODefSurely1=!(((*iter2)[0].first)->getComponent()->isAttachedOnCloning()); + else + isRTODefSurely1=false; + } + if(isRTODefSurely1) + if(((*iter1)[0][0].first)->getComponent()->getContainer()) + if(!((*iter1)[0][0].first)->getComponent()->getContainer()->isAttachedOnCloning()) + ret++; + } + return ret; +} + +unsigned DeploymentTreeOnHeap::getNumberOfCTDefComponentInstances() const +{ + vector< vector< vector< pair > > >::const_iterator iter1; + vector< vector< pair > >::const_iterator iter2; + vector< pair >::const_iterator iter3; + unsigned ret=0; + for(iter1=_tree.begin();iter1!=_tree.end();iter1++) + for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + { + bool isCTDefSurely=true; + for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isCTDefSurely;iter3++) + if((*iter3).second!=0) + isCTDefSurely=false; + if(isCTDefSurely) + ret++; + else + if(((*iter2)[0].first)->getComponent()->isAttachedOnCloning()) + ret++; + } + return ret; +} + +unsigned DeploymentTreeOnHeap::getNumberOfRTODefComponentInstances() const +{ + vector< vector< vector< pair > > >::const_iterator iter1; + vector< vector< pair > >::const_iterator iter2; + vector< pair >::const_iterator iter3; + unsigned ret=0; + for(iter1=_tree.begin();iter1!=_tree.end();iter1++) + for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + { + bool isRTODef=false; + for(iter3=(*iter2).begin();iter3!=(*iter2).end() && !isRTODef;iter3++) + if((*iter3).second!=0) + isRTODef=true; + if(isRTODef && !((*iter2)[0].first)->getComponent()->isAttachedOnCloning()) + ret++; + } + return ret; +} + +std::vector DeploymentTreeOnHeap::getAllContainers() const +{ + vector ret; + vector< vector< vector< pair > > >::const_iterator iter1; + for(iter1=_tree.begin();iter1!=_tree.end();iter1++) + ret.push_back(((*iter1)[0][0].first)->getComponent()->getContainer()); + return ret; +} + +std::vector DeploymentTreeOnHeap::getAllCTDefContainers() const +{ + vector ret; + vector< vector< vector< pair > > >::const_iterator iter1; + vector< vector< pair > >::const_iterator iter2; + vector< pair >::const_iterator iter3; + for(iter1=_tree.begin();iter1!=_tree.end();iter1++) + { + bool isCTDefSurely1=true; + for(iter2=(*iter1).begin();iter2!=(*iter1).end() && isCTDefSurely1;iter2++) + { + bool isCTDefSurely2=true; + for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isCTDefSurely2;iter3++) + if((*iter3).second!=0) + isCTDefSurely2=false; + if(isCTDefSurely2) + isCTDefSurely1=true; + else + isCTDefSurely1=(((*iter2)[0].first)->getComponent()->isAttachedOnCloning()); + } + Container *cont=((*iter1)[0][0].first)->getComponent()->getContainer(); + if(isCTDefSurely1) + { + if(cont) + ret.push_back(cont); + } + else + if(cont) + if(cont->isAttachedOnCloning()) + ret.push_back(cont); + } + return ret; +} + +std::vector DeploymentTreeOnHeap::getAllRTODefContainers() const +{ + vector< vector< vector< pair > > >::const_iterator iter1; + vector< vector< pair > >::const_iterator iter2; + vector< pair >::const_iterator iter3; + vector ret; + for(iter1=_tree.begin();iter1!=_tree.end();iter1++) + { + bool isRTODefSurely1=true; + for(iter2=(*iter1).begin();iter2!=(*iter1).end() && isRTODefSurely1;iter2++) + { + bool isRTODefSurely2=true; + for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isRTODefSurely2;iter3++) + if((*iter3).second==0) + isRTODefSurely2=false; + if(isRTODefSurely2) + isRTODefSurely1=!(((*iter2)[0].first)->getComponent()->isAttachedOnCloning()); + else + isRTODefSurely1=false; + } + if(isRTODefSurely1) + if(((*iter1)[0][0].first)->getComponent()->getContainer()) + if(!((*iter1)[0][0].first)->getComponent()->getContainer()->isAttachedOnCloning()) + ret.push_back(((*iter1)[0][0].first)->getComponent()->getContainer()); + } + return ret; +} + +std::vector DeploymentTreeOnHeap::getTasksLinkedToComponent(ComponentInstance *comp) const +{ + vector< vector< vector< pair > > >::const_iterator iter1; + vector< vector< pair > >::const_iterator iter2; + vector< pair >::const_iterator iter3; + + std::vector ret; + for(iter1=_tree.begin();iter1!=_tree.end();iter1++) + for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + if(((*iter2)[0].first)->getComponent()==comp) + for(iter3=(*iter2).begin();iter3!=(*iter2).end();iter3++) + ret.push_back((*iter3).first); + return ret; +} + +std::vector DeploymentTreeOnHeap::getComponentsLinkedToContainer(Container *cont) const +{ + vector ret; + vector< vector< vector< pair > > >::const_iterator iter1; + vector< vector< pair > >::const_iterator iter2; + for(iter1=_tree.begin();iter1!=_tree.end();iter1++) + if(((*iter1)[0][0].first)->getComponent()->getContainer()==cont) + for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + ret.push_back(((*iter2)[0].first)->getComponent()); + return ret; +} + +bool DeploymentTreeOnHeap::presenceOfDefaultContainer() const +{ + vector< vector< vector< pair > > >::const_iterator iter1; + for(iter1=_tree.begin();iter1!=_tree.end();iter1++) + if(!((*iter1)[0][0].first)->getComponent()->getContainer()) + return true; + return false; +} + +std::vector DeploymentTreeOnHeap::getFreeDeployableTasks() const +{ + vector ret; + for(vector< pair >::const_iterator iter=_freePlacableTasks.begin();iter!=_freePlacableTasks.end();iter++) + ret.push_back((*iter).first); + return ret; +} + +bool DeploymentTreeOnHeap::isConsistentTaskRegardingShCompInst(std::vector< std::pair >& tasksSharingSameCompInst, Scheduler *cloner) +{ + vector< std::pair >::const_iterator iter; + bool coexistenceOfDifferentSched=false; + for(iter=tasksSharingSameCompInst.begin();iter!=tasksSharingSameCompInst.end() && !coexistenceOfDifferentSched;iter++) + { + coexistenceOfDifferentSched=(((*iter).second)!=cloner); + } + if(!coexistenceOfDifferentSched) + return true; + //In this case the component is duplicated on cloning raising on runtime on different policy (schedulers) than other tasks in tasksSharingSameCompInst + return (tasksSharingSameCompInst[0].first)->getComponent()->isAttachedOnCloning(); +} + +DeploymentTree::DeploymentTree():_treeHandle(0) +{ +} + +DeploymentTree::~DeploymentTree() +{ + if(_treeHandle) + _treeHandle->decrRef(); +} + +DeploymentTree::DeploymentTree(const DeploymentTree& other) +{ + _treeHandle=other._treeHandle; + if(_treeHandle) + _treeHandle->incrRef(); +} + +const DeploymentTree &DeploymentTree::operator=(const DeploymentTree& other) +{ + if(_treeHandle) + _treeHandle->decrRef(); + _treeHandle=other._treeHandle; + if(_treeHandle) + _treeHandle->incrRef(); + return *this; +} + +unsigned char DeploymentTree::appendTask(Task *task, Scheduler *cloner) +{ + if(_treeHandle) + return _treeHandle->appendTask(task,cloner); + if(!task) + return DeploymentTree::NULL_TASK; + if(!task->isDeployable())//Task not needed to be placed. + return DeploymentTree::NOT_DEPLOYABLE_TASK; + _treeHandle=new DeploymentTreeOnHeap; + return _treeHandle->appendTask(task,cloner); +} + +/*! + * Returns number of containers predictably launchable \b without counting default container. + */ +unsigned DeploymentTree::getNumberOfCTDefContainer() const +{ + if(_treeHandle) + return _treeHandle->getNumberOfCTDefContainer(); + return 0; +} + +/*! + * Returns number of containers unpredictably launchable \b without counting default container. + */ +unsigned DeploymentTree::getNumberOfRTODefContainer() const +{ + if(_treeHandle) + return _treeHandle->getNumberOfRTODefContainer(); + return 0; +} + +unsigned DeploymentTree::getNumberOfCTDefComponentInstances() const +{ + if(_treeHandle) + return _treeHandle->getNumberOfCTDefComponentInstances(); + return 0; +} + +unsigned DeploymentTree::getNumberOfRTODefComponentInstances() const +{ + if(_treeHandle) + return _treeHandle->getNumberOfRTODefComponentInstances(); + return 0; +} + +/*! + * Returns all containers default included (0). + */ +std::vector DeploymentTree::getAllContainers() const +{ + if(_treeHandle) + return _treeHandle->getAllContainers(); + return vector(); +} + +/*! + * Returns containers predictably launchable \b without counting default container. + */ +std::vector DeploymentTree::getAllCTDefContainers() const +{ + if(_treeHandle) + return _treeHandle->getAllCTDefContainers(); + return vector(); +} + +/*! + * Returns containers unpredictably launchable \b without counting default container. + */ +std::vector DeploymentTree::getAllRTODefContainers() const +{ + if(_treeHandle) + return _treeHandle->getAllRTODefContainers(); + return vector(); +} + +std::vector DeploymentTree::getTasksLinkedToComponent(ComponentInstance *comp) const +{ + if(_treeHandle) + return _treeHandle->getTasksLinkedToComponent(comp); + return vector(); +} + +std::vector DeploymentTree::getComponentsLinkedToContainer(Container *cont) const +{ + if(_treeHandle) + return _treeHandle->getComponentsLinkedToContainer(cont); + return vector(); +} + +bool DeploymentTree::presenceOfDefaultContainer() const +{ + if(_treeHandle) + return _treeHandle->presenceOfDefaultContainer(); + return false; +} + +bool DeploymentTree::isNull() const +{ + return _treeHandle==0; +} + +std::vector DeploymentTree::getFreeDeployableTasks() const +{ + if(_treeHandle) + return _treeHandle->getFreeDeployableTasks(); + return vector(); +} diff --git a/src/engine/DeploymentTree.hxx b/src/engine/DeploymentTree.hxx new file mode 100644 index 000000000..09b00022e --- /dev/null +++ b/src/engine/DeploymentTree.hxx @@ -0,0 +1,85 @@ +#ifndef __DEPLOYMENTTREE_HXX__ +#define __DEPLOYMENTTREE_HXX__ + +#include + +namespace YACS +{ + namespace ENGINE + { + class Task; + class Container; + class Scheduler; + class ComponentInstance; + + class DeploymentTreeOnHeap + { + public: + DeploymentTreeOnHeap(); + ~DeploymentTreeOnHeap(); + bool decrRef(); + void incrRef() const; + // + unsigned char appendTask(Task *task, Scheduler *cloner); + // + unsigned getNumberOfCTDefContainer() const; + unsigned getNumberOfRTODefContainer() const; + unsigned getNumberOfCTDefComponentInstances() const; + unsigned getNumberOfRTODefComponentInstances() const; + // + std::vector getAllContainers() const; + std::vector getAllCTDefContainers() const; + std::vector getAllRTODefContainers() const; + std::vector getTasksLinkedToComponent(ComponentInstance *comp) const; + std::vector getComponentsLinkedToContainer(Container *cont) const; + // + bool presenceOfDefaultContainer() const; + std::vector getFreeDeployableTasks() const; + private: + static bool isConsistentTaskRegardingShCompInst(std::vector< std::pair >& tasksSharingSameCompInst, Scheduler *cloner); + private: + mutable int _cnt; + std::vector< std::pair > _freePlacableTasks; + //! internal representation of tree. Scheduler is the duplicating Task, \b if it exists, on runtime unpredictable times on compil-time + std::vector< std::vector< std::vector< std::pair > > > _tree; + }; + + class DeploymentTree + { + public: + DeploymentTree(); + ~DeploymentTree(); + DeploymentTree(const DeploymentTree& other); + const DeploymentTree &operator=(const DeploymentTree& other); + unsigned char appendTask(Task *task, Scheduler *cloner); + // + unsigned getNumberOfCTDefContainer() const; + unsigned getNumberOfRTODefContainer() const; + unsigned getNumberOfCTDefComponentInstances() const; + unsigned getNumberOfRTODefComponentInstances() const; + // + bool presenceOfDefaultContainer() const; + std::vector getAllContainers() const; + std::vector getAllCTDefContainers() const; + std::vector getAllRTODefContainers() const; + std::vector getTasksLinkedToComponent(ComponentInstance *comp) const; + std::vector getComponentsLinkedToContainer(Container *cont) const; + // + bool isNull() const; + std::vector getFreeDeployableTasks() const; + public: + //possible return of appendTask method. + static const unsigned char NULL_TASK = 3; + static const unsigned char APPEND_OK = 0; + static const unsigned char NULL_TREE = 199; + static const unsigned char ALREADY_IN_TREE = 1; + static const unsigned char NOT_DEPLOYABLE_TASK = 2; + static const unsigned char DEPLOYABLE_BUT_NOT_SPECIFIED = 5; + static const unsigned char DUP_TASK_NOT_COMPATIBLE_WITH_EXISTING_TREE = 4; + private: + DeploymentTreeOnHeap *_treeHandle; + }; + } +} + +#endif diff --git a/src/engine/Dispatcher.cxx b/src/engine/Dispatcher.cxx new file mode 100644 index 000000000..581100bbc --- /dev/null +++ b/src/engine/Dispatcher.cxx @@ -0,0 +1,77 @@ +#include "Dispatcher.hxx" +#include "Node.hxx" +#include + +using namespace YACS::ENGINE; + +Observer::~Observer() +{ +} + +void Observer::notifyObserver(Node* object, const std::string& event) +{ + std::cerr << "notifyObserver " << event << object << std::endl; +} + +Dispatcher* Dispatcher::_singleton = 0; + +Dispatcher::~Dispatcher() +{ + Dispatcher::_singleton =0; +} + +Dispatcher* Dispatcher::getDispatcher() +{ + if ( !Dispatcher::_singleton ) + { + Dispatcher::_singleton =new Dispatcher; + } + return Dispatcher::_singleton; +} + +void Dispatcher::setDispatcher(Dispatcher* dispatcher) +{ + Dispatcher::_singleton=dispatcher; +} + +void Dispatcher::printObservers() +{ + std::cerr << "Dispatcher::printObservers " << std::endl; + typedef std::map< std::pair , std::set >::iterator it; + typedef std::set::iterator jt; + + for(it i=_observers.begin();i!=_observers.end();i++) + { + std::cerr << "Node*: " << (*i).first.first << " event: " << (*i).first.second << std::endl; + for(jt j=(*i).second.begin();j!=(*i).second.end();j++) + { + std::cerr << "observer: " << *j << std::endl; + } + } +} + +void Dispatcher::dispatch(Node* object, const std::string& event) +{ + //std::cerr << "Dispatcher::dispatch " << event << std::endl; + typedef std::set::iterator jt; + std::pair key(object,event); + if(_observers.count(key) != 0) + { + for(jt iter=_observers[key].begin();iter!=_observers[key].end();iter++) + { + (*iter)->notifyObserver(object,event); + } + } +} + +void Dispatcher::addObserver(Observer* observer,Node* object, const std::string& event) +{ + _observers[std::pair(object,event)].insert(observer); +// printObservers(); +} + +void Dispatcher::removeObserver(Observer* observer,Node* object, const std::string& event) +{ + _observers[std::pair(object,event)].erase(observer); +// printObservers(); +} diff --git a/src/engine/Dispatcher.hxx b/src/engine/Dispatcher.hxx new file mode 100644 index 000000000..ede2d13e9 --- /dev/null +++ b/src/engine/Dispatcher.hxx @@ -0,0 +1,69 @@ +#ifndef __DISPATCHER_HXX__ +#define __DISPATCHER_HXX__ + +#include +#include +#include + +namespace YACS +{ + namespace ENGINE + { + class Node; + class Executor; + +/*! \brief Base class for observer in observer pattern + * + * When an event occurs, a registered observer is notified by + * calling its notifyObserver method with 2 arguments : the object + * which has emitted the event and the event type. There is no more + * data. It's the responsability of the observer to request all needed + * information from the emitting object. + * + */ + class Observer + { + public: + virtual void notifyObserver(Node* object,const std::string& event); + virtual ~Observer(); + }; + +/*! \brief Base class for dispatcher in observer pattern + * + * Dispatcher and Observer objects can be used to be notified about events + * that occurs in editing or executing a calculation schema. + * + * When an object wants to notify an event, it calls the dispatch method + * of the dispatcher with 2 arguments : the object reference and an event type. + * The dispatcher which is a singleton is obtained by calling the class method + * getDispatcher. + * The dispatcher notifies all the registered observers by calling their notifyObserver + * method. + * + * Observers can be registered by calling the addObserver method with two + * arguments : an object reference and an event type. This observer will be + * notify with events coming only from this object. + * + * Limitation : emitting objects can be only Node + * + */ + class Dispatcher + { + public: + virtual void dispatch(Node* object,const std::string& event); + virtual void addObserver(Observer* observer,Node* object,const std::string& event); + virtual void removeObserver(Observer* observer,Node* object,const std::string& event); + virtual void printObservers(); + static Dispatcher* getDispatcher(); + static void setDispatcher(Dispatcher* dispatcher); + virtual ~Dispatcher(); + protected: + std::map< std::pair , std::set > _observers; + std::map< std::pair , std::set > _observExec; + static Dispatcher* _singleton; + }; + + } +} + +#endif diff --git a/src/engine/DynParaLoop.cxx b/src/engine/DynParaLoop.cxx new file mode 100644 index 000000000..3fa713db0 --- /dev/null +++ b/src/engine/DynParaLoop.cxx @@ -0,0 +1,389 @@ +#include "DynParaLoop.hxx" +#include "OutPort.hxx" +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; +using namespace YACS::ENGINE; + +const char DynParaLoop::NAME_OF_SPLITTED_SEQ_OUT[]="SmplPrt"; + +const char DynParaLoop::NAME_OF_NUMBER_OF_BRANCHES[]="nbBranches"; + +AnyOutputPort::AnyOutputPort(const std::string& name, Node *node, TypeCode *type):OutputPort(name,node,type), + DataPort(name,node,type),Port(node),_data(0) +{ +} + +AnyOutputPort::AnyOutputPort(const AnyOutputPort& other, Node *newHelder):OutputPort(other,newHelder), + DataPort(other,newHelder), + Port(other,newHelder),_data(0) +{ +} + +AnyOutputPort::~AnyOutputPort() +{ + if(_data) + _data->decrRef(); +} + +void AnyOutputPort::setValue(Any *data) +{ + if(_data) + _data->decrRef(); + _data = data; + if(_data) + _data->incrRef(); +} + +OutputPort *AnyOutputPort::clone(Node *newHelder) const +{ + return new AnyOutputPort(*this,newHelder); +} + +DynParaLoop::DynParaLoop(const std::string& name, TypeCode *typeOfDataSplitted):ComposedNode(name),_node(0),_initNode(0),_nbOfEltConsumed(0), + _nbOfBranches(NAME_OF_NUMBER_OF_BRANCHES,this,Runtime::_tc_int), + _splittedPort(NAME_OF_SPLITTED_SEQ_OUT,this,typeOfDataSplitted) +{ +} + +DynParaLoop::~DynParaLoop() +{ + delete _node; + delete _initNode; +} + +DynParaLoop::DynParaLoop(const DynParaLoop& other, ComposedNode *father, bool editionOnly):ComposedNode(other,father), + _nbOfBranches(other._nbOfBranches,this), + _splittedPort(other._splittedPort,this), + _node(0),_initNode(0),_nbOfEltConsumed(0) +{ + if(other._node) + _node=other._node->clone(this,editionOnly); + if(other._initNode) + _initNode=other._initNode->clone(this,editionOnly); + const AnyOutputPort& startOfLinksToReproduce=other._splittedPort; + set endsOfLinksToReproduce=startOfLinksToReproduce.edSetInPort(); + for(set::iterator iter=endsOfLinksToReproduce.begin();iter!=endsOfLinksToReproduce.end();iter++) + edAddLink(&_splittedPort,getInPort(other.getPortName(*iter))); +} + +Node *DynParaLoop::edSetNode(Node *node) +{ + if(_node==node) + return 0; + if(node) + { + if(node->_father) + { + std::string what = "DynParaLoop::edSetNode: node "; what += node->getName(); what += " is not orphan ! "; + throw Exception(what); + } + if(_initNode) + if(_initNode->getName()==node->getName()) + { + std::string what = "DynParaLoop::edSetNode: node "; what += node->getName(); what += " has the same name than init node already in "; what+=_name; what+="! "; + throw Exception(what); + } + } + ComposedNode::edRemoveChild(_node); + Node *ret=_node; + _node=node; + _node->_father=this; + return ret; +} + +void DynParaLoop::init(bool start) +{ + ComposedNode::init(start); + if(!_node) + { + string what("DynParaLoop::init : no node specified for ForEachLoop with name "); what +=_name; + throw Exception(what); + } + _nbOfBranches.exInit(start); + _splittedPort.exInit(); + _nbOfEltConsumed=0; +} + +Node *DynParaLoop::edSetInitNode(Node *node) +{ + if(_initNode==node) + return 0; + if(node) + { + if(node->_father) + { + std::string what = "DynParaLoop::edSetInitNode : node "; what += node->getName(); what += " is not orphan ! "; + throw Exception(what); + } + if(_node) + if(_node->getName()==node->getName()) + { + std::string what = "DynParaLoop::edSetInitNode : node "; what += node->getName(); what += " has the same name than node already in "; what+=_name; what+="! "; + throw Exception(what); + } + } + edRemoveChild(_initNode); + Node *ret=_initNode; + _initNode=node; + _initNode->_father=this; + return ret; +} + +int DynParaLoop::getNumberOfInputPorts() const +{ + return ComposedNode::getNumberOfInputPorts()+1; +} + +int DynParaLoop::getNumberOfOutputPorts() const +{ + return ComposedNode::getNumberOfOutputPorts()+1; +} + +std::list DynParaLoop::getSetOfOutputPort() const +{ + list ret=ComposedNode::getSetOfOutputPort(); + ret.push_back((OutputPort *)&_splittedPort); + return ret; +} + +OutPort *DynParaLoop::getOutPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_OF_SPLITTED_SEQ_OUT) + return (OutPort *)&_splittedPort; + return ComposedNode::getOutPort(name); +} + +InputPort *DynParaLoop::getInputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_OF_NUMBER_OF_BRANCHES) + return (InputPort *)&_nbOfBranches; + return ComposedNode::getInputPort(name); +} + +OutputPort *DynParaLoop::getOutputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_OF_SPLITTED_SEQ_OUT) + return (OutputPort *)&_splittedPort; + return ComposedNode::getOutputPort(name); +} + +bool DynParaLoop::isPlacementPredictableB4Run() const +{ + return false; +} + +Node *DynParaLoop::edRemoveNode() +{ + if(!_node) + return 0; + ComposedNode::edRemoveChild(_node); + Node *ret=_node; + _node=0; + return ret; +} + +Node *DynParaLoop::edRemoveInitNode() +{ + if(!_initNode) + return 0; + ComposedNode::edRemoveChild(_initNode); + Node *ret=_initNode; + _initNode=0; + return ret; +} + +void DynParaLoop::edRemoveChild(Node *node) throw(Exception) +{ + ComposedNode::edRemoveChild(node); + if(node==_node) + _node=0; + if(node==_initNode) + _initNode=0; +} + +std::set DynParaLoop::edGetDirectDescendants() const +{ + set ret; + if(_node) + ret.insert(_node); + if(_initNode) + ret.insert(_initNode); + return ret; +} + +std::list DynParaLoop::getSetOfInputPort() const +{ + list ret=ComposedNode::getSetOfInputPort(); + ret.push_back((InputPort *)&_nbOfBranches); + return ret; +} + +unsigned DynParaLoop::getNumberOfBranchesCreatedDyn() const throw(Exception) +{ + if(_execNodes.empty()) + throw Exception("ForEachLoop::getNumberOfBranches : No branches created dynamically ! - ForEachLoop needs to run or to be runned to call getNumberOfBranches"); + else + return _execNodes.size(); +} + +Node *DynParaLoop::getChildByShortName(const std::string& name) const throw(Exception) +{ + if(_node) + if(name==_node->getName()) + return _node; + if(_initNode) + if(name==_initNode->getName()) + return _initNode; + std::string what("node "); what+= name ; what+=" is not a child of DynParaLoop node "; what += getName(); + throw Exception(what); +} + +Node *DynParaLoop::getChildByNameExec(const std::string& name, unsigned id) const throw(Exception) +{ + if(id>=getNumberOfBranchesCreatedDyn()) + throw Exception("ForEachLoop::getChildByNameExec : invalid id - too large compared with dynamically created branches."); + if(_node) + if(name==_node->getName()) + return _execNodes[id]; + if(_initNode) + if(name==_initNode->getName()) + return _execInitNodes[id]; + std::string what("node "); what+= name ; what+=" is not a child of DynParaLoop node "; what += getName(); + throw Exception(what); +} + +void DynParaLoop::cleanDynGraph() +{ + for(vector::iterator iter=_execNodes.begin();iter!=_execNodes.end();iter++) + delete *iter; + _execNodes.clear(); + for(vector::iterator iter2=_execInitNodes.begin();iter2!=_execInitNodes.end();iter2++) + delete *iter2; + _execNodes.clear(); +} + +/*! + * This method applies on newly cloned on exec nodes (_execNodes/_execInitNodes) + * the setting of input ports coming from outside of 'this' + */ +void DynParaLoop::prepareInputsFromOutOfScope(int branchNb) +{ + set< InPort * > portsToSetVals=getAllInPortsComingFromOutsideOfCurrentScope(); + portsToSetVals.erase(&_nbOfBranches);//_nbOfBranches inport is not a candidate of dynamically duplicated inport. + for(set< InPort * >::iterator iter=portsToSetVals.begin();iter!=portsToSetVals.end();iter++) + { + InputPort *curPortCasted=(InputPort *) *iter;//Cast granted by ForEachLoop::buildDelegateOf(InPort) + void *val=curPortCasted->get(); + InputPort *portToSet=getDynInputPortByAbsName(branchNb,getInPortName(*iter),true); + if(portToSet)//portToSet==0 in case of portToSet==_splitterNode._dataPortToDispatch of ForEach + { + portToSet->put((const void *)val); + portToSet->edNotifyReferencedBy(0);//This is to indicate that somewhere somebody deals with this inputport + //even if no direct physical link exists. This exclusively for _execNodes[branchNb]::init on the next turn of loop. + } + } +} + +void DynParaLoop::putValueOnBranch(Any *val, unsigned branchId, bool first) +{ + bool isDispatched = false; + set inPrtLkdWthSplttdPrt=_splittedPort.edSetInPort(); + for(set::iterator iter=inPrtLkdWthSplttdPrt.begin();iter!=inPrtLkdWthSplttdPrt.end();iter++) + { + std::string portNameOnCurPrt=getPortName(*iter); + InputPort *portOnGivenBranch=getDynInputPortByAbsName(branchId,portNameOnCurPrt,first);//Cast granted because impossible to have cross protocol with _splittedPort + //see OptimizerLoop::buildDelegateOf + if(portOnGivenBranch) + { + if(first) + portOnGivenBranch->edNotifyReferencedBy(0); + InputPort *traducer=getRuntime()->adapt(portOnGivenBranch, + Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME,_splittedPort.edGetType()); + traducer->put((const void *)val); + isDispatched = true; + if(traducer!=portOnGivenBranch) + delete traducer; + } + } + if ( isDispatched ) + { + Any *tmp=val->clone(); + _splittedPort.setValue(tmp); + tmp->decrRef(); + } +} + +DynParaLoop::TypeOfNode DynParaLoop::getIdentityOfNotifyerNode(const Node *node, unsigned& id) +{ + id=0; + for(vector::iterator iter=_execNodes.begin();iter!=_execNodes.end();iter++,id++) + if(*iter==node) + return WORK_NODE; + id=0; + for(vector::iterator iter2=_execInitNodes.begin();iter2!=_execInitNodes.end();iter2++,id++) + if(*iter2==node) + return INIT_NODE; +} + +bool DynParaLoop::isMultiplicitySpecified(unsigned& value) const +{ + if(_nbOfBranches.edIsManuallyInitialized()) + if(_nbOfBranches.edGetNumberOfLinks()==0) + { + value=_nbOfBranches.getIntValue(); + return true; + } + return false; +} + +void DynParaLoop::forceMultiplicity(unsigned value) +{ + _nbOfBranches.edRemoveAllLinksLinkedWithMe(); + _nbOfBranches.edInit((int)value); +} + +void DynParaLoop::buildDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView) +{ + string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); + if(typeOfPortInstance!=InputPort::NAME) + throw Exception("DynParaLoop::buildDelegateOf : A link with datastream end inside DynParaLoop this is not possible"); +} + +void DynParaLoop::buildDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) +{ + if(_initNode) + if(isInMyDescendance(port.first->getNode())==_initNode) + throw Exception("DynParaLoop::buildDelegateOf : uncorrect ForEach link : a link starting from init node can't leave the scope of ForEachLoop node it belongs to."); + if(port.first==&_splittedPort) + throw Exception("DynParaLoop::buildDelegateOf : uncorrect ForEach link : splitted port must be link within the scope of ForEachLoop node it belongs to."); +} + +/*! + * \note : For a given name 'name' of port in absolute form from this, returns the corresponding InputPort instance of the + * port for the branch # 'branchNb'. The port can be part of _node or _initNode if it exists (if 'initNodeAdmitted' is true). + * \b WARNING : no check performed on 'branchNb' value to see if it is compatible with size of '_execNodes'. + * This method is called to dispatch value on each InputPort linked to this->._splitterNode._splittedPort + */ +InputPort *DynParaLoop::getDynInputPortByAbsName(int branchNb, const std::string& name, bool initNodeAdmitted) +{ + string portName, nodeName; + splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true); + Node *staticChild = getChildByName(nodeName); + Node *desc=isInMyDescendance(staticChild); + if(desc==_node) + { + splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false); + return _execNodes[branchNb]->getInputPort(portName); + } + else if(desc==_initNode) + if(initNodeAdmitted) + { + splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false); + return _execInitNodes[branchNb]->getInputPort(portName); + } + return 0; +} diff --git a/src/engine/DynParaLoop.hxx b/src/engine/DynParaLoop.hxx new file mode 100644 index 000000000..6978a6995 --- /dev/null +++ b/src/engine/DynParaLoop.hxx @@ -0,0 +1,97 @@ +#ifndef __DYNPARALOOP_HXX__ +#define __DYNPARALOOP_HXX__ + +#include "ComposedNode.hxx" +#include "AnyInputPort.hxx" +#include "OutputPort.hxx" + +namespace YACS +{ + namespace ENGINE + { + class DynParaLoop; + + class AnyOutputPort : public OutputPort + { + friend class DynParaLoop; + public: + //! store the current dispatched value + virtual void setValue(Any *data); + //! get the current dispatched value for update port value + Any* getValue() const { return _data; } + private: + Any* _data; // the data dispatched from port on the current moment + private: + AnyOutputPort(const std::string& name, Node *node, TypeCode *type); + AnyOutputPort(const AnyOutputPort& other, Node *newHelder); + virtual ~AnyOutputPort(); + OutputPort *clone(Node *newHelder) const; + }; + + /*! + * \brief Base class for dynamically (fully or semifully) built graphs. + */ + class DynParaLoop : public ComposedNode + { + protected: + typedef enum + { + INIT_NODE = 5, + WORK_NODE = 6 + } TypeOfNode; + protected: + Node *_node; + Node *_initNode; + unsigned _nbOfEltConsumed; + std::vector _execIds; + AnyInputPort _nbOfBranches; + AnyOutputPort _splittedPort; + std::vector _execNodes; + std::vector _execInitNodes; + protected: + static const char NAME_OF_SPLITTED_SEQ_OUT[]; + static const char NAME_OF_NUMBER_OF_BRANCHES[]; + protected: + DynParaLoop(const std::string& name, TypeCode *typeOfDataSplitted); + virtual ~DynParaLoop(); + DynParaLoop(const DynParaLoop& other, ComposedNode *father, bool editionOnly); + public: + Node *edRemoveNode(); + Node *edRemoveInitNode(); + Node *edSetNode(Node *node); + Node *edSetInitNode(Node *node); + void init(bool start=true); + InputPort *edGetNbOfBranchesPort() { return &_nbOfBranches; } + int getNumberOfInputPorts() const; + int getNumberOfOutputPorts() const; + unsigned getNumberOfEltsConsumed() const { return _nbOfEltConsumed; } + std::list getSetOfOutputPort() const; + OutputPort *edGetSamplePort() { return &_splittedPort; } + OutPort *getOutPort(const std::string& name) const throw(Exception); + InputPort *getInputPort(const std::string& name) const throw(Exception); + OutputPort *getOutputPort(const std::string& name) const throw(Exception); + //! For the moment false is returned : impovement about it coming soon. + bool isPlacementPredictableB4Run() const; + void edRemoveChild(Node *node) throw(Exception); + std::set edGetDirectDescendants() const; + std::list getSetOfInputPort() const; + unsigned getNumberOfBranchesCreatedDyn() const throw(Exception); + Node *getChildByShortName(const std::string& name) const throw(Exception); + Node *getChildByNameExec(const std::string& name, unsigned id) const throw(Exception); + std::vector getNodes() const { return _execNodes; } // need to use in GUI part for adding observers for clone nodes + bool isMultiplicitySpecified(unsigned& value) const; + void forceMultiplicity(unsigned value); + protected: + void buildDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView); + void buildDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView); + protected: + void cleanDynGraph(); + void prepareInputsFromOutOfScope(int branchNb); + void putValueOnBranch(Any *val, unsigned branchId, bool first); + TypeOfNode getIdentityOfNotifyerNode(const Node *node, unsigned& id); + InputPort *getDynInputPortByAbsName(int branchNb, const std::string& name, bool initNodeAdmitted); + }; + } +} + +#endif diff --git a/src/engine/ElementaryNode.cxx b/src/engine/ElementaryNode.cxx index ea7a84115..ad1fb4144 100644 --- a/src/engine/ElementaryNode.cxx +++ b/src/engine/ElementaryNode.cxx @@ -5,33 +5,194 @@ #include "ComposedNode.hxx" #include "InputDataStreamPort.hxx" #include "OutputDataStreamPort.hxx" +#include "Visitor.hxx" +#include using namespace YACS::ENGINE; using namespace std; -ElementaryNode::ElementaryNode(const string& name):Node(name) +ElementaryNode::ElementaryNode(const std::string& name):Node(name) +{ +} + +ElementaryNode::ElementaryNode(const ElementaryNode& other, ComposedNode *father):Node(other,father) +{ + for(list::const_iterator iter1=other._setOfInputPort.begin();iter1!=other._setOfInputPort.end();iter1++) + _setOfInputPort.push_back((InputPort *)(*iter1)->clone(this)); + for(list::const_iterator iter2=other._setOfOutputPort.begin();iter2!=other._setOfOutputPort.end();iter2++) + _setOfOutputPort.push_back((OutputPort *)(*iter2)->clone(this)); + for(list::const_iterator iter3=other._setOfInputDataStreamPort.begin();iter3!=other._setOfInputDataStreamPort.end();iter3++) + _setOfInputDataStreamPort.push_back((InputDataStreamPort *)(*iter3)->clone(this)); + for(list::const_iterator iter4=other._setOfOutputDataStreamPort.begin();iter4!=other._setOfOutputDataStreamPort.end();iter4++) + _setOfOutputDataStreamPort.push_back((OutputDataStreamPort *)(*iter4)->clone(this)); +} + +void ElementaryNode::performDuplicationOfPlacement(const Node& other) { } ElementaryNode::~ElementaryNode() { - for(set::iterator iter1=_setOfInputPort.begin();iter1!=_setOfInputPort.end();iter1++) + for(list::iterator iter1=_setOfInputPort.begin();iter1!=_setOfInputPort.end();iter1++) delete *iter1; - for(set::iterator iter2=_setOfOutputPort.begin();iter2!=_setOfOutputPort.end();iter2++) + for(list::iterator iter2=_setOfOutputPort.begin();iter2!=_setOfOutputPort.end();iter2++) delete *iter2; - for(set::iterator iter3=_setOfInputDataStreamPort.begin();iter3!=_setOfInputDataStreamPort.end();iter3++) + for(list::iterator iter3=_setOfInputDataStreamPort.begin();iter3!=_setOfInputDataStreamPort.end();iter3++) delete *iter3; - for(set::iterator iter4=_setOfOutputDataStreamPort.begin();iter4!=_setOfOutputDataStreamPort.end();iter4++) + for(list::iterator iter4=_setOfOutputDataStreamPort.begin();iter4!=_setOfOutputDataStreamPort.end();iter4++) delete *iter4; } +void ElementaryNode::init(bool start) +{ + for(list::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++) + (*iter)->exInit(); + for(list::iterator iter2=_setOfInputPort.begin();iter2!=_setOfInputPort.end();iter2++) + (*iter2)->exInit(start); + _inGate.exReset(); + if(_state == YACS::DISABLED) + { + exDisabledState(); // to refresh propagation of DISABLED state + return; + } + if(start) //complete initialization + setState(YACS::INITED); + else //partial initialization (inside a loop) + _state=YACS::LOADED; +} + +bool ElementaryNode::isDeployable() const +{ + return false; +} + +ComponentInstance *ElementaryNode::getComponent() +{ + return 0; +} + +YACS::StatesForNode ElementaryNode::getState() const +{ + return Node::getState(); +} + +void ElementaryNode::exUpdateState() +{ + if(_state==YACS::DISABLED)return; + if(_inGate.exIsReady()) + if(areAllInputPortsValid()) + if(_state == YACS::INITED) + setState(YACS::TOLOAD); + else + setState(YACS::TOACTIVATE); + else + { + string what("ElementaryNode::exUpdateState : Invalid graph given : Node with name \""); + what+=_name; what+="\" ready to run whereas some inputports are not set correctly\nCheck coherence DF/CF"; + setState(YACS::INTERNALERR); + throw Exception(what); + } +} + +int ElementaryNode::getNumberOfInputPorts() const +{ + return _setOfInputPort.size(); +} + +int ElementaryNode::getNumberOfOutputPorts() const +{ + return _setOfOutputPort.size(); +} + +InputPort *ElementaryNode::getInputPort(const std::string& name) const throw(Exception) +{ + return getPort(name,_setOfInputPort); +} + +OutputPort *ElementaryNode::getOutputPort(const std::string& name) const throw(Exception) +{ + return getPort(name,_setOfOutputPort); +} + +std::set ElementaryNode::getAllOutPortsLeavingCurrentScope() const +{ + set ret; + list temp=getSetOfOutPort(); + for(list::iterator iter2=temp.begin();iter2!=temp.end();iter2++) + { + set temp2=(*iter2)->edSetInPort(); + if(temp2.size()!=0) + ret.insert(*iter2); + } + return ret; +} + +std::set ElementaryNode::getAllInPortsComingFromOutsideOfCurrentScope() const +{ + set ret; + list temp=getSetOfInPort(); + for(list::iterator iter2=temp.begin();iter2!=temp.end();iter2++) + { + set temp2=(*iter2)->edSetOutPort(); + if(temp2.size()!=0) + ret.insert(*iter2); + } + return ret; +} + +InputDataStreamPort *ElementaryNode::getInputDataStreamPort(const std::string& name) const throw(Exception) +{ + return getPort(name,_setOfInputDataStreamPort); +} + +OutputDataStreamPort *ElementaryNode::getOutputDataStreamPort(const std::string& name) const throw(Exception) +{ + return getPort(name,_setOfOutputDataStreamPort); +} + +void ElementaryNode::edDisconnectAllLinksWithMe() +{ + //CF + Node::edDisconnectAllLinksWithMe(); + //Leaving part + // - DF + for(list::iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + (*iter)->edRemoveAllLinksLinkedWithMe(); + // - DS + for(list::iterator iter2=_setOfInputDataStreamPort.begin();iter2!=_setOfInputDataStreamPort.end();iter2++) + (*iter2)->edRemoveAllLinksLinkedWithMe(); + //Arriving part + // - DF + for(list::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++) + (*iter)->edRemoveAllLinksLinkedWithMe(); + // - DS + for(list::iterator iter2=_setOfOutputDataStreamPort.begin();iter2!=_setOfOutputDataStreamPort.end();iter2++) + (*iter2)->edRemoveAllLinksLinkedWithMe(); +} + +/** + * checks if all input ports contains a valid data. Used at execution to change the state of the node + * for activation. + */ + +bool ElementaryNode::areAllInputPortsValid() const +{ + bool ret=true; + for(list::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + { + ret=!(*iter)->isEmpty(); + if (!ret) break; + } + return ret; +} + /** * add this node task to a given set of ready tasks, if this task is ready to activate */ -void ElementaryNode::getReadyTasks(vector& tasks) +void ElementaryNode::getReadyTasks(std::vector& tasks) { - if(_state==YACS::TOACTIVATE) + if(_state==YACS::TOACTIVATE or _state==YACS::TOLOAD) tasks.push_back(this); } @@ -42,7 +203,7 @@ void ElementaryNode::getReadyTasks(vector& tasks) void ElementaryNode::edRemovePort(Port *port) throw(Exception) { if(port->getNode()!=this) - throw Exception("ElementaryNode::edRemovePort : Port is not owned by this"); + throw Exception("ElementaryNode::edRemovePort : Port is not held by this"); string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); if(typeOfPortInstance==InputPort::NAME) edRemovePortTypedFromSet(dynamic_cast(port),_setOfInputPort); @@ -61,101 +222,123 @@ void ElementaryNode::edRemovePort(Port *port) throw(Exception) * @return a set with only this node. (Same method in composed nodes) */ -set ElementaryNode::getRecursiveConstituents() +set ElementaryNode::getRecursiveConstituents() const { set ret; - ret.insert(this); + ret.insert((ElementaryNode *)this); return ret; } +Node *ElementaryNode::getChildByName(const std::string& name) const throw(Exception) +{ + string what("ElementaryNode does not agregate any nodes particullary node with name "); what+=name; + throw Exception(what); +} + +void ElementaryNode::checkBasicConsistency() const throw(Exception) +{ + list::const_iterator iter; + for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + (*iter)->checkBasicConsistency(); +} + +ComposedNode *ElementaryNode::getDynClonerIfExists(const ComposedNode *levelToStop) const +{ + for(ComposedNode *iter=_father;iter!=levelToStop && iter!=0; iter=iter->_father) + if(!iter->isPlacementPredictableB4Run()) + return iter; + return 0; +} + /** * 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 *ElementaryNode::edAddInputPort(const std::string& inputPortName, TypeCode* type) throw(Exception) { InputPort *ret = 0; if (edCheckAddPort(inputPortName,_setOfInputPort,type)) { - //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 + _setOfInputPort.push_back(ret); ComposedNode *iter=_father; while(iter) - { - iter->publishInputPort(ret); - iter=iter->_father; - } + iter=iter->_father; } return ret; } /** - * The output port is not published in father. Father must create an output port. + * TO SOLVE : The output port is not published in father. Father must create an output port. + * for now, publication is done the same way as input ports */ -OutputPort *ElementaryNode::edAddOutputPort(const string& outputPortName, TypeCode* type) throw(Exception) +OutputPort *ElementaryNode::edAddOutputPort(const std::string& outputPortName, TypeCode* type) throw(Exception) { OutputPort *ret =0; if (edCheckAddPort(outputPortName,_setOfOutputPort,type)) { ret = getRuntime()->createOutputPort(outputPortName, _implementation, this, type); - _setOfOutputPort.insert(ret); + _setOfOutputPort.push_back(ret); + ComposedNode *iter=_father; + while(iter) + iter=iter->_father; } return ret; } -InputDataStreamPort *ElementaryNode::edAddInputDataStreamPort(const string& inputPortDSName, TypeCode* type) throw(Exception) +InputDataStreamPort *ElementaryNode::edAddInputDataStreamPort(const std::string& inputPortDSName, TypeCode* type) throw(Exception) { - return edAddPort(inputPortDSName,_setOfInputDataStreamPort,type); + InputDataStreamPort *ret = 0; + if (edCheckAddPort(inputPortDSName,_setOfInputDataStreamPort,type)) + { + ret = getRuntime()->createInputDataStreamPort(inputPortDSName, this, type); + _setOfInputDataStreamPort.push_back(ret); + } + return ret; } -OutputDataStreamPort *ElementaryNode::edAddOutputDataStreamPort(const string& outputPortDSName, TypeCode* type) throw(Exception) +OutputDataStreamPort *ElementaryNode::edAddOutputDataStreamPort(const std::string& outputPortDSName, TypeCode* type) throw(Exception) { - 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) -{ - 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()); + OutputDataStreamPort *ret = 0; + if (edCheckAddPort(outputPortDSName,_setOfOutputDataStreamPort,type)) + { + ret = getRuntime()->createOutputDataStreamPort(outputPortDSName, this, type); + _setOfOutputDataStreamPort.push_back(ret); + } + return ret; } /** * get the input port name used by the current node (see composed nodes) */ -const string ElementaryNode::getInputPortName(const InputPort * inputPort) throw (Exception) +string ElementaryNode::getInPortName(const InPort * inPort) const throw (Exception) { - Node *node = inputPort->getNode(); + Node *node = inPort->getNode(); if ( node != this ) { - string what("InputPort "); what += inputPort->getName(); what += " does not belong to node "; what += node->getName(); + string what("InputPort "); what += inPort->getName(); what += " does not belong to node "; what += node->getName(); throw Exception(what); } - return inputPort->getName(); + return inPort->getName(); } -const string ElementaryNode::getOutputPortName(const OutputPort *outputPort) throw (Exception) +string ElementaryNode::getOutPortName(const OutPort *outPort) const throw (Exception) { + Node *node = outPort->getNode(); + if ( node != this ) + { + string what("OutputPort "); what += outPort->getName(); what += " does not belong to node "; what += node->getName(); + throw Exception(what); + } + return outPort->getName(); } void ElementaryNode::begin() { - _state=ACTIVATED; + setState(ACTIVATED); } bool ElementaryNode::isReady() @@ -165,5 +348,25 @@ bool ElementaryNode::isReady() void ElementaryNode::finished() { - _state=DONE; + setState(DONE); +} +void ElementaryNode::aborted() +{ + setState(ERROR); +} + +//! Notify this node that it is loaded +/*! + * When an elementary node has been loaded it goes to TOACTIVATE state + * It is then ready to be executed + * + */ +void ElementaryNode::loaded() +{ + setState(TOACTIVATE); +} + +void ElementaryNode::accept(Visitor *visitor) +{ + visitor->visitElementaryNode(this); } diff --git a/src/engine/ElementaryNode.hxx b/src/engine/ElementaryNode.hxx index 7937cccac..3e4cb5391 100644 --- a/src/engine/ElementaryNode.hxx +++ b/src/engine/ElementaryNode.hxx @@ -5,7 +5,6 @@ #include "Node.hxx" #include "Task.hxx" #include "define.hxx" -//#include "Data.hxx" #include namespace YACS @@ -22,26 +21,154 @@ namespace YACS class ElementaryNode : public Node, public Task { friend class ComposedNode; + protected: + std::list _setOfInputPort; + std::list _setOfOutputPort; + std::list _setOfInputDataStreamPort; + std::list _setOfOutputDataStreamPort; protected: ElementaryNode(const std::string& name); - ~ElementaryNode(); + ElementaryNode(const ElementaryNode& other, ComposedNode *father); + void performDuplicationOfPlacement(const Node& other); public: + virtual ~ElementaryNode(); + void exUpdateState(); + void init(bool start=true); + bool isDeployable() const; + ComponentInstance *getComponent(); + YACS::StatesForNode getState() const; void getReadyTasks(std::vector& tasks); void edRemovePort(Port *port) throw(Exception); - std::set getRecursiveConstituents(); + std::set getRecursiveConstituents() const; + Node *getChildByName(const std::string& name) const throw(Exception); + void checkBasicConsistency() const throw(Exception); + ComposedNode *getDynClonerIfExists(const ComposedNode *levelToStop) const; + int getNumberOfInputPorts() const; + int getNumberOfOutputPorts() const; + std::string getInPortName(const InPort *) const throw (Exception); + std::string getOutPortName(const OutPort *) const throw (Exception); + InputPort *getInputPort(const std::string& name) const throw(Exception); + OutputPort *getOutputPort(const std::string& name) const throw(Exception); + std::list getSetOfInputPort() const { return _setOfInputPort; } + std::list getSetOfOutputPort() const { return _setOfOutputPort; } + std::list getLocalInputPorts() const { return _setOfInputPort; } + std::list getLocalOutputPorts() const { return _setOfOutputPort; } + std::set getAllOutPortsLeavingCurrentScope() const; + std::set getAllInPortsComingFromOutsideOfCurrentScope() const; + std::list getSetOfInputDataStreamPort() const { return _setOfInputDataStreamPort; } + std::list getSetOfOutputDataStreamPort() const { return _setOfOutputDataStreamPort; } + InputDataStreamPort *getInputDataStreamPort(const std::string& name) const throw(Exception); + OutputDataStreamPort *getOutputDataStreamPort(const std::string& name) const throw(Exception); 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(); void finished(); + void aborted(); + void loaded(); + virtual void initService() { } + virtual void connectService() { } + virtual void disconnectService() { } + virtual void load() { } + void accept(Visitor *visitor); protected: - void disconnectAllLinksConnectedTo(Node *node); + void edDisconnectAllLinksWithMe(); + bool areAllInputPortsValid() const; + template + PORT *getPort(const std::string& name, const std::list& setOfPorts) const throw(Exception); + template + PORT *edAddPort(const std::string& portName, std::list& setOfPorts, ENUMTYPE type) throw(Exception); + template + bool edCheckAddPort(const std::string& portName, std::list& setOfPorts, ENUMTYPE type) throw(Exception); + template + static void edRemovePortTypedFromSet(PORT *port, std::list& setOfPorts) throw(Exception); + template + static bool isPortNameAlreadyExist(const std::string& portName, const std::list& setOfPorts); }; + + /** + * protected: get a port in a list given it's name + */ + + template + PORT *ElementaryNode::getPort(const std::string& name, const std::list& setOfPorts) const throw(Exception) + { + for(typename std::list::const_iterator iter=setOfPorts.begin();iter!=setOfPorts.end();iter++) + { + if((*iter)->getName()==name) + return *iter; + } + std::string what="ElementaryNode::getPort : unexisting "; what+=PORT::NAME; + what+=" with name "; + what+=name; + throw Exception(what); + } + + /** + * protected: add a port given it's name and type, in a given list of ports + * WHY TEMPLATE PARAMETER ENUMTYPE? + */ + + template + PORT *ElementaryNode::edAddPort(const std::string& portName, std::list& 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); + setOfPorts.push_back(ret); + return ret; + } + + template + bool ElementaryNode::edCheckAddPort(const std::string& portName, std::list& 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); + } + return true; + } + + /** + * protected: remove a port from a given list + */ + + template + void ElementaryNode::edRemovePortTypedFromSet(PORT *port, std::list& setOfPorts) throw(Exception) + { + if(!isPortNameAlreadyExist(port->getName(), setOfPorts)) + throw Exception("Port is not part of the list : unable to remove it"); + typename std::list::iterator iter=std::find(setOfPorts.begin(),setOfPorts.end(),port); + if(iter!=setOfPorts.end()) + { + (*iter)->edRemoveAllLinksLinkedWithMe(); + setOfPorts.erase(iter); + } + } + + /** + * protected: checks existence of a port, given it's name, in a list + */ + + template + bool ElementaryNode::isPortNameAlreadyExist(const std::string& portName, const std::list& setOfPorts) + { + for(typename std::list::const_iterator iter=setOfPorts.begin();iter!=setOfPorts.end();iter++) + { + if((*iter)->getName()==portName) + return true; + } + return false; + } } } diff --git a/src/engine/Executor.cxx b/src/engine/Executor.cxx index f9f8f3669..9cabe6c6f 100644 --- a/src/engine/Executor.cxx +++ b/src/engine/Executor.cxx @@ -1,8 +1,15 @@ #include "Executor.hxx" #include "Task.hxx" #include "Scheduler.hxx" -#include +#include "Dispatcher.hxx" + +#include "VisitorSaveState.hxx" +#include "ComposedNode.hxx" + #include +#include +#include +#include using namespace YACS::ENGINE; using namespace std; @@ -11,8 +18,21 @@ using YACS::BASES::Mutex; using YACS::BASES::Thread; using YACS::BASES::Semaphore; -Executor::Executor():_nbOfConcurrentThreads(0)//,_cond(PTHREAD_COND_INITIALIZER) +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +Executor::Executor():_nbOfConcurrentThreads(0), _semForMaxThreads(50) { + _root=0; + _toContinue = true; + _isOKToEnd = false; + _stopOnErrorRequested = false; + _dumpOnErrorRequested = false; + _errorDetected = false; + _isRunningunderExternalControl=false; + _executorState = YACS::NOTYETINITIALIZED; + _execMode = YACS::CONTINUE; + _semThreadCnt = 50; } Executor::~Executor() @@ -21,65 +41,857 @@ Executor::~Executor() delete *iter; } -void Executor::RunW(Scheduler *graph) +//! Execute a graph waiting for completion +/*! + * \param graph : schema to execute + * \param debug : display the graph with dot if debug == 1 + * + * Calls Scheduler::getNextTasks and Scheduler::selectRunnableTasks to select tasks to execute + * + * Calls Executor::launchTask to execute a selected Task. + * + * Completion when graph is finished (Scheduler::isFinished) + */ + +void Executor::RunA(Scheduler *graph,int debug, bool fromScratch) { + DEBTRACE("Executor::RunW debug: " << debug << " fromScratch: " << fromScratch); _mainSched=graph; + _root = dynamic_cast(_mainSched); + if (!_root) throw Exception("Executor::Run, Internal Error!"); bool isMore; int i=0; - graph->init(); + if(debug>1)_displayDot(graph); + if (fromScratch) + { + graph->init(); + graph->exUpdateState(); + } + if(debug>1)_displayDot(graph); vector tasks; vector::iterator iter; - bool toContinue=true; - wakeUp(); - while(toContinue) + _toContinue=true; + _execMode = YACS::CONTINUE; + _isWaitingEventsFromRunningTasks = false; + _numberOfRunningTasks = 0; + while(_toContinue) { sleepWhileNoEventsFromAnyRunningTask(); + + if(debug>2)_displayDot(graph); + {//Critical section - _mutexForSchedulerUpdate.lock(); - tasks=graph->getNextTasks(isMore); - graph->selectRunnableTasks(tasks); - _mutexForSchedulerUpdate.unlock(); + _mutexForSchedulerUpdate.lock(); + tasks=graph->getNextTasks(isMore); + graph->selectRunnableTasks(tasks); + _mutexForSchedulerUpdate.unlock(); }//End of critical section + + if(debug>2)_displayDot(graph); + for(iter=tasks.begin();iter!=tasks.end();iter++) - launchTask(*iter); + loadTask(*iter); + + if(debug>1)_displayDot(graph); + + launchTasks(tasks); + + if(debug>1)_displayDot(graph); + {//Critical section - _mutexForSchedulerUpdate.lock(); - toContinue=!graph->isFinished(); - _mutexForSchedulerUpdate.unlock(); + _mutexForSchedulerUpdate.lock(); + _toContinue=!graph->isFinished(); + _mutexForSchedulerUpdate.unlock(); }//End of critical section + DEBTRACE("_toContinue: " << _toContinue); + + if(debug>0)_displayDot(graph); + i++; } } +//! Execute a graph with breakpoints or step by step +/*! + * To be launch in a thread (main thread controls the progression). + * \param graph : schema to execute + * \param debug : display the graph with dot if debug >0 + * \param fromscratch : if false, state from a previous partial exection is already loaded + * + * Calls Scheduler::getNextTasks and Scheduler::selectRunnableTasks to select tasks to execute + * + * Calls Executor::checkBreakPoints to verify if a pause is requested + * + * Calls Executor::launchTask to execute a selected Task + * + * Completion when graph is finished (Scheduler::isFinished) + * + * States of execution: + * - YACS::NOTYETINITIALIZED + * - YACS::INITIALISED + * - YACS::RUNNING (to next breakpoint or step) + * - YACS::WAITINGTASKS (a breakpoint or step as been reached, but there are still running tasks) + * - YACS::PAUSED (a breakpoint or step as been reached, no more running tasks) + * - YACS::FINISHED (no more ready tasks, nore running tasks) + * - YACS::STOPPED (stopped by user before end) + * + * Modes of Execution: + * - YACS::CONTINUE (normal run without breakpoints) + * - YACS::STEPBYSTEP (pause at each loop) + * - YACS::STOPBEFORENODES (pause when a node is reached) + * + * A breakpoint is defined by a node name. The breakpoint is reached when the node becomes ready. + * Step by Step means execution node by node or group of node by group of nodes. + * At a given step, the user decides to launch all the ready nodes or only a subset + * (Caution: some nodes must run in parallel). + * The next event (end of task) may give a new set of ready nodes, and define a new step. + * + * The graph execution may be controled by a pilot which sends requests. Requests are asynchronous. + * Requests are taken into account only on certain states, otherwise return the status IgnoredRequest. + * - Executor::getCurrentExecMode + * - Executor::getExecutorState + * - Executor::setExecMode : change the execution mode for next loop + * - Executor::setListOfBreakPoints : must be set before setting YACS::STOPBEFORENODES + * - Executor::getTasksToLoad : when paused or waiting tasks, get the list of next tasks + * - Executor::setStepsToExecute : define a subset of the list given by Executor::getTasksToLoad + * - Executor::resumeCurrentBreakPoint : when paused or waiting tasks, resumes execution + * - Executor::isNotFinished + * - Executor::stopExecution : stop execution asap, i.e. set STEPBYSTEP and wait PAUSED + * - Executor::saveState : dump the current state of execution in an xml file + * - Executor::loadState : Not yet implemented + * - Executor::getNbOfThreads + * - Executor::displayDot + * - Executor::setStopOnError : ask to stop execution if a node is found in ERROR state + * + * If the pilot wants to wait the state YACS::PAUSED or YACS::WAITINGTASKS, synchronisation is obtained with: + * - Executor::waitPause + * + * TO BE VALIDATED: + * - Pilot may connect to executor during execution, or deconnect. + * - Several Pilots may be connected at the same time (for observation...) + * + */ + +void Executor::RunB(Scheduler *graph,int debug, bool fromScratch) +{ + DEBTRACE("Executor::RunB debug: "<< graph->getName() <<" "<< debug<<" fromScratch: "<(_mainSched); + if (!_root) throw Exception("Executor::Run, Internal Error!"); + _executorState = YACS::NOTYETINITIALIZED; + sendEvent("executor"); + _toContinue=true; + _isOKToEnd = false; + _errorDetected = false; + _isWaitingEventsFromRunningTasks = false; + _numberOfRunningTasks = 0; + string tracefile = "traceExec_"; + tracefile += _mainSched->getName(); + _trace.open(tracefile.c_str()); + _mutexForSchedulerUpdate.unlock(); + } // --- End of critical section + + if (debug > 1) _displayDot(graph); + + if (fromScratch) + { + graph->init(); + graph->exUpdateState(); + } + _executorState = YACS::INITIALISED; + sendEvent("executor"); + + if (debug > 1) _displayDot(graph); + + vector::iterator iter; + bool isMore; + int problemCount=0; + int numberAllTasks; + + _executorState = YACS::RUNNING; + sendEvent("executor"); + while (_toContinue) + { + DEBTRACE("--- executor main loop"); + sleepWhileNoEventsFromAnyRunningTask(); + DEBTRACE("--- events..."); + if (debug > 2) _displayDot(graph); + { // --- Critical section + _mutexForSchedulerUpdate.lock(); + _tasks=graph->getNextTasks(isMore); + numberAllTasks=_numberOfRunningTasks+_tasks.size(); + graph->selectRunnableTasks(_tasks); + _mutexForSchedulerUpdate.unlock(); + } // --- End of critical section + if (debug > 2) _displayDot(graph); + if (_executorState == YACS::RUNNING) + { + if (checkBreakPoints()) break; // end of thread requested, OK to exit at once; + if (debug > 0) _displayDot(graph); + DEBTRACE("---"); + for (iter = _tasks.begin(); iter != _tasks.end(); iter++) + loadTask(*iter); + if (debug > 1) _displayDot(graph); + DEBTRACE("---"); + launchTasks(_tasks); + DEBTRACE("---"); + } + if (debug > 1) _displayDot(graph); + { // --- Critical section + DEBTRACE("---"); + _mutexForSchedulerUpdate.lock(); + _toContinue = !graph->isFinished(); + + if(_toContinue && numberAllTasks==0) + { + //Problem : no running tasks and no task to launch ?? + problemCount++; + std::cerr << "Problem in Executor : no running tasks and no task to launch ?? problemCount=" << problemCount << std::endl; + //Pause to give a chance to interrupt + usleep(1000); + if(problemCount > 25) + { + // Too much problems encountered : stop execution + _toContinue=false; + } + } + + if (! _toContinue) + { + _executorState = YACS::FINISHED; + sendEvent("executor"); + _condForPilot.notify_all(); + } + _mutexForSchedulerUpdate.unlock(); + } // --- End of critical section + if (debug > 0) _displayDot(graph); + DEBTRACE("_toContinue: " << _toContinue); + } + + DEBTRACE("End of main Loop"); + + { // --- Critical section + _mutexForSchedulerUpdate.lock(); + if ( _toContinue) // --- break while(): request to stop detected on checkBreakPoints() + { + DEBTRACE("stop requested: End soon"); + _executorState = YACS::STOPPED; + _toContinue = false; + sendEvent("executor"); + } + _mutexForSchedulerUpdate.unlock(); + } // --- End of critical section + if ( _dumpOnErrorRequested && _errorDetected && !_isRunningunderExternalControl) + { + saveState(_dumpErrorFile); + } + _trace.close(); + DEBTRACE("End of RunB thread"); +} + +YACS::ExecutionMode Executor::getCurrentExecMode() +{ + _isRunningunderExternalControl=true; + return _execMode; +} + + +YACS::ExecutorState Executor::getExecutorState() +{ + _isRunningunderExternalControl=true; + return _executorState; +} + + +bool Executor::isNotFinished() +{ + _isRunningunderExternalControl=true; + return _toContinue; +} + +//! ask to stop execution on the first node found in error +/*! + * \param dumpRequested produce a state dump when an error is found + * \param xmlFile name of file used for state dump + */ + +void Executor::setStopOnError(bool dumpRequested, std::string xmlFile) +{ + { // --- Critical section + _mutexForSchedulerUpdate.lock(); + _dumpErrorFile=xmlFile; + _stopOnErrorRequested=true; + _dumpOnErrorRequested = dumpRequested; + if (dumpRequested && xmlFile.empty()) + throw YACS::Exception("dump on error requested and no filename given for dump"); + _mutexForSchedulerUpdate.unlock(); + } // --- End of critical section +} + +//! Dynamically set the current mode of execution +/*! + * The mode can be Continue, step by step, or stop before execution of a node + * defined in a list of breakpoints. + */ + +void Executor::setExecMode(YACS::ExecutionMode mode) +{ + DEBTRACE("Executor::setExecMode(YACS::ExecutionMode mode) " << mode); + { // --- Critical section + _mutexForSchedulerUpdate.lock(); + _isRunningunderExternalControl=true; + _execMode = mode; + _mutexForSchedulerUpdate.unlock(); + } // --- End of critical section +} + +//! wake up executor when in pause +/*! + * When Executor is in state paused or waiting for task completion, the thread + * running loop RunB waits on condition _condForStepByStep. + * Thread RunB is waken up. + * \return true when actually wakes up executor + */ + +bool Executor::resumeCurrentBreakPoint() +{ + DEBTRACE("Executor::resumeCurrentBreakPoint()"); + bool ret = false; + //bool doDump = false; + { // --- Critical section + _mutexForSchedulerUpdate.lock(); + _isRunningunderExternalControl=true; + DEBTRACE("_executorState: " << _executorState); + switch (_executorState) + { + case YACS::WAITINGTASKS: + case YACS::PAUSED: + { + _condForStepByStep.notify_all(); + _executorState = YACS::RUNNING; + sendEvent("executor"); + ret = true; + //if (_dumpOnErrorRequested && _errorDetected) doDump =true; + break; + } + case YACS::FINISHED: + case YACS::STOPPED: + { + //if (_dumpOnErrorRequested && _errorDetected) doDump =true; + DEBTRACE("Graph Execution finished or stopped !"); + break; + } + default : + { + // debug: no easy way to verify if main loop is acutally waiting on condition + } + } + _mutexForSchedulerUpdate.unlock(); + DEBTRACE("---"); + //if (doDump) saveState(_dumpErrorFile); + } // --- End of critical section + return ret; +} + + +//! define a list of nodes names as breakpoints in the graph + + +void Executor::setListOfBreakPoints(std::list listOfBreakPoints) +{ + DEBTRACE("Executor::setListOfBreakPoints(std::list listOfBreakPoints)"); + { // --- Critical section + _mutexForSchedulerUpdate.lock(); + _isRunningunderExternalControl=true; + _listOfBreakPoints = listOfBreakPoints; + _mutexForSchedulerUpdate.unlock(); + } // --- End of critical section +} + + +//! Get the list of tasks to load, to define a subset to execute in step by step mode +/*! + * If the executor is not in mode YACS::WAITINGTASKS nor YACS::PAUSED, the list is empty. + * Use Executor::waitPause to wait. + */ +std::list Executor::getTasksToLoad() +{ + DEBTRACE("Executor::getTasksToLoad()"); + list listOfNodesToLoad; + listOfNodesToLoad.clear(); + { // --- Critical section + _mutexForSchedulerUpdate.lock(); + _isRunningunderExternalControl=true; + switch (_executorState) + { + case YACS::WAITINGTASKS: + case YACS::PAUSED: + { + listOfNodesToLoad = _listOfTasksToLoad; + break; + } + case YACS::NOTYETINITIALIZED: + case YACS::INITIALISED: + case YACS::RUNNING: + case YACS::FINISHED: + case YACS::STOPPED: + default: + { + break; + } + } + _mutexForSchedulerUpdate.unlock(); + } // --- End of critical section + return listOfNodesToLoad; +} + + +//! Define a subset of task to execute in step by step mode +/*! + * Behaviour is unpredictable if the list is not a subset of the list given by Executor::getTasksToLoad + * in the current step. + * If some nodes must run in parallel, they must stay together in the list. + */ + +bool Executor::setStepsToExecute(std::list listToExecute) +{ + DEBTRACE("Executor::setStepsToExecute(std::list listToExecute)"); + bool ret = false; + vector::iterator iter; + vector restrictedTasks; + { // --- Critical section + _mutexForSchedulerUpdate.lock(); + _isRunningunderExternalControl=true; + switch (_executorState) + { + case YACS::WAITINGTASKS: + case YACS::PAUSED: + { + for (iter=_tasksSave.begin(); iter!=_tasksSave.end(); iter++) + { + string readyNode = _mainSched->getTaskName(*iter); + if (find(listToExecute.begin(), listToExecute.end(), readyNode) + != listToExecute.end()) + { + restrictedTasks.push_back(*iter); + DEBTRACE("node to execute " << readyNode); + } + } + _tasks.clear(); + for (iter=restrictedTasks.begin(); iter!=restrictedTasks.end(); iter++) + { + _tasks.push_back(*iter); + } + break; + } + case YACS::NOTYETINITIALIZED: + case YACS::INITIALISED: + case YACS::RUNNING: + case YACS::FINISHED: + case YACS::STOPPED: + default: + { + break; + } + } + _mutexForSchedulerUpdate.unlock(); + } // --- End of critical section + + _tasks.clear(); + for (iter=restrictedTasks.begin(); iter!=restrictedTasks.end(); iter++) + { + _tasks.push_back(*iter); + } + for (iter=_tasks.begin(); iter!=_tasks.end(); iter++) + { + string readyNode = _mainSched->getTaskName(*iter); + DEBTRACE("selected node to execute " << readyNode); + } + +} + +//! suspend pilot execution until Executor is in pause or waiting tasks completion mode. +/*! + * Do nothing if execution is finished or in pause. + * Wait first step if Executor is running or in initialization. + */ + +void Executor::waitPause() +{ + DEBTRACE("Executor::waitPause()"); + { // --- Critical section + _mutexForSchedulerUpdate.lock(); + _isRunningunderExternalControl=true; + switch (_executorState) + { + default: + case YACS::STOPPED: + case YACS::FINISHED: + case YACS::WAITINGTASKS: + case YACS::PAUSED: + { + break; + } + case YACS::NOTYETINITIALIZED: + case YACS::INITIALISED: + case YACS::RUNNING: + { + _condForPilot.wait(_mutexForSchedulerUpdate); // wait until executor is PAUSED or WAITINGTASKS + break; + } + } + _mutexForSchedulerUpdate.unlock(); + } // --- End of critical section + DEBTRACE("---"); +} + +//! stops the execution as soon as possible + +void Executor::stopExecution() +{ + setExecMode(YACS::STEPBYSTEP); + //waitPause(); + _isOKToEnd = true; + resumeCurrentBreakPoint(); +} + +//! save the current state of execution in an xml file + +bool Executor::saveState(const std::string& xmlFile) +{ + DEBTRACE("Executor::saveState() in " << xmlFile); + YACS::ENGINE::VisitorSaveState vst(_root); + vst.openFileDump(xmlFile.c_str()); + _root->accept(&vst); + vst.closeFileDump(); +} + +//! not yet implemented + +bool Executor::loadState() +{ + DEBTRACE("Executor::loadState()"); + _isRunningunderExternalControl=true; +} + + +static int isfile(char *filename) +{ + struct stat buf; + if (stat(filename, &buf) != 0) + return 0; + if (!S_ISREG(buf.st_mode)) + return 0; + return 1; +} + +//! Display the graph state as a dot display, public method + +void Executor::displayDot(Scheduler *graph) +{ + _isRunningunderExternalControl=true; + _displayDot(graph); +} + +//! Display the graph state as a dot display +/*! + * \param graph : the node to display + */ + +void Executor::_displayDot(Scheduler *graph) +{ + std::ofstream g("titi"); + ((ComposedNode*)graph)->writeDot(g); + g.close(); + if(isfile("display.sh")) + system("sh display.sh"); + else + system("dot -Tpng titi|display -delay 5"); +} + +//! Wait reactivation in modes Step By step or with BreakPoints +/*! + * Check mode of execution (set by main thread): + * - YACS::CONTINUE : the graph execution continues. + * - YACS::STEPBYSTEP : wait on condition (pilot thread, Executor::resumeCurrentBreakPoint) + * - YACS::STOPBEFORENODES : if there are ready nodes in a list of breakpoints, + * wait on condition (pilot thread, Executor::resumeCurrentBreakPoint) + * else continue the graph execution. + * \return true if end of executor thread is requested + */ + +bool Executor::checkBreakPoints() +{ + DEBTRACE("Executor::checkBreakPoints()"); + vector::iterator iter; + bool endRequested = false; + + switch (_execMode) + { + case YACS::CONTINUE: + { + break; + } + case YACS::STOPBEFORENODES: + { + bool stop = false; + { // --- Critical section + _mutexForSchedulerUpdate.lock(); + _tasksSave = _tasks; + for (iter=_tasks.begin(); iter!=_tasks.end(); iter++) + { + string nodeToLoad = _mainSched->getTaskName(*iter); + if (find(_listOfBreakPoints.begin(), _listOfBreakPoints.end(), nodeToLoad) + != _listOfBreakPoints.end()) + { + stop = true; + break; + } + } + if (stop) + { + _listOfTasksToLoad.clear(); + for (iter=_tasks.begin(); iter!=_tasks.end(); iter++) + { + string nodeToLoad = _mainSched->getTaskName(*iter); + _listOfTasksToLoad.push_back(nodeToLoad); + } + if (getNbOfThreads()) + _executorState = YACS::WAITINGTASKS; // will be paused after completion of running tasks + else + _executorState = YACS::PAUSED; + sendEvent("executor"); + _condForPilot.notify_all(); + } + //_mutexForSchedulerUpdate.unlock(); + //} // --- End of critical section + if (stop && !_isOKToEnd) waitResume(); // wait until pilot calls resumeCurrentBreakPoint(), mutex released during wait + if (_isOKToEnd) endRequested = true; + _mutexForSchedulerUpdate.unlock(); + } // --- End of critical section + if (stop) DEBTRACE("wake up from waitResume"); + break; + } + default: + case YACS::STEPBYSTEP: + { + { // --- Critical section + _mutexForSchedulerUpdate.lock(); + _tasksSave = _tasks; + _listOfTasksToLoad.clear(); + for (iter=_tasks.begin(); iter!=_tasks.end(); iter++) + { + string nodeToLoad = _mainSched->getTaskName(*iter); + _listOfTasksToLoad.push_back(nodeToLoad); + } + if (getNbOfThreads()) + _executorState = YACS::WAITINGTASKS; // will be paused after completion of running tasks + else + _executorState = YACS::PAUSED; + sendEvent("executor"); + _condForPilot.notify_all(); + if (!_isOKToEnd) + waitResume(); // wait until pilot calls resumeCurrentBreakPoint(), mutex released during wait + // or, if no pilot, wait until no more running tasks (stop on error) + if (_isOKToEnd) endRequested = true; + _mutexForSchedulerUpdate.unlock(); + } // --- End of critical section + DEBTRACE("wake up from waitResume"); + break; + } + } + DEBTRACE("endRequested: " << endRequested); + return endRequested; +} + + +//! in modes Step By step or with BreakPoint, wait until pilot resumes the execution +/*! + * With the condition Mutex, the mutex is released atomically during the wait. + * Pilot calls Executor::resumeCurrentBreakPoint to resume execution. + * Must be called while mutex is locked. + */ + +void Executor::waitResume() +{ + DEBTRACE("Executor::waitResume()"); + _condForStepByStep.wait(_mutexForSchedulerUpdate); // wait until pilot calls resumeCurrentBreakPoint() + DEBTRACE("---"); +} + + +//! Perform loading of a Task. +/*! + * \param task : Task to load + */ + +void Executor::loadTask(Task *task) +{ + DEBTRACE("Executor::loadTask(Task *task)"); + if(task->getState() != YACS::TOLOAD)return; + {//Critical section + _mutexForSchedulerUpdate.lock(); + task->loaded(); + _mainSched->notifyFrom(task,YACS::START); + _mutexForSchedulerUpdate.unlock(); + }//End of critical section + try + { + task->load(); + } + catch(Exception& ex) + { + std::cerr << ex.what() << std::endl; + {//Critical section + _mutexForSchedulerUpdate.lock(); + task->aborted(); + _mainSched->notifyFrom(task,YACS::ABORT); + _mutexForSchedulerUpdate.unlock(); + }//End of critical section + } + catch(...) + { + std::cerr << "Load failed" << std::endl; + {//Critical section + _mutexForSchedulerUpdate.lock(); + task->aborted(); + _mainSched->notifyFrom(task,YACS::ABORT); + _mutexForSchedulerUpdate.unlock(); + }//End of critical section + } +} + + +//! Execute a list of tasks possibly connected through datastream links +/*! + * \param tasks : a list of tasks to execute + * + */ +void Executor::launchTasks(std::vector& tasks) +{ + vector::iterator iter; + //First phase, initialize the execution + for(iter=tasks.begin();iter!=tasks.end();iter++) + { + if((*iter)->getState() != YACS::TOACTIVATE)continue; + try + { + (*iter)->initService(); + traceExec(*iter, "initService"); + } + catch(Exception& ex) + { + std::cerr << ex.what() << std::endl; + {//Critical section + _mutexForSchedulerUpdate.lock(); + (*iter)->aborted(); + _mainSched->notifyFrom(*iter,YACS::ABORT); + _mutexForSchedulerUpdate.unlock(); + }//End of critical section + } + catch(...) + { + std::cerr << "Problem in initService" << std::endl; + {//Critical section + _mutexForSchedulerUpdate.lock(); + (*iter)->aborted(); + _mainSched->notifyFrom(*iter,YACS::ABORT); + _mutexForSchedulerUpdate.unlock(); + }//End of critical section + } + } + //Second phase, make datastream connections + for(iter=tasks.begin();iter!=tasks.end();iter++) + { + if((*iter)->getState() != YACS::TOACTIVATE)continue; + try + { + (*iter)->connectService(); + traceExec(*iter, "connectService"); + } + catch(Exception& ex) + { + std::cerr << ex.what() << std::endl; + {//Critical section + _mutexForSchedulerUpdate.lock(); + (*iter)->aborted(); + _mainSched->notifyFrom(*iter,YACS::ABORT); + _mutexForSchedulerUpdate.unlock(); + }//End of critical section + } + catch(...) + { + std::cerr << "Problem in connectService" << std::endl; + {//Critical section + _mutexForSchedulerUpdate.lock(); + (*iter)->aborted(); + _mainSched->notifyFrom(*iter,YACS::ABORT); + _mutexForSchedulerUpdate.unlock(); + }//End of critical section + } + } + //Third phase, execute each task in a thread + for(iter=tasks.begin();iter!=tasks.end();iter++) + { + DEBTRACE("before _semForMaxThreads.wait " << _semThreadCnt); + _semForMaxThreads.wait(); + _semThreadCnt -= 1; + launchTask(*iter); + } +} + +//! Execute a Task in a thread +/*! + * \param task : Task to execute + * + * Calls Scheduler::notifyFrom of main node (_mainSched) to notify start + * + * Calls Executor::functionForTaskExecution in Thread + */ + void Executor::launchTask(Task *task) { + DEBTRACE("Executor::launchTask(Task *task)"); + if(task->getState() != YACS::TOACTIVATE)return; void **args=new void *[3]; - _mutexForNbOfConcurrentThreads.lock(); - _groupOfAllThreadsCreated.push_back(0); - list::iterator iter=_groupOfAllThreadsCreated.end(); - iter--; - _mutexForNbOfConcurrentThreads.unlock(); args[0]=(void *)task; args[1]=(void *)_mainSched; args[2]=(void *)this; - {//Critical section + traceExec(task, "launch"); + + { // --- Critical section _mutexForSchedulerUpdate.lock(); - task->begin(); - _mainSched->notifyFrom(task,YACS::START); + _numberOfRunningTasks++; + task->begin(); //change state to ACTIVATED + //no more need : done when loading + //_mainSched->notifyFrom(task,YACS::START); _mutexForSchedulerUpdate.unlock(); - }//End of critical section - _mutexForNbOfConcurrentThreads.lock(); - //functionForTaskExecution(args);//MultiThreaded=NO - // *iter= - new Thread(functionForTaskExecution,args);//MultiThreaded=YES - _mutexForNbOfConcurrentThreads.unlock(); + } // --- End of critical section + Thread(functionForTaskExecution,args); + //functionForTaskExecution(args); } +//! wait until a running task ends + void Executor::sleepWhileNoEventsFromAnyRunningTask() { - _semForNewTasksToPerform.wait(); + DEBTRACE("Executor::sleepWhileNoEventsFromAnyRunningTask()"); +// _semForNewTasksToPerform.wait(); //----utiliser pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); + _mutexForSchedulerUpdate.lock(); + if (_numberOfRunningTasks > 0) + { + _isWaitingEventsFromRunningTasks = true; + _condForNewTasksToPerform.wait(_mutexForSchedulerUpdate); // mutex released during wait + } + _mutexForSchedulerUpdate.unlock(); + DEBTRACE("---"); } +//! not implemented + void Executor::notifyEndOfThread(YACS::BASES::Thread *thread) { /*_mutexForNbOfConcurrentThreads.lock(); @@ -88,37 +900,174 @@ void Executor::notifyEndOfThread(YACS::BASES::Thread *thread) _mutexForNbOfConcurrentThreads.unlock();*/ } + +//! must be used protected by _mutexForSchedulerUpdate! + void Executor::wakeUp() { - int val=_semForNewTasksToPerform.getValue(); - if(!val) - _semForNewTasksToPerform.post(); + DEBTRACE("Executor::wakeUp()"); + if (_isWaitingEventsFromRunningTasks) + { + _isWaitingEventsFromRunningTasks = false; + _condForNewTasksToPerform.notify_all(); + } } +//! number of running tasks + int Executor::getNbOfThreads() { int ret; _mutexForNbOfConcurrentThreads.lock(); - ret=_groupOfAllThreadsCreated.size(); + _isRunningunderExternalControl=true; + ret = _groupOfAllThreadsCreated.size(); _mutexForNbOfConcurrentThreads.unlock(); return ret; } + +//! Function to perform execution of a task in a thread +/*! + * \param arg : 3 elements (a Task, a Scheduler, an Executor) + * + * Calls Task::execute + * + * Calls Task::finished when the task is finished + * + * Calls (notify with event YACS::FINISH) Scheduler::notifyFrom when the task is finished + * + * Calls Executor::wakeUp and Executor::notifyEndOfThread + */ + void *Executor::functionForTaskExecution(void *arg) { + DEBTRACE("Executor::functionForTaskExecution(void *arg)"); void **argT=(void **)arg; Task *task=(Task *)argT[0]; Scheduler *sched=(Scheduler *)argT[1]; Executor *execInst=(Executor *)argT[2]; delete [] argT; - task->execute(); - {//Critical section + Thread::detach(); + + // Execute task + + YACS::Event ev=YACS::FINISH; + try + { + execInst->traceExec(task, "start execution"); + task->execute(); + execInst->traceExec(task, "end execution OK"); + } + catch(Exception& ex) + { + std::cerr << "YACS Exception during execute" << std::endl; + std::cerr << ex.what() << std::endl; + ev=YACS::ABORT; + string message = "end execution ABORT, "; + message += ex.what(); + execInst->traceExec(task, message); + } + catch(...) + { + // Execution has failed + std::cerr << "Execution has failed: unknown reason" << std::endl; + ev=YACS::ABORT; + execInst->traceExec(task, "end execution ABORT, unknown reason"); + } + + // Disconnect task + try + { + task->disconnectService(); + execInst->traceExec(task, "disconnectService"); + } + catch(...) + { + // Disconnect has failed + std::cerr << "disconnect has failed" << std::endl; + ev=YACS::ABORT; + execInst->traceExec(task, "disconnectService failed, ABORT"); + } + + DEBTRACE("End task->execute()"); + { // --- Critical section execInst->_mutexForSchedulerUpdate.lock(); - task->finished(); - sched->notifyFrom(task,YACS::FINISH); + try + { + if (ev == YACS::FINISH) task->finished(); + if (ev == YACS::ABORT) + { + execInst->_errorDetected = true; + if (execInst->_stopOnErrorRequested) + { + execInst->_execMode = YACS::STEPBYSTEP; + if (!execInst->_isRunningunderExternalControl) execInst->_isOKToEnd = true; + } + task->aborted(); + } + sched->notifyFrom(task,ev); + } + catch(Exception& ex) + { + //notify has failed : it is supposed to have set state + //so no need to do anything + std::cerr << "Error during notification" << std::endl; + std::cerr << ex.what() << std::endl; + } + catch(...) + { + //notify has failed : it is supposed to have set state + //so no need to do anything + std::cerr << "Notification failed" << std::endl; + } + execInst->_numberOfRunningTasks--; + DEBTRACE("_numberOfRunningTasks: " << execInst->_numberOfRunningTasks + << " _execMode: " << execInst->_execMode + << " _executorState: " << execInst->_executorState); + if ((execInst->_numberOfRunningTasks == 0) && (execInst->_execMode != YACS::CONTINUE)) // no more running tasks + { + if (execInst->_executorState == YACS::WAITINGTASKS) + { + execInst->_executorState = YACS::PAUSED; + execInst->sendEvent("executor"); + execInst->_condForPilot.notify_all(); + if (execInst->_errorDetected && + execInst->_stopOnErrorRequested && + !execInst->_isRunningunderExternalControl) + execInst->_condForStepByStep.notify_all(); // exec thread may be on waitResume + } + } + DEBTRACE("before _semForMaxThreads.post " << execInst->_semThreadCnt); + execInst->_semForMaxThreads.post(); + execInst->_semThreadCnt += 1; + DEBTRACE("after _semForMaxThreads.post " << execInst->_semThreadCnt); + if (execInst->_executorState != YACS::PAUSED) execInst->wakeUp(); + execInst->_mutexForSchedulerUpdate.unlock(); - }//End of critical section - execInst->wakeUp(); - execInst->notifyEndOfThread(0); + } // --- End of critical section (change state) + + //execInst->notifyEndOfThread(0); + Thread::exit(0); return 0; } + +void Executor::traceExec(Task *task, const std::string& message) +{ + string nodeName = _mainSched->getTaskName(task); + _mutexForTrace.lock(); + _trace << nodeName << " " << message << endl; + _trace << flush; + _mutexForTrace.unlock(); +} + +//! emit notification to all observers registered with the dispatcher +/*! + * The dispatcher is unique and can be obtained by getDispatcher() + */ +void Executor::sendEvent(const std::string& event) +{ + Dispatcher* disp=Dispatcher::getDispatcher(); + assert(disp); + assert(_root); + disp->dispatch(_root,event); +} diff --git a/src/engine/Executor.hxx b/src/engine/Executor.hxx index 9337cc03a..233e23278 100644 --- a/src/engine/Executor.hxx +++ b/src/engine/Executor.hxx @@ -4,36 +4,92 @@ #include "Mutex.hxx" #include "Thread.hxx" #include "Semaphore.hxx" +#include "Exception.hxx" +#include "define.hxx" #include +#include +#include +#include namespace YACS { namespace ENGINE { class Scheduler; + class ComposedNode; class Task; +/*! \brief Threaded Executor + * + * \ingroup Executors + * + * + */ class Executor { protected: Scheduler *_mainSched; + ComposedNode *_root; int _nbOfConcurrentThreads; YACS::BASES::Mutex _mutexForNbOfConcurrentThreads; - YACS::BASES::Semaphore _semForNewTasksToPerform; + YACS::BASES::Condition _condForNewTasksToPerform; + YACS::BASES::Semaphore _semForMaxThreads; + YACS::BASES::Condition _condForStepByStep; + YACS::BASES::Condition _condForPilot; YACS::BASES::Mutex _mutexForSchedulerUpdate; - pthread_cond_t _cond; + YACS::BASES::Mutex _mutexForTrace; + bool _toContinue; + bool _isOKToEnd; + bool _stopOnErrorRequested; + bool _dumpOnErrorRequested; + bool _errorDetected; + bool _isRunningunderExternalControl; + bool _isWaitingEventsFromRunningTasks; + int _numberOfRunningTasks; + int _semThreadCnt; + YACS::ExecutorState _executorState; + YACS::ExecutionMode _execMode; + std::list _listOfBreakPoints; + std::list _listOfTasksToLoad; + std::vector _tasks; + std::vector _tasksSave; std::list< YACS::BASES::Thread * > _groupOfAllThreadsCreated; + std::ofstream _trace; + std::string _dumpErrorFile; public: Executor(); ~Executor(); - void RunW(Scheduler *graph); + void RunA(Scheduler *graph,int debug=0, bool fromScratch=true); + void RunW(Scheduler *graph,int debug=0, bool fromScratch=true) { RunB(graph, debug, fromScratch); } + void RunB(Scheduler *graph,int debug=0, bool fromScratch=true); + YACS::ExecutionMode getCurrentExecMode(); + YACS::ExecutorState getExecutorState(); + void setExecMode(YACS::ExecutionMode mode); + void setListOfBreakPoints(std::list listOfBreakPoints); + std::list getTasksToLoad(); + bool setStepsToExecute(std::list listToExecute); + bool resumeCurrentBreakPoint(); + bool isNotFinished(); + void stopExecution(); + bool saveState(const std::string& xmlFile); + bool loadState(); int getNbOfThreads(); + void displayDot(Scheduler *graph); + void setStopOnError(bool dumpRequested=false, std::string xmlFile=""); + void waitPause(); protected: + bool checkBreakPoints(); + void waitResume(); + void loadTask(Task *task); + void launchTasks(std::vector& tasks); void launchTask(Task *task); void wakeUp(); void sleepWhileNoEventsFromAnyRunningTask(); void notifyEndOfThread(YACS::BASES::Thread *thread); + void traceExec(Task *task, const std::string& message); + void _displayDot(Scheduler *graph); + virtual void sendEvent(const std::string& event); protected: static void *functionForTaskExecution(void *); }; diff --git a/src/engine/ExecutorSwig.cxx b/src/engine/ExecutorSwig.cxx new file mode 100644 index 000000000..b426ce8ea --- /dev/null +++ b/src/engine/ExecutorSwig.cxx @@ -0,0 +1,47 @@ +#include +#include "ExecutorSwig.hxx" +#include "Scheduler.hxx" + +#include + +using namespace YACS::ENGINE; +using namespace std; + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +void ExecutorSwig::RunPy(Scheduler *graph,int debug, bool isPyThread, bool fromscratch) +{ + DEBTRACE("ExecutorSwig::RunPy(Scheduler *graph,int debug, bool isPyThread, bool fromscratch) " + << debug << " " << isPyThread << " " << fromscratch); + PyThreadState *_save; + if (isPyThread) _save = PyEval_SaveThread(); // allow Python threads when embedded in a Python thread + try + { + RunB(graph, debug, fromscratch); + } + catch (YACS::Exception& e) + { + DEBTRACE("YACS exception caught: "); + DEBTRACE(e.what()); + } + catch (const std::ios_base::failure&) + { + DEBTRACE("io failure"); + } + catch(...) + { + DEBTRACE("Caught unknown exception."); + } + if (isPyThread) PyEval_RestoreThread(_save); // restore thread state and lock at the end of Python thread +} + +void ExecutorSwig::waitPause() +{ + DEBTRACE("ExecutorSwig::waitPause()"); + PyThreadState *_save; + _save = PyEval_SaveThread(); // allow Python threads when embedded in a Python thread + Executor::waitPause(); + PyEval_RestoreThread(_save); // restore thread state and lock at the end of Python thread +} + diff --git a/src/engine/ExecutorSwig.hxx b/src/engine/ExecutorSwig.hxx new file mode 100644 index 000000000..b32059d92 --- /dev/null +++ b/src/engine/ExecutorSwig.hxx @@ -0,0 +1,22 @@ +#ifndef _EXECUTOR_SWIG_HXX_ +#define _EXECUTOR_SWIG_HXX_ + +#include "Executor.hxx" + +namespace YACS +{ + namespace ENGINE + { + class ExecutorSwig: public Executor + { + public: + void RunPy(Scheduler *graph, + int debug=0, + bool isPyThread = true, + bool fromscratch=true); + void waitPause(); + }; + } +} + +#endif diff --git a/src/engine/ForEachLoop.cxx b/src/engine/ForEachLoop.cxx new file mode 100644 index 000000000..b9b4484e0 --- /dev/null +++ b/src/engine/ForEachLoop.cxx @@ -0,0 +1,700 @@ +#include "ForEachLoop.hxx" +#include "Visitor.hxx" +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +const char FakeNodeForForEachLoop::NAME[]="thisIsAFakeNode"; + +const char SplitterNode::NAME_OF_SEQUENCE_INPUT[]="SmplsCollection"; + +const char ForEachLoop::NAME_OF_SPLITTERNODE[]="splitter"; + +const int ForEachLoop::NOT_RUNNING_BRANCH_ID=-1; + +InterceptorInputPort::InterceptorInputPort(const std::string& name, Node *node, TypeCode* type):AnyInputPort(name,node,type), + DataPort(name,node,type),Port(node), + _repr(0) +{ +} + +InterceptorInputPort::InterceptorInputPort(const InterceptorInputPort& other, Node *newHelder):AnyInputPort(other,newHelder),DataPort(other,newHelder), + Port(other,newHelder), + _repr(0) +{ +} + +void InterceptorInputPort::getAllRepresentants(std::set& repr) const +{ + set ports=_repr->edSetInPort(); + for(set::iterator iter=ports.begin();iter!=ports.end();iter++) + (*iter)->getAllRepresentants(repr); +} + +InputPort *InterceptorInputPort::clone(Node *newHelder) const +{ + return new InterceptorInputPort(*this,newHelder); +} + +void InterceptorInputPort::setRepr(AnySplitOutputPort *repr) +{ + _repr=repr; +} + +bool AnySplitOutputPort::decrRef() +{ + return (--_cnt==0); +} + +void AnySplitOutputPort::incrRef() const +{ + _cnt++; +} + +AnySplitOutputPort::AnySplitOutputPort(const std::string& name, Node *node, TypeCode *type):OutputPort(name,node,type), + DataPort(name,node,type),Port(node), + _repr(0),_intercptr(0),_cnt(1) +{ +} + +AnySplitOutputPort::AnySplitOutputPort(const AnySplitOutputPort& other, Node *newHelder):OutputPort(other,newHelder), + DataPort(other,newHelder), + Port(other,newHelder), + _repr(0),_intercptr(0),_cnt(1) +{ +} + +bool AnySplitOutputPort::addInPort(InPort *inPort) throw(Exception) +{ + bool ret=OutputPort::addInPort(inPort); + if(_repr) + _repr->addInPort(_intercptr); + return ret; +} + +void AnySplitOutputPort::getAllRepresented(std::set& represented) const +{ + if(!_repr) + OutPort::getAllRepresented(represented); + else + _repr->getAllRepresented(represented); +} + +int AnySplitOutputPort::removeInPort(InPort *inPort, bool forward) throw(Exception) +{ + bool ret=OutputPort::removeInPort(inPort,forward); + if(_repr) + _repr->removeInPort(_intercptr,forward); + return ret; +} + +void AnySplitOutputPort::addRepr(OutPort *repr, InterceptorInputPort *intercptr) +{ + _repr=repr; + _intercptr=intercptr; +} + +OutputPort *AnySplitOutputPort::clone(Node *newHelder) const +{ + return new AnySplitOutputPort(*this,newHelder); +} + +SeqAnyInputPort::SeqAnyInputPort(const std::string& name, Node *node, TypeCodeSeq* type):AnyInputPort(name,node,type),DataPort(name,node,type),Port(node) +{ + _type->decrRef(); +} + +SeqAnyInputPort::SeqAnyInputPort(const SeqAnyInputPort& other, Node *newHelder):AnyInputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder) +{ +} + +InputPort *SeqAnyInputPort::clone(Node *newHelder) const +{ + return new SeqAnyInputPort(*this,newHelder); +} + +unsigned SeqAnyInputPort::getNumberOfElements() const +{ + const SequenceAny * valCsted=(const SequenceAny *) _value; + return valCsted->size(); +} + +Any *SeqAnyInputPort::getValueAtRank(int i) const +{ + const SequenceAny * valCsted=(const SequenceAny *) _value; + AnyPtr ret=(*valCsted)[i]; + ret->incrRef(); + return ret; +} + +std::string SeqAnyInputPort::dump() +{ + stringstream xmldump; + int nbElem = getNumberOfElements(); + xmldump << "" << endl; + for (int i = 0; i < nbElem; i++) + { + Any *val = getValueAtRank(i); + switch (val->getType()->kind()) + { + case Double: + xmldump << "" << val->getDoubleValue() << "" << endl; + break; + case Int: + xmldump << "" << val->getIntValue() << "" << endl; + break; + case Bool: + xmldump << "" << val->getBoolValue() << "" << endl; + break; + case String: + xmldump << "" << val->getStringValue() << "" << endl; + break; + case Objref: + xmldump << "" << val->getStringValue() << "" << endl; + break; + default: + xmldump << " NO_SERIALISATION_AVAILABLE " << endl; + break; + } + } + xmldump << "" << endl; + return xmldump.str(); +} + +SplitterNode::SplitterNode(const std::string& name, TypeCode *typeOfData, + ForEachLoop *father):ElementaryNode(name), + _dataPortToDispatch(NAME_OF_SEQUENCE_INPUT, + this,new TypeCodeSeq("","",typeOfData)) +{ + _father=father; +} + +SplitterNode::SplitterNode(const SplitterNode& other, ForEachLoop *father):ElementaryNode(other,father), + _dataPortToDispatch(other._dataPortToDispatch,this) +{ +} + +InputPort *SplitterNode::getInputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_OF_SEQUENCE_INPUT) + return (InputPort *)&_dataPortToDispatch; + else + return ElementaryNode::getInputPort(name); +} + +Node *SplitterNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new SplitterNode(*this,(ForEachLoop *)father); +} + +unsigned SplitterNode::getNumberOfElements() const +{ + return _dataPortToDispatch.getNumberOfElements(); +} + +void SplitterNode::execute() +{ + //Nothing : should never been called elsewhere big problem... +} + +void SplitterNode::init(bool start) +{ + ElementaryNode::init(start); + _dataPortToDispatch.exInit(start); +} + +void SplitterNode::putSplittedValueOnRankTo(int rankInSeq, int branch, bool first) +{ + Any *valueToDispatch=_dataPortToDispatch.getValueAtRank(rankInSeq); + ForEachLoop *fatherTyped=(ForEachLoop *)_father; + fatherTyped->putValueOnBranch(valueToDispatch,branch,first); + valueToDispatch->decrRef(); +} + +FakeNodeForForEachLoop::FakeNodeForForEachLoop(ForEachLoop *loop, bool normalFinish):ElementaryNode(NAME), + _loop(loop), + _normalFinish(normalFinish) +{ + _state=YACS::TOACTIVATE; + _father=_loop->getFather(); +} + +FakeNodeForForEachLoop::FakeNodeForForEachLoop(const FakeNodeForForEachLoop& other):ElementaryNode(other),_loop(0), + _normalFinish(false) +{ +} + +Node *FakeNodeForForEachLoop::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new FakeNodeForForEachLoop(*this); +} + +void FakeNodeForForEachLoop::exForwardFailed() +{ + _loop->exForwardFailed(); + FakeNodeForForEachLoop *normallyThis=_loop->_nodeForSpecialCases; + _loop->_nodeForSpecialCases=0; + delete normallyThis; +} + +void FakeNodeForForEachLoop::exForwardFinished() +{ + _loop->exForwardFinished(); + FakeNodeForForEachLoop *normallyThis=_loop->_nodeForSpecialCases; + _loop->_nodeForSpecialCases=0; + delete normallyThis; +} + +void FakeNodeForForEachLoop::execute() +{ + if(!_normalFinish) + throw Exception("");//only to trigger ABORT on Executor + else + _loop->pushAllSequenceValues(); +} + +void FakeNodeForForEachLoop::aborted() +{ + _loop->setState(YACS::ERROR); +} + +void FakeNodeForForEachLoop::finished() +{ + _loop->setState(YACS::DONE); +} + +ForEachLoop::ForEachLoop(const std::string& name, TypeCode *typeOfDataSplitted):DynParaLoop(name,typeOfDataSplitted), + _splitterNode(NAME_OF_SPLITTERNODE,typeOfDataSplitted,this), + _execCurrentId(0),_nodeForSpecialCases(0) +{ +} + +ForEachLoop::ForEachLoop(const ForEachLoop& other, ComposedNode *father, bool editionOnly):DynParaLoop(other,father,editionOnly), + _splitterNode(other._splitterNode,this), + _execCurrentId(0),_nodeForSpecialCases(0) +{ + int i=0; + if(!editionOnly) + for(vector::const_iterator iter2=other._outGoingPorts.begin();iter2!=other._outGoingPorts.end();iter2++,i++) + { + AnySplitOutputPort *temp=new AnySplitOutputPort(*(*iter2),this); + InterceptorInputPort *interc=new InterceptorInputPort(*other._intecptrsForOutGoingPorts[i],this); + temp->addRepr(getOutPort((*iter2)->getName()),interc); + interc->setRepr(temp); + _outGoingPorts.push_back(temp); + _intecptrsForOutGoingPorts.push_back(interc); + } +} + +Node *ForEachLoop::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new ForEachLoop(*this,father,editionOnly); +} + +ForEachLoop::~ForEachLoop() +{ + cleanDynGraph(); + for(vector::iterator iter=_outGoingPorts.begin();iter!=_outGoingPorts.end();iter++) + delete *iter; + for(vector::iterator iter2=_intecptrsForOutGoingPorts.begin();iter2!=_intecptrsForOutGoingPorts.end();iter2++) + delete *iter2; +} + +void ForEachLoop::init(bool start) +{ + DynParaLoop::init(start); + _splitterNode.init(start); + _execCurrentId=0; + cleanDynGraph(); +} + +void ForEachLoop::exUpdateState() +{ + if(_state == YACS::DISABLED) + return; + if(_inGate.exIsReady()) + { + //setState(YACS::TOACTIVATE); // call this method below + //internal graph update + int i; + int nbOfBr=_nbOfBranches.getIntValue(); + int nbOfElts=_splitterNode.getNumberOfElements(); + if(nbOfElts==0) + { + prepareSequenceValues(0); + delete _nodeForSpecialCases; + _nodeForSpecialCases=new FakeNodeForForEachLoop(this,true); + return ; + } + if(nbOfBr<=0) + { + delete _nodeForSpecialCases; + _nodeForSpecialCases=new FakeNodeForForEachLoop(this,getAllOutPortsLeavingCurrentScope().empty()); + return ; + } + if(nbOfBr>nbOfElts) + nbOfBr=nbOfElts; + _execNodes.resize(nbOfBr); + _execIds.resize(nbOfBr); + _execOutGoingPorts.resize(nbOfBr); + prepareSequenceValues(nbOfElts); + if(_initNode) + _execInitNodes.resize(nbOfBr); + + //Conversion exceptions can be thrown by createOutputOutOfScopeInterceptors + //so catch them to control errors + try + { + for(i=0;iclone(this,false); + DEBTRACE( "-------------- 3" ); + if(_initNode) + _execInitNodes[i]=_initNode->clone(this,false); + DEBTRACE( "-------------- 4" ); + prepareInputsFromOutOfScope(i); + DEBTRACE( "-------------- 5" ); + createOutputOutOfScopeInterceptors(i); + DEBTRACE( "-------------- 6" ); + _splitterNode.putSplittedValueOnRankTo(_execCurrentId++,i,true); + DEBTRACE( "-------------- 7" ); + } + } + catch(YACS::Exception& ex) + { + //ForEachLoop must be put in error and the exception rethrown to notify the caller + DEBTRACE( "ForEachLoop::exUpdateState: " << ex.what() ); + setState(YACS::ERROR); + exForwardFailed(); + throw; + } + + setState(YACS::TOACTIVATE); // move the calling of setState method there for adding observers for clone nodes in GUI part + + //let's go + for(i=0;iexUpdateState(); + else + { + _nbOfEltConsumed++; + _execNodes[i]->exUpdateState(); + } + } +} + +void ForEachLoop::getReadyTasks(std::vector& tasks) +{ + if(!_node) + return; + if(_state==YACS::TOACTIVATE || _state==YACS::ACTIVATED) + { + if(_nodeForSpecialCases) + { + _nodeForSpecialCases->getReadyTasks(tasks); + return ; + } + for(vector::iterator iter=_execNodes.begin();iter!=_execNodes.end();iter++) + (*iter)->getReadyTasks(tasks); + for(vector::iterator iter2=_execInitNodes.begin();iter2!=_execInitNodes.end();iter2++) + (*iter2)->getReadyTasks(tasks); + } +} + +int ForEachLoop::getNumberOfInputPorts() const +{ + return DynParaLoop::getNumberOfInputPorts()+1; +} + +void ForEachLoop::checkConsistency(ComposedNode *pointOfView) const throw(Exception) +{ + //TO DO +} + +void ForEachLoop::checkNoCyclePassingThrough(Node *node) throw(Exception) +{ + //TO DO +} + +void ForEachLoop::selectRunnableTasks(std::vector& tasks) +{ +} + +std::list ForEachLoop::getSetOfInputPort() const +{ + list ret=DynParaLoop::getSetOfInputPort(); + ret.push_back((InputPort *)&_splitterNode._dataPortToDispatch); + return ret; +} + +InputPort *ForEachLoop::getInputPort(const std::string& name) const throw(Exception) +{ + if(name==SplitterNode::NAME_OF_SEQUENCE_INPUT) + return (InputPort *)&_splitterNode._dataPortToDispatch; + else + return DynParaLoop::getInputPort(name); +} + +OutputPort *ForEachLoop::getOutputPort(const std::string& name) const throw(Exception) +{ + for(vector::const_iterator iter=_outGoingPorts.begin();iter!=_outGoingPorts.end();iter++) + { + if(name==(*iter)->getName()) + return (OutputPort *)(*iter); + } + return DynParaLoop::getOutputPort(name); +} + +OutPort *ForEachLoop::getOutPort(const std::string& name) const throw(Exception) +{ + for(vector::const_iterator iter=_outGoingPorts.begin();iter!=_outGoingPorts.end();iter++) + { + if(name==(*iter)->getName()) + return (OutPort *)(*iter); + } + return DynParaLoop::getOutPort(name); +} + +Node *ForEachLoop::getChildByShortName(const std::string& name) const throw(Exception) +{ + if(name==NAME_OF_SPLITTERNODE) + return (Node *)&_splitterNode; + else + return DynParaLoop::getChildByShortName(name); +} + +YACS::Event ForEachLoop::updateStateOnFinishedEventFrom(Node *node) +{ + unsigned int id; + switch(getIdentityOfNotifyerNode(node,id)) + { + case INIT_NODE: + _execNodes[id]->exUpdateState(); + _nbOfEltConsumed++; + break; + case WORK_NODE: + storeOutValsInSeqForOutOfScopeUse(_execIds[id],id); + if(_execCurrentId==_splitterNode.getNumberOfElements()) + {//No more elements of _dataPortToDispatch to treat + _execIds[id]=NOT_RUNNING_BRANCH_ID; + //analyzing if some samples are still on treatment on other branches. + bool isFinished=true; + for(int i=0;i<_execIds.size() and isFinished;i++) + isFinished=(_execIds[i]==NOT_RUNNING_BRANCH_ID); + if(isFinished) + { + try + { + pushAllSequenceValues(); + setState(YACS::DONE); + return YACS::FINISH; + } + catch(YACS::Exception& ex) + { + DEBTRACE("ForEachLoop::updateStateOnFinishedEventFrom: "<init(false); + _splitterNode.putSplittedValueOnRankTo(_execCurrentId++,id,false); + node->exUpdateState(); + _nbOfEltConsumed++; + } + break; + } + return YACS::NOEVENT; +} + +void ForEachLoop::buildDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) +{ + DynParaLoop::buildDelegateOf(port,finalTarget,pointsOfView); + string typeOfPortInstance=(port.first)->getNameOfTypeOfCurrentInstance(); + if(typeOfPortInstance==OutputPort::NAME) + { + vector::iterator iter=_outGoingPorts.begin(); + int i=0; + for(;iter!=_outGoingPorts.end();iter++,i++) + if((*iter)->getRepr()==port.first) + break; + if(iter!=_outGoingPorts.end()) + { + (*iter)->incrRef(); + (*iter)->addRepr(port.first,_intecptrsForOutGoingPorts[i]); + port.first=*iter; + } + else + { + TypeCodeSeq *newTc=new TypeCodeSeq("","",port.first->edGetType()); + AnySplitOutputPort *newPort=new AnySplitOutputPort(getPortName(port.first),this,newTc); + InterceptorInputPort *intercptor=new InterceptorInputPort(string("intercptr for ")+getPortName(port.first),this,port.first->edGetType()); + intercptor->setRepr(newPort); + newTc->decrRef(); + newPort->addRepr(port.first,intercptor); + _outGoingPorts.push_back(newPort); + _intecptrsForOutGoingPorts.push_back(intercptor); + port.first=newPort; + } + } + else + throw Exception("ForEachLoop::buildDelegateOf : not implemented for DS because not specified"); +} + +void ForEachLoop::getDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) throw(Exception) +{ + string typeOfPortInstance=(port.first)->getNameOfTypeOfCurrentInstance(); + if(typeOfPortInstance==OutputPort::NAME) + { + vector::iterator iter=_outGoingPorts.begin(); + for(;iter!=_outGoingPorts.end();iter++) + if((*iter)->getRepr()==port.first) + break; + if(iter==_outGoingPorts.end()) + { + string what("ForEachLoop::getDelegateOf : Port with name "); what+=port.first->getName(); what+=" not exported by ForEachLoop "; what+=_name; + throw Exception(what); + } + else + port.first=(*iter); + } + else + throw Exception("ForEachLoop::getDelegateOf : not implemented because not specified"); +} + +void ForEachLoop::releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::set& pointsOfView) throw(Exception) +{ + string typeOfPortInstance=portDwn->getNameOfTypeOfCurrentInstance(); + if(typeOfPortInstance==OutputPort::NAME) + { + vector::iterator iter=_outGoingPorts.begin(); + vector::iterator iter2=_intecptrsForOutGoingPorts.begin(); + for(;iter!=_outGoingPorts.end();iter++,iter2++) + if((*iter)->getRepr()==portDwn) + break; + //ASSERT(portUp==*iter.second) + if((*iter)->decrRef()) + { + _outGoingPorts.erase(iter); + delete *iter2; + _intecptrsForOutGoingPorts.erase(iter2); + delete *iter; + } + } +} + +OutPort *ForEachLoop::getDynOutPortByAbsName(int branchNb, const std::string& name) +{ + string portName, nodeName; + splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false); + Node *staticChild = getChildByName(nodeName); + return _execNodes[branchNb]->getOutPort(portName);//It's impossible(garanteed by YACS::ENGINE::ForEachLoop::buildDelegateOf) + //that a link starting from _initNode goes out of scope of 'this'. +} + +void ForEachLoop::cleanDynGraph() +{ + DynParaLoop::cleanDynGraph(); + for(vector< SequenceAny *>::iterator iter3=_execVals.begin();iter3!=_execVals.end();iter3++) + (*iter3)->decrRef(); + _execVals.clear(); + for(vector< vector >::iterator iter4=_execOutGoingPorts.begin();iter4!=_execOutGoingPorts.end();iter4++) + for(vector::iterator iter5=(*iter4).begin();iter5!=(*iter4).end();iter5++) + delete *iter5; + _execOutGoingPorts.clear(); +} + +void ForEachLoop::storeOutValsInSeqForOutOfScopeUse(int rank, int branchNb) +{ + vector::iterator iter; + int i=0; + for(iter=_execOutGoingPorts[branchNb].begin();iter!=_execOutGoingPorts[branchNb].end();iter++,i++) + { + Any *val=(Any *)(*iter)->getValue(); + _execVals[i]->setEltAtRank(rank,val); + } +} + +void ForEachLoop::prepareSequenceValues(int sizeOfSamples) +{ + _execVals.resize(_outGoingPorts.size()); + vector::iterator iter=_outGoingPorts.begin(); + for(int i=0;iter!=_outGoingPorts.end();iter++,i++) + _execVals[i]=SequenceAny::New((*iter)->edGetType()->contentType(),sizeOfSamples); +} + +void ForEachLoop::pushAllSequenceValues() +{ + vector::iterator iter=_outGoingPorts.begin(); + int i=0; + for(;iter!=_outGoingPorts.end();iter++,i++) + (*iter)->put((const void *)_execVals[i]); +} + +void ForEachLoop::createOutputOutOfScopeInterceptors(int branchNb) +{ + vector::iterator iter=_outGoingPorts.begin(); + int i=0; + for(;iter!=_outGoingPorts.end();iter++,i++) + { + DEBTRACE( (*iter)->getName() << " " << (*iter)->edGetType()->kind() ); + //AnyInputPort *interceptor=new AnyInputPort((*iter)->getName(),this,(*iter)->edGetType()); + OutPort *portOut=getDynOutPortByAbsName(branchNb,getOutPortName(((*iter)->getRepr()))); + DEBTRACE( portOut->getName() ); + AnyInputPort *interceptor=new AnyInputPort((*iter)->getName(),this,portOut->edGetType()); + portOut->addInPort(interceptor); + _execOutGoingPorts[branchNb].push_back(interceptor); + } +} + +void ForEachLoop::checkLinkPossibility(OutPort *start, const std::set& pointsOfViewStart, + InPort *end, const std::set& pointsOfViewEnd) throw(Exception) +{ + if(isInMyDescendance(start->getNode())==_node) + throw Exception("ForEachLoop::checkLinkPossibility : A link from work node to init node not permitted"); +} + +std::list ForEachLoop::getLocalOutputPorts() const +{ + list ret; + ret.push_back(getOutputPort(NAME_OF_SPLITTED_SEQ_OUT)); // OCC : mkr : add _splittedPort to the list of output ports + //ret.push_back(getOutputPort(SplitterNode::NAME_OF_SEQUENCE_INPUT)); + return ret; +} + +void ForEachLoop::accept(Visitor *visitor) +{ + visitor->visitForEachLoop(this); +} + +//! Dump the node state to a stream +/*! + * \param os : the output stream + */ +void ForEachLoop::writeDot(std::ostream &os) +{ + os << " subgraph cluster_" << getId() << " {\n" ; + //only one node in a loop + _node->writeDot(os); + os << getId() << " -> " << _node->getId() << ";\n"; + os << "}\n" ; + os << getId() << "[fillcolor=\"" ; + YACS::StatesForNode state=getEffectiveState(); + os << getColorState(state); + os << "\" label=\"" << "Loop:" ; + os << getName() <<"\"];\n"; +} diff --git a/src/engine/ForEachLoop.hxx b/src/engine/ForEachLoop.hxx new file mode 100644 index 000000000..13f52f2bd --- /dev/null +++ b/src/engine/ForEachLoop.hxx @@ -0,0 +1,165 @@ +#ifndef __FOREACHLOOP_HXX__ +#define __FOREACHLOOP_HXX__ + +#include "ElementaryNode.hxx" +#include "DynParaLoop.hxx" +#include "OutputPort.hxx" +#include "InputPort.hxx" +#include "TypeCode.hxx" +#include "AnyInputPort.hxx" + +namespace YACS +{ + namespace ENGINE + { + class ForEachLoop; + class SplitterNode; + class AnySplitOutputPort; + + class InterceptorInputPort : public AnyInputPort + { + friend class ForEachLoop; + friend class SplitterNode; + private: + AnySplitOutputPort *_repr; + private: + InterceptorInputPort(const std::string& name, Node *node, TypeCode* type); + InterceptorInputPort(const InterceptorInputPort& other, Node *newHelder); + void getAllRepresentants(std::set& repr) const; + InputPort *clone(Node *newHelder) const; + void setRepr(AnySplitOutputPort *repr); + }; + + class AnySplitOutputPort : public OutputPort + { + friend class ForEachLoop; + friend class SplitterNode; + private: + OutPort *_repr; + InterceptorInputPort *_intercptr; + mutable unsigned int _cnt; + private: + bool decrRef(); + void incrRef() const; + AnySplitOutputPort(const std::string& name, Node *node, TypeCode *type); + AnySplitOutputPort(const AnySplitOutputPort& other, Node *newHelder); + bool addInPort(InPort *inPort) throw(Exception); + void getAllRepresented(std::set& represented) const; + int removeInPort(InPort *inPort, bool forward) throw(Exception); + void addRepr(OutPort *repr, InterceptorInputPort *intercptr); + OutPort *getRepr() const { return _repr; } + OutputPort *clone(Node *newHelder) const; + }; + + class SeqAnyInputPort : public AnyInputPort + { + friend class ForEachLoop; + friend class SplitterNode; + public: + unsigned getNumberOfElements() const; + virtual std::string dump(); + private: + SeqAnyInputPort(const std::string& name, Node *node, TypeCodeSeq* type); + SeqAnyInputPort(const SeqAnyInputPort& other, Node *newHelder); + InputPort *clone(Node *newHelder) const; + Any *getValueAtRank(int i) const; + }; + + class SplitterNode : public ElementaryNode + { + friend class ForEachLoop; + private: + static const char NAME_OF_SEQUENCE_INPUT[]; + private: + SplitterNode(const std::string& name, TypeCode *typeOfData, ForEachLoop *father); + SplitterNode(const SplitterNode& other, ForEachLoop *father); + InputPort *getInputPort(const std::string& name) const throw(Exception); + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + unsigned getNumberOfElements() const; + void execute(); + void init(bool start=true); + void putSplittedValueOnRankTo(int rankInSeq, int branch, bool first); + private: + SeqAnyInputPort _dataPortToDispatch; + }; + + class FakeNodeForForEachLoop : public ElementaryNode + { + friend class ForEachLoop; + private: + ForEachLoop *_loop; + bool _normalFinish; + private: + FakeNodeForForEachLoop(ForEachLoop *loop, bool normalFinish); + FakeNodeForForEachLoop(const FakeNodeForForEachLoop& other); + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + void exForwardFailed(); + void exForwardFinished(); + void execute(); + void aborted(); + void finished(); + private: + static const char NAME[]; + }; + + class ForEachLoop : public DynParaLoop + { + friend class SplitterNode; + friend class FakeNodeForForEachLoop; + + public: + static const char NAME_OF_SPLITTERNODE[]; + protected: + static const int NOT_RUNNING_BRANCH_ID; + protected: + SplitterNode _splitterNode; + FakeNodeForForEachLoop *_nodeForSpecialCases; + std::vector _outGoingPorts;//! ports linked to node outside the current scope + std::vector _intecptrsForOutGoingPorts;//!ports created for TypeCodes correctness + //part of attributes defining graph dynamically built on control notification + unsigned _execCurrentId; + std::vector _execVals; + std::vector< std::vector > _execOutGoingPorts; + public: + ForEachLoop(const std::string& name, TypeCode *typeOfDataSplitted); + ForEachLoop(const ForEachLoop& other, ComposedNode *father, bool editionOnly); + ~ForEachLoop(); + void init(bool start=true); + void exUpdateState(); + void getReadyTasks(std::vector& tasks); + int getNumberOfInputPorts() const; + // + void checkConsistency(ComposedNode *pointOfView) const throw(Exception); + void checkNoCyclePassingThrough(Node *node) throw(Exception); + void selectRunnableTasks(std::vector& tasks); + // + unsigned getExecCurrentId() const { return _execCurrentId; } // for update progress bar on GUI part + std::list getSetOfInputPort() const; + InputPort *edGetSeqOfSamplesPort() { return &_splitterNode._dataPortToDispatch; } + InputPort *getInputPort(const std::string& name) const throw(Exception); + OutPort *getOutPort(const std::string& name) const throw(Exception); + OutputPort *getOutputPort(const std::string& name) const throw(Exception); + Node *getChildByShortName(const std::string& name) const throw(Exception); + std::list getLocalOutputPorts() const; + void accept(Visitor *visitor); + void writeDot(std::ostream &os); + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; + void checkLinkPossibility(OutPort *start, const std::set& pointsOfViewStart, + InPort *end, const std::set& pointsOfViewEnd) throw(Exception); + YACS::Event updateStateOnFinishedEventFrom(Node *node); + void buildDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView); + void getDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) throw(Exception); + void releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::set& pointsOfView) throw(Exception); + protected: + void cleanDynGraph(); + void pushAllSequenceValues(); + void createOutputOutOfScopeInterceptors(int branchNb); + void prepareSequenceValues(int sizeOfSamples); + OutPort *getDynOutPortByAbsName(int branchNb, const std::string& name); + void storeOutValsInSeqForOutOfScopeUse(int rank, int branchNb); + }; + } +} + +#endif diff --git a/src/engine/ForLoop.cxx b/src/engine/ForLoop.cxx new file mode 100644 index 000000000..23e36ceb9 --- /dev/null +++ b/src/engine/ForLoop.cxx @@ -0,0 +1,132 @@ +#include "ForLoop.hxx" +#include "Runtime.hxx" +#include "OutputPort.hxx" +#include "Visitor.hxx" +#include + +using namespace YACS::ENGINE; +using namespace std; + +const char ForLoop::NAME_OF_NSTEPS_NUMBER[]="nsteps"; + +ForLoop::ForLoop(const std::string& name):Loop(name),_nbOfTimesPort(NAME_OF_NSTEPS_NUMBER,this,Runtime::_tc_int) +{ +} + +ForLoop::ForLoop(const ForLoop& other, ComposedNode *father, bool editionOnly):Loop(other,father,editionOnly), + _nbOfTimesPort(other._nbOfTimesPort,this) +{ +} + +Node *ForLoop::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new ForLoop(*this,father,editionOnly); +} + +int ForLoop::getNumberOfInputPorts() const +{ + return StaticDefinedComposedNode::getNumberOfInputPorts()+1; +} + +std::list ForLoop::getSetOfInputPort() const +{ + list ret=StaticDefinedComposedNode::getSetOfInputPort(); + ret.push_back((InputPort *)&_nbOfTimesPort); + return ret; +} + +InputPort* ForLoop::getInputPort(const std::string& name) const throw(Exception) +{ + if(name == NAME_OF_NSTEPS_NUMBER)return (InputPort*)&_nbOfTimesPort; + return Loop::getInputPort(name); + +} + +//! Initialize the node +/*! + * \param start: a boolean flag to indicate the initialization mode + * + * If start is true, it's a complete initialization (with port values initialization) + * If start is false, there is no port values initialization + * + */ +void ForLoop::init(bool start) +{ + Loop::init(start); + _nbOfTimesPort.exInit(start); +} + +//! Update the state of the for loop +/*! + * If the inGate port is ready goes to YACS::TOACTIVATE state + * If the steps number is 0, create an special internal node + * + */ +void ForLoop::exUpdateState() +{ + if(_state == YACS::DISABLED) + return; + if(_inGate.exIsReady()) + { + setState(YACS::TOACTIVATE); + _node->exUpdateState(); + if(_nbOfTimesPort.isEmpty()) + { + delete _nodeForNullTurnOfLoops; + _nodeForNullTurnOfLoops=new FakeNodeForLoop(this,false,true); + } + else + { + if(_nbOfTimesPort.getIntValue()==0) + { + bool normalFinish=getAllOutPortsLeavingCurrentScope().empty(); + delete _nodeForNullTurnOfLoops; + _nodeForNullTurnOfLoops=new FakeNodeForLoop(this,normalFinish); + } + else if(_nbOfTimesPort.getIntValue()<0) + { + delete _nodeForNullTurnOfLoops; + _nodeForNullTurnOfLoops=new FakeNodeForLoop(this,false); + } + else + { + delete _nodeForNullTurnOfLoops; + _nodeForNullTurnOfLoops=0; + } + } + } +} + +//! Method used to notify the node that a child node has ended +/*! + * Update the loop state and return the loop change state + * + * \param node : the child node that has ended + * \return the loop state change + */ +YACS::Event ForLoop::updateStateOnFinishedEventFrom(Node *node) +{ + if((++_nbOfTurns)>=_nbOfTimesPort.getIntValue()) + { + setState(YACS::DONE); + return YACS::FINISH; + } + else + { + node->init(false); + node->exUpdateState(); + } + return YACS::NOEVENT; +} + +void ForLoop::accept(Visitor *visitor) +{ + visitor->visitForLoop(this); +} + +std::list ForLoop::getLocalInputPorts() const +{ + list ret; + ret.push_back((InputPort *)&_nbOfTimesPort); + return ret; +} diff --git a/src/engine/ForLoop.hxx b/src/engine/ForLoop.hxx new file mode 100644 index 000000000..a595e0c6e --- /dev/null +++ b/src/engine/ForLoop.hxx @@ -0,0 +1,41 @@ +#ifndef __FORLOOP_HXX__ +#define __FORLOOP_HXX__ + +#include "AnyInputPort.hxx" +#include "Loop.hxx" + +namespace YACS +{ + namespace ENGINE + { +/*! \brief Class for for loop node + * + * \ingroup Nodes + * + * This kind of loop makes a fixed number of steps and stops + * + */ + class ForLoop : public Loop + { + protected: + static const char NAME_OF_NSTEPS_NUMBER[]; + AnyInputPort _nbOfTimesPort; + public: + ForLoop(const ForLoop& other, ComposedNode *father, bool editionOnly); + ForLoop(const std::string& name); + void exUpdateState(); + void init(bool start=true); + InputPort *edGetNbOfTimesInputPort() { return &_nbOfTimesPort; } + int getNumberOfInputPorts() const; + Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; + std::list getSetOfInputPort() const; + InputPort* getInputPort(const std::string& name) const throw(Exception); + std::list getLocalInputPorts() const; + virtual void accept(Visitor *visitor); + protected: + YACS::Event updateStateOnFinishedEventFrom(Node *node); + }; + } +} + +#endif diff --git a/src/engine/InGate.cxx b/src/engine/InGate.cxx index ec6574e18..06e6904c3 100644 --- a/src/engine/InGate.cxx +++ b/src/engine/InGate.cxx @@ -6,7 +6,11 @@ using namespace std; const char InGate::NAME[]="InGate"; -InGate::InGate(Node *node):Port(node),_nbPrecursor(0),_nbPrecursorDone(0),_colour(YACS::White) +InGate::InGate(Node *node):Port(node) +{ +} + +InGate::~InGate() { } @@ -15,34 +19,85 @@ string InGate::getNameOfTypeOfCurrentInstance() const return NAME; } -void InGate::exNotifyFromPrecursor() +void InGate::edDisconnectAllLinksToMe() { - _nbPrecursorDone++; - if(exIsReady() && _node) + for(map::iterator iter=_backLinks.begin();iter!=_backLinks.end();iter++) + ((*iter).first)->edRemoveInGate(this,false); + _backLinks.clear(); +} + +//! Notify this port that an upstream node connected by a control flow link is finished +/*! + * Calls the node's gate method : Node::exUpdateState + * + * Called by OutGate::exNotifyDone + */ +void InGate::exNotifyFromPrecursor(OutGate *from) +{ + map< OutGate *, bool >::iterator iter=_backLinks.find(from); + (*iter).second=true; + if(exIsReady()) _node->exUpdateState(); } -void InGate::edAppendPrecursor() +//! Notify this port that an upstream node connected by a control flow link has failed +/*! + * + */ +void InGate::exNotifyFailed() +{ + if(_node) _node->exFailedState(); +} + +//! Notify this port that an upstream node connected by a control flow link has been disabled +/*! + * + */ +void InGate::exNotifyDisabled() { - _nbPrecursor++; + if(_node) + _node->exDisabledState(); } -void InGate::edRemovePrecursor() +void InGate::edAppendPrecursor(OutGate *from) { - _nbPrecursor--; + _backLinks[from]=false; } -void InGate::edSet(int nbOfPrecursors) +void InGate::edRemovePrecursor(OutGate *from) { - _nbPrecursor=nbOfPrecursors; + _backLinks.erase(from); +} + +int InGate::getNumberOfBackLinks() const +{ + return _backLinks.size(); } void InGate::exReset() { - _nbPrecursorDone=0; + for(map::iterator iter=_backLinks.begin();iter!=_backLinks.end();iter++) + (*iter).second=false; } bool InGate::exIsReady() const { - return _nbPrecursor==_nbPrecursorDone; + bool isReady=true; + for(map::const_iterator iter=_backLinks.begin();iter!=_backLinks.end() && isReady;iter++) + isReady=(*iter).second; + return isReady; +} + +std::list InGate::getBackLinks() +{ + list listo; + for(map::iterator iter=_backLinks.begin();iter!=_backLinks.end();iter++) + listo.push_back(iter->first); + return listo; +} + +void InGate::setPrecursorDone(OutGate *from) +{ + map< OutGate *, bool >::iterator iter=_backLinks.find(from); + (*iter).second=true; } diff --git a/src/engine/InGate.hxx b/src/engine/InGate.hxx index 75e888c8e..bf6dc8dd1 100644 --- a/src/engine/InGate.hxx +++ b/src/engine/InGate.hxx @@ -4,32 +4,39 @@ #include "Port.hxx" #include "define.hxx" +#include +#include + namespace YACS { namespace ENGINE { + class OutGate; + class InGate : public Port { friend class Bloc; friend class Node; protected: - int _nbPrecursor; - int _nbPrecursorDone; static const char NAME[]; private: - //for graphs algs - mutable Colour _colour; + std::map< OutGate *, bool > _backLinks; public: InGate(Node *node); + virtual ~InGate(); std::string getNameOfTypeOfCurrentInstance() const; - void exNotifyFromPrecursor(); - void edAppendPrecursor(); - void edRemovePrecursor(); - void edSet(int nbOfPrecursors); + void exNotifyFromPrecursor(OutGate *from); + std::map& edMapOutGate() { return _backLinks; } + void edAppendPrecursor(OutGate *from); + void edRemovePrecursor(OutGate *from); + int getNumberOfBackLinks() const; + void edDisconnectAllLinksToMe(); + void exNotifyFailed(); + void exNotifyDisabled(); void exReset(); bool exIsReady() const; - private: - void initForDFS() const { _colour=YACS::White; } + std::list getBackLinks(); + void setPrecursorDone(OutGate *from); }; } } diff --git a/src/engine/InPort.cxx b/src/engine/InPort.cxx index ea17280c4..5adca23f5 100644 --- a/src/engine/InPort.cxx +++ b/src/engine/InPort.cxx @@ -1,7 +1,61 @@ #include "InPort.hxx" +#include "OutPort.hxx" +#include "ComposedNode.hxx" +#include using namespace YACS::ENGINE; +using namespace std; -InPort::InPort(Node *node):Port(node) +InPort::InPort(const InPort& other, Node *newHelder): + DataPort(other,newHelder),Port(other,newHelder) { } + +InPort::InPort(const std::string& name, Node *node, TypeCode* type): + DataPort(name,node,type),Port(node) +{ +} + +InPort::~InPort() +{ +} + +//! Returns number of \b physical backlinks \b NOT number of user backlinks. +int InPort::edGetNumberOfLinks() const +{ + return _backLinks.size(); +} + +void InPort::edRemoveAllLinksLinkedWithMe() throw(Exception) +{ + set temp(_backLinks);//edRemoveLink called after causes invalidation of set iterator. + for(set::iterator iter=temp.begin();iter!=temp.end();iter++) + { + set trueBackOutputs; + (*iter)->getAllRepresented(trueBackOutputs); + for(set::iterator iter2=trueBackOutputs.begin();iter2!=trueBackOutputs.end();iter2++) + _node->getRootNode()->edRemoveLink(*iter2,this); + } + _backLinks.clear(); +} + +//! Returns \b physical backlinks \b NOT user backlinks. +std::set InPort::edSetOutPort() const +{ + return _backLinks; +} + +void InPort::edNotifyReferencedBy(OutPort *fromPort) +{ + _backLinks.insert(fromPort); +} + +void InPort::edNotifyDereferencedBy(OutPort *fromPort) +{ + _backLinks.erase(fromPort); +} + +void InPort::getAllRepresentants(std::set& repr) const +{ + repr.insert((InPort *)this); +} diff --git a/src/engine/InPort.hxx b/src/engine/InPort.hxx index 0377fc1cd..3860a2470 100644 --- a/src/engine/InPort.hxx +++ b/src/engine/InPort.hxx @@ -1,16 +1,57 @@ #ifndef __INPORT_HXX__ #define __INPORT_HXX__ -#include "Port.hxx" +#include "DataPort.hxx" + +#include namespace YACS { namespace ENGINE { - class InPort : public virtual Port + class Loop; + class OutPort; + class ProxyPort; + class OutputPort; + class DynParaLoop; + class ForEachLoop; + class SplitterNode; + class ComposedNode; + class OptimizerLoop; + class ElementaryNode; + class CollectorSwOutPort; + class OutputDataStreamPort; + class InterceptorInputPort; + + class InPort : public virtual DataPort { + friend class Loop; + friend class OutPort; + friend class ProxyPort; + friend class OutputPort; + friend class DynParaLoop; + friend class ForEachLoop; + friend class SplitterNode; + friend class ComposedNode; + friend class OptimizerLoop; + friend class ElementaryNode; //for removeAllLinksWithMe + friend class CollectorSwOutPort; + friend class OutputDataStreamPort; + friend class InterceptorInputPort; + public: + virtual InPort *getPublicRepresentant() { return this; } + virtual int edGetNumberOfLinks() const; + virtual std::set edSetOutPort() const; + virtual ~InPort(); + protected: + InPort(const InPort& other, Node *newHelder); + InPort(const std::string& name, Node *node, TypeCode* type); + void edRemoveAllLinksLinkedWithMe() throw(Exception); + virtual void edNotifyReferencedBy(OutPort *fromPort); + virtual void edNotifyDereferencedBy(OutPort *fromPort); + virtual void getAllRepresentants(std::set& repr) const; protected: - InPort(Node *node); + std::set _backLinks; }; } } diff --git a/src/engine/InlineNode.cxx b/src/engine/InlineNode.cxx new file mode 100644 index 000000000..bf734693d --- /dev/null +++ b/src/engine/InlineNode.cxx @@ -0,0 +1,21 @@ +#include "InlineNode.hxx" +#include "Visitor.hxx" + +using namespace YACS::ENGINE; + + +InlineNode::~InlineNode() { } + +void InlineNode::accept(Visitor *visitor) +{ + visitor->visitInlineNode(this); +} + + +InlineFuncNode::~InlineFuncNode() { } + +void InlineFuncNode::accept(Visitor *visitor) +{ + visitor->visitInlineFuncNode(this); +} + diff --git a/src/engine/InlineNode.hxx b/src/engine/InlineNode.hxx new file mode 100644 index 000000000..9253406d1 --- /dev/null +++ b/src/engine/InlineNode.hxx @@ -0,0 +1,81 @@ +#ifndef __INLINENODE_HXX__ +#define __INLINENODE_HXX__ + +#include "ElementaryNode.hxx" +#include + +namespace YACS +{ + namespace ENGINE + { +/*! \brief Class for calculation node (script) inlined (and executed) in the schema + * + * \ingroup Nodes + * + * This node is like a script. It has no state if it is executed several times. + * Each execution the string _script is executed within a clean context. + * + * \see ServiceNode + * \see ElementaryNode + */ + class InlineNode : public ElementaryNode + { + protected: + InlineNode(const InlineNode& other, ComposedNode *father) + :ElementaryNode(other,father),_script(other._script) { } + InlineNode(const std::string& name):ElementaryNode(name) { } + public: +//! Set the script (as a string) to execute +/*! + * \param script: script to execute + */ + virtual void setScript(const std::string& script) { _script=script; } + virtual std::string getScript(){return _script;} + +//! Return a new InlineNode node by making a copy of this node +/*! + * \param name: name of the new node + * \return the new node built by cloning. + */ + virtual InlineNode* cloneNode(const std::string& name) + { throw Exception("Not implemented");}; + virtual void accept(Visitor *visitor); + virtual ~InlineNode(); + protected: + std::string _script; + }; + +/*! \brief Class for calculation node (function) inlined (and executed) in the schema + * + * \ingroup Nodes + * + * This node is like a function. It can have a state. The first time the node + * is executed, the string _script is executed in a clean context followed by the + * execution of the function _fname. Next times, the function _fname is executed + * within the preserved context. + * + * \see ServiceNode + * \see ElementaryNode + */ + class InlineFuncNode : public InlineNode + { + protected: + InlineFuncNode(const InlineFuncNode& other, ComposedNode *father) + :InlineNode(other,father),_fname(other._fname) { } + InlineFuncNode(const std::string& name):InlineNode(name) { } + public: +//! Set the function name to use in node execution +/*! + * \param fname: name of the function contained in the script to execute + */ + virtual void setFname(const std::string& fname) { _fname=fname; } + virtual std::string getFname() { return _fname; } + void accept(Visitor *visitor); + virtual ~InlineFuncNode(); + protected: + std::string _fname; + }; + } +} + +#endif diff --git a/src/engine/InputDataStreamPort.cxx b/src/engine/InputDataStreamPort.cxx index 305ea9992..2ba62f65c 100644 --- a/src/engine/InputDataStreamPort.cxx +++ b/src/engine/InputDataStreamPort.cxx @@ -1,13 +1,28 @@ #include "InputDataStreamPort.hxx" +#include using namespace YACS::ENGINE; using namespace std; const char InputDataStreamPort::NAME[]="InputDataStreamPort"; -InputDataStreamPort::InputDataStreamPort(const string& name, Node *node, TypeCode* type):DataStreamPort(name,node,type), - InPort(node), - Port(node) +InputDataStreamPort::InputDataStreamPort(const InputDataStreamPort& other, Node *newHelder): + DataStreamPort(other,newHelder), + InPort(other,newHelder), + DataPort(other,newHelder), + Port(other,newHelder) +{ +} + +InputDataStreamPort::InputDataStreamPort(const std::string& name, Node *node, TypeCode* type): + DataStreamPort(name,node,type), + InPort(name,node,type), + DataPort(name,node,type), + Port(node) +{ +} + +InputDataStreamPort::~InputDataStreamPort() { } @@ -15,3 +30,8 @@ string InputDataStreamPort::getNameOfTypeOfCurrentInstance() const { return NAME; } + +InputDataStreamPort *InputDataStreamPort::clone(Node *newHelder) const +{ + return new InputDataStreamPort(*this,newHelder); +} diff --git a/src/engine/InputDataStreamPort.hxx b/src/engine/InputDataStreamPort.hxx index 468f02ed9..1f4768b17 100644 --- a/src/engine/InputDataStreamPort.hxx +++ b/src/engine/InputDataStreamPort.hxx @@ -8,13 +8,21 @@ namespace YACS { namespace ENGINE { + /*! \brief Class for Input DataStream Ports + * + * \ingroup Ports + * + */ class InputDataStreamPort : public DataStreamPort, public InPort { public: static const char NAME[]; public: + InputDataStreamPort(const InputDataStreamPort& other, Node *newHelder); InputDataStreamPort(const std::string& name, Node *node, TypeCode* type); - std::string getNameOfTypeOfCurrentInstance() const; + virtual ~InputDataStreamPort(); + virtual std::string getNameOfTypeOfCurrentInstance() const; + virtual InputDataStreamPort *clone(Node *newHelder) const; }; } } diff --git a/src/engine/InputPort.cxx b/src/engine/InputPort.cxx index 3a7c97540..37af33bfe 100644 --- a/src/engine/InputPort.cxx +++ b/src/engine/InputPort.cxx @@ -1,15 +1,29 @@ #include "InputPort.hxx" +#include "OutPort.hxx" +#include "ComposedNode.hxx" #include #include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" using namespace YACS::ENGINE; using namespace std; const char InputPort::NAME[]="InputPort"; -InputPort::InputPort(const string& name, Node *node, TypeCode* type) - : DataFlowPort(name,node,type), InPort(node),Port(node), _manuallySet(false), _empty(true) +InputPort::InputPort(const InputPort& other, Node *newHelder):DataFlowPort(other,newHelder),InPort(other,newHelder), + DataPort(other,newHelder),Port(other,newHelder), + _initValue(0) +{ + if(other._initValue) + _initValue=other._initValue->clone(); +} + +InputPort::InputPort(const std::string& name, Node *node, TypeCode* type) + : DataFlowPort(name,node,type), InPort(name,node,type),DataPort(name,node,type),Port(node), _initValue(0) { } @@ -18,46 +32,163 @@ string InputPort::getNameOfTypeOfCurrentInstance() const return NAME; } -// void InputPort::edInit(Data data) throw(ConversionException) -// { -// _data=data; -// _manuallySet=true; -// } +void InputPort::exInit(bool start) +{ + checkBasicConsistency(); + if(start) + exRestoreInit(); +} -void InputPort::edNotifyReferenced() +bool InputPort::isEmpty() { - _manuallySet=false; + return get()==0; } -void InputPort::exInit() +//! Specifies if this port has been \b manually set by the call of InputPort::edInit +bool InputPort::edIsManuallyInitialized() const { -// if(!_manuallySet) -// _data.exInit(); + return _initValue!=0; } -bool InputPort::isEmpty() +/*! + * Perform a quick and not complete check. Use ComposedNode::CheckConsistency instead. + */ +bool InputPort::edIsInitialized() const { - return _empty; + return (edIsManuallyInitialized() or _backLinks.size()!=0 ); } -void InputPort::edInit(const void *data) throw(ConversionException) +InputPort::~InputPort() { - _manuallySet=true; - put(data); + if(_initValue) + _initValue->decrRef(); } -void InputPort::put(const void *data) throw(ConversionException) +void InputPort::edInit(Any *value) { -// _data = (void *)data; - cerr << _name << endl; - cerr << _impl << endl; - stringstream msg; - msg << "Not implemented (" << __FILE__ << ":" << __LINE__ << ")"; - throw Exception(msg.str()); + InputPort *manuallySet=getRuntime()->adapt(this, + Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME,_type); + manuallySet->put((const void *) value); + if(manuallySet!=this) + delete manuallySet; + exSaveInit(); } +void InputPort::edInit(const std::string& impl,const void* value) +{ + InputPort *manuallySet=getRuntime()->adapt(this,impl,_type); + manuallySet->put(value); + if(manuallySet!=this) + delete manuallySet; + exSaveInit(); +} +//! Removes eventually previous manual initialisation. +void InputPort::edRemoveManInit() +{ + if(_initValue) + _initValue->decrRef(); + _initValue=0; +} -InputPort::~InputPort() +//! Check basisically that this port has one chance to be specified on time. It's a necessary condition \b not \b sufficient at all. +void InputPort::checkBasicConsistency() const throw(Exception) +{ + if(!edIsManuallyInitialized() and _backLinks.size()==0 ) + { + ostringstream stream; + stream << "InputPort::checkBasicConsistency : Port " << _name << " of node with name " << _node->getName() << " neither initialized nor linked back"; + throw Exception(stream.str()); + } +} + +std::string InputPort::dump() +{ + string xmldump = " NO_SERIALISATION_AVAILABLE "; + return xmldump; +} + +void InputPort::setStringRef(std::string strRef) +{ + _stringRef = strRef; +} + +ProxyPort::ProxyPort(InputPort* p):InputPort("Convertor", p->getNode(), p->edGetType()),DataPort("Convertor", p->getNode(), p->edGetType()), + Port( p->getNode()) +{ + _port = p; +} + +ProxyPort::~ProxyPort() +{ + //For the moment, there is no case in YACS we have a proxy port in a proxy port + //So don't test that. _port may be already deleted. The test is not sure. + /* + if(_port->isIntermediate()) + delete _port; + */ +} + +void ProxyPort::edRemoveAllLinksLinkedWithMe() throw(Exception) +{ + _port->edRemoveAllLinksLinkedWithMe(); +} + +/*! + * \note : Should never been called because Node clone process does not duplicate data attributes relative to links. + * This part is done afterwards on relink process. + */ +InputPort *ProxyPort::clone(Node *newHelder) const +{ + throw Exception("ProxyPort::clone : internal error - should never happened"); +} + +void ProxyPort::edNotifyReferencedBy(OutPort *fromPort) +{ + _port->edNotifyReferencedBy(fromPort); +} + +void ProxyPort::edNotifyDereferencedBy(OutPort *fromPort) +{ + _port->edNotifyDereferencedBy(fromPort); +} + +std::set ProxyPort::edSetOutPort() const +{ + return _port->edSetOutPort(); +} + +int ProxyPort::edGetNumberOfLinks() const +{ + return _port->edGetNumberOfLinks(); +} + +void ProxyPort::exRestoreInit() +{ + _port->exRestoreInit(); +} + +void ProxyPort::exSaveInit() +{ + _port->exSaveInit(); +} + +InputPort *ProxyPort::getPublicRepresentant() +{ + return _port->getPublicRepresentant(); +} + +void *ProxyPort::get() const throw(Exception) +{ + return _port->get(); +} + +void ProxyPort::put(const void *data) throw(ConversionException) +{ + _port->put(data); +} + +void ProxyPort::getAllRepresentants(std::set& repr) const { + _port->getAllRepresentants(repr); } diff --git a/src/engine/InputPort.hxx b/src/engine/InputPort.hxx index 20d550661..c6b5840e8 100644 --- a/src/engine/InputPort.hxx +++ b/src/engine/InputPort.hxx @@ -1,11 +1,10 @@ #ifndef __INPUTPORT_HXX__ #define __INPUTPORT_HXX__ -//#include -//#include - -#include "TypeCode.hxx" +#include "Any.hxx" #include "InPort.hxx" +#include "Runtime.hxx" +#include "TypeCode.hxx" #include "DataFlowPort.hxx" #include "ConversionException.hxx" @@ -15,47 +14,93 @@ namespace YACS { namespace ENGINE { - - class Runtime; - + class OutPort; +/*! \brief Base class for Input Ports + * + * \ingroup Ports + * + */ class InputPort : public DataFlowPort, public InPort { friend class Runtime; // for port creation + friend class OutPort; public: - ~InputPort(); - - std::string getNameOfTypeOfCurrentInstance() const; - - void edNotifyReferenced(); - void edInit(const void *data) throw(ConversionException); - - void exInit(); - bool isEmpty(); - - virtual void put(const void *data) throw(ConversionException); - static const char NAME[]; + public: + virtual ~InputPort(); + std::string getNameOfTypeOfCurrentInstance() const; + //! returns the final physical port behind 'this'. + virtual InputPort *getPublicRepresentant() { return this; } + virtual bool isIntermediate() const { return false; } + virtual bool edIsManuallyInitialized() const; + //!soon deprecated + bool edIsInitialized() const; + + template + void edInit(T value); + void edInit(Any *value); + void edInit(const std::string& impl,const void* value); + virtual void edRemoveManInit(); + void checkBasicConsistency() const throw(Exception); + virtual void exInit(bool start); + virtual void exSaveInit() = 0; + virtual void exRestoreInit() = 0; + virtual InputPort *clone(Node *newHelder) const = 0; + virtual bool isEmpty(); + + virtual void *get() const throw(Exception) = 0; + virtual void put(const void *data) throw(ConversionException) = 0; + virtual std::string dump(); + virtual void setStringRef(std::string strRef); protected: + InputPort(const InputPort& other, Node *newHelder); InputPort(const std::string& name, Node *node, TypeCode* type); - bool _empty; - bool _manuallySet; + protected: + Any *_initValue; + std::string _stringRef; }; - +/*! \brief Base class for Proxy Input Ports + * + * \ingroup Ports + * + */ class ProxyPort : public InputPort { public: - ProxyPort(InputPort* p) - : InputPort("Convertor", p->getNode(), p->type()), - Port( p->getNode()) - { _port = p; } + ProxyPort(InputPort* p); + ~ProxyPort(); + + void edRemoveAllLinksLinkedWithMe() throw(Exception); + InputPort *clone(Node *newHelder) const; + void edNotifyReferencedBy(OutPort *fromPort); + void edNotifyDereferencedBy(OutPort *fromPort); + std::set edSetOutPort() const; + InputPort *getPublicRepresentant(); + void *get() const throw(Exception); + virtual void put(const void *data) throw(ConversionException) ; + int edGetNumberOfLinks() const; + bool isIntermediate() const { return true; } + void exRestoreInit(); + void exSaveInit(); + void getAllRepresentants(std::set& repr) const; protected: InputPort* _port; }; - - + template + void InputPort::edInit(T value) + { + InputPort *manuallySet=getRuntime()->adapt(this, + Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME,_type); + Any* any=AtomAny::New(value); + manuallySet->put((const void *) any); + if(manuallySet!=this) + delete manuallySet; + any->decrRef(); + exSaveInit(); + } } } diff --git a/src/engine/InvalidExtractionException.cxx b/src/engine/InvalidExtractionException.cxx new file mode 100644 index 000000000..74b5f122d --- /dev/null +++ b/src/engine/InvalidExtractionException.cxx @@ -0,0 +1,13 @@ +#include "InvalidExtractionException.hxx" + +using namespace YACS::ENGINE; + +const char InvalidExtractionException::TYPEOFEXCEPTION[]="Invalid runtime of YACS::Any struct : having "; + + +InvalidExtractionException::InvalidExtractionException(DynType kindExpected, DynType myKind):Exception(TYPEOFEXCEPTION) +{ + _what=TYPEOFEXCEPTION; + _what+=TypeCode::getKindRepr(kindExpected); + _what+=" and you want "; _what+=TypeCode::getKindRepr(myKind); +} diff --git a/src/engine/InvalidExtractionException.hxx b/src/engine/InvalidExtractionException.hxx new file mode 100644 index 000000000..dbd05054f --- /dev/null +++ b/src/engine/InvalidExtractionException.hxx @@ -0,0 +1,23 @@ +#ifndef __INVALIDEXTRACTIONEXCEPTION_HXX__ +#define __INVALIDEXTRACTIONEXCEPTION_HXX__ + +#include "Exception.hxx" +#include "TypeCode.hxx" + +#include + +namespace YACS +{ + namespace ENGINE + { + class InvalidExtractionException : public Exception + { + public: + InvalidExtractionException(DynType kindExpected, DynType myKind); + private: + static const char TYPEOFEXCEPTION[]; + }; + } +} + +#endif diff --git a/src/engine/LinkInfo.cxx b/src/engine/LinkInfo.cxx new file mode 100644 index 000000000..4885ec708 --- /dev/null +++ b/src/engine/LinkInfo.cxx @@ -0,0 +1,358 @@ +#include "LinkInfo.hxx" +#include "ComposedNode.hxx" + +#include + +using namespace std; +using namespace YACS::ENGINE; + +static const char GLOBAL_MESSAGE1[]="Global report : \n"; + +static const char LINK_REPR[]="link"; + +LinkInfo::LinkInfo(unsigned char level):_levelOfInfo(level),_level(0) +{ +} + +void LinkInfo::clearAll() +{ + _level=0; + _unsetInPort.clear(); + _onlyBackDefined.clear(); + _uselessLinks.clear(); + _infos.clear(); + _collapse.clear(); + _errors.clear(); +} + +void LinkInfo::startCollapseTransac() +{ + _level++; +} + +void LinkInfo::endCollapseTransac() throw(Exception) +{ + if(--_level==0) + { + if(_levelOfInfo==ALL_STOP_ASAP or _levelOfInfo==ERR_ONLY_DONT_STOP) + throw Exception(getErrRepr()); + if(_levelOfInfo==ALL_STOP_ASAP) + throw Exception(getWarnRepr()); + } +} + +void LinkInfo::setPointOfView(ComposedNode *pov) +{ + _pov=pov; +} + +void LinkInfo::pushInfoLink(OutPort *semStart, InPort *end, InfoReason reason) +{ + _infos[reason].push_back(pair(semStart,end)); +} + +void LinkInfo::pushWarnLink(OutPort *semStart, InPort *end, WarnReason reason) +{ + if(_collapse[reason].empty()) + _collapse[reason].push_back(vector< pair >()); + else + if(_collapse[reason].back()[0].second!=end) + _collapse[reason].push_back(vector< pair >()); + _collapse[reason].back().push_back(pair(semStart,end)); +} + +void LinkInfo::pushErrLink(OutPort *semStart, InPort *end, ErrReason reason) throw(Exception) +{ + if(reason==E_NEVER_SET_INPUTPORT) + _unsetInPort.push_back(end); + else if(reason==E_ONLY_BACKWARD_DEFINED) + _onlyBackDefined.push_back(end); + else + _errors[reason].push_back(pair(semStart,end)); + if(_level==0) + if(_levelOfInfo==ALL_STOP_ASAP or _levelOfInfo==ERR_ONLY_DONT_STOP) + throw Exception(getErrRepr()); +} + +void LinkInfo::pushUselessCFLink(Node *start, Node *end) +{ + _uselessLinks.insert(pair(start,end)); +} + +void LinkInfo::takeDecision() const throw(Exception) +{ + if(!_errors.empty()) + throw Exception(getErrRepr()); +} + +std::string LinkInfo::getGlobalRepr() const +{ + ostringstream retS; retS << GLOBAL_MESSAGE1; + retS << printThereIsAre(getNumberOfErrLinks(E_ALL),"error") << ".\n"; + retS << printThereIsAre(getNumberOfWarnLinksGrp(W_ALL),"warning") << ".\n"; + retS << printThereIsAre(getNumberOfInfoLinks(I_ALL),"info") << ".\n"; + if(getNumberOfErrLinks(E_ALL)>0) + { + retS << "****** ERRORS ******" << endl; + retS << getErrRepr() << endl; + } + if(getNumberOfWarnLinksGrp(W_ALL)>0) + { + retS << "****** WARNINGS ******" << endl; + retS << getWarnRepr() << endl; + } + if(getNumberOfInfoLinks(I_ALL)>0) + { + retS << "****** INFO ******" << endl; + retS << getInfoRepr() << endl; + } + return retS.str(); +} + +std::string LinkInfo::getInfoRepr() const +{ + map > >::const_iterator iter; + ostringstream stream; + for(iter=_infos.begin();iter!=_infos.end();iter++) + { + for(vector< pair >::const_iterator iter2=(*iter).second.begin();iter2!=(*iter).second.end();iter2++) + { + stream << getStringReprOfI((*iter).first) << " between \"" << _pov->getOutPortName((*iter2).first); + stream << "\" and \"" << _pov->getInPortName((*iter2).second) << "\"." << endl; + } + } + set< pair >::const_iterator iter3; + for(iter3=_uselessLinks.begin();iter3!=_uselessLinks.end();iter3++) + { + stream << getStringReprOfI(I_USELESS) << " between \"" << _pov->getChildName((*iter3).first); + stream << "\" and \"" << _pov->getChildName((*iter3).second) << "\"." << endl; + } + return stream.str(); +} + +std::string LinkInfo::getWarnRepr() const +{ + map > > >::const_iterator iter; + ostringstream stream; + unsigned i=0; + for(iter=_collapse.begin();iter!=_collapse.end();iter++) + { + stream << getStringReprOfW((*iter).first) << " for group containing following group links: "; + vector< vector< pair > >::const_iterator iter2=(*iter).second.begin(); + for(;iter2!=(*iter).second.end();iter2++) + { + stream << " Group # " << i++ << " : " << endl; + for(vector< pair >::const_iterator iter3=(*iter2).begin();iter3!=(*iter2).end();iter3++) + stream << " \"" << _pov->getOutPortName((*iter3).first) << "\" and \"" << _pov->getInPortName((*iter3).second) << endl; + } + } + return stream.str(); +} + +std::string LinkInfo::getErrRepr() const +{ + vector::const_iterator iter; + ostringstream stream; + for(iter=_unsetInPort.begin();iter!=_unsetInPort.end();iter++) + stream << getStringReprOfE(E_NEVER_SET_INPUTPORT) << "\"" << _pov->getInPortName(*iter) << "\"." << endl; + for(iter=_onlyBackDefined.begin();iter!=_onlyBackDefined.end();iter++) + stream << getStringReprOfE(E_ONLY_BACKWARD_DEFINED) << "\"" << _pov->getInPortName(*iter) << "\"." << endl; + map > >::const_iterator iter2; + for(iter2=_errors.begin();iter2!=_errors.end();iter2++) + for(vector< pair >::const_iterator iter3=(*iter2).second.begin();iter3!=(*iter2).second.end();iter3++) + stream << getStringReprOfE((*iter2).first) << " between \"" <<_pov->getOutPortName((*iter3).first) << "\" and \"" << _pov->getInPortName((*iter3).second) << endl; + return stream.str(); +} + +/*! + * If 'reason'==I_ALL returns nummmber of types of links info whereas it returns number of info per type. + */ +unsigned LinkInfo::getNumberOfInfoLinks(InfoReason reason) const +{ + if(reason==I_ALL) + return _infos.size()+_uselessLinks.size(); + if(reason==I_CF_USELESS) + return _uselessLinks.size(); + else + { + map > >::const_iterator iter=_infos.find(reason); + if(iter!=_infos.end()) + return (*iter).second.size(); + else + return 0; + } +} + +unsigned LinkInfo::getNumberOfWarnLinksGrp(WarnReason reason) const +{ + unsigned ret=0; + map > > >::const_iterator iter; + if(reason==W_ALL) + { + for(iter=_collapse.begin();iter!=_collapse.end();iter++) + ret+=(*iter).second.size(); + return ret; + } + map > > >::const_iterator iter2=_collapse.find(reason); + if(iter2!=_collapse.end()) + return (*iter2).second.size(); + else + return 0; +} + +unsigned LinkInfo::getNumberOfErrLinks(ErrReason reason) const +{ + if(reason==E_ALL) + return _errors.size()+_onlyBackDefined.size()+_unsetInPort.size(); + else if(reason==E_NEVER_SET_INPUTPORT) + return _unsetInPort.size(); + else if(reason==E_ONLY_BACKWARD_DEFINED) + return _onlyBackDefined.size(); + else + { + map > >::const_iterator iter=_errors.find(reason); + if(iter!=_errors.end()) + return (*iter).second.size(); + else + return 0; + } +} + +std::set< std::pair > LinkInfo::getInfoUselessLinks() const +{ + return _uselessLinks; +} + +std::pair LinkInfo::getInfoLink(unsigned id, InfoReason reason) const +{ + if(reason==I_CF_USELESS) + return pair(); + map > >::const_iterator iter=_infos.find(reason); + if(iter!=_infos.end()) + return (*iter).second[id]; + else + return pair(0,0); +} + +std::vector< std::pair > LinkInfo::getWarnLink(unsigned id, WarnReason reason) const +{ + map > > >::const_iterator iter=_collapse.find(reason); + if(iter!=_collapse.end()) + return (*iter).second[id]; + else + return vector< pair >(); +} + +std::pair LinkInfo::getErrLink(unsigned id, ErrReason reason) const +{ + if(reason==E_NEVER_SET_INPUTPORT) + return pair(0,_unsetInPort[id]); + else if(reason==E_ONLY_BACKWARD_DEFINED) + return pair(0,_onlyBackDefined[id]); + else + { + map > >::const_iterator iter=_errors.find(reason); + if(iter!=_errors.end()) + return (*iter).second[id]; + else + return pair(0,0); + } +} + +std::string LinkInfo::getStringReprOfI(InfoReason reason) +{ + string ret; + switch(reason) + { + case I_USELESS: + ret="Useless CF"; + break; + case I_BACK: + ret="Back"; + break; + case I_BACK_USELESS: + ret="Back and useless"; + break; + case I_BACK_CRAZY: + ret+="Crazy back"; + break; + case I_DFDS: + ret+="DF/DS"; + } + ret+=" "; ret+=LINK_REPR; + return ret; +} + +std::string LinkInfo::getStringReprOfW(WarnReason reason) +{ + string ret; + switch(reason) + { + case W_COLLAPSE: + ret="Collapse"; + break; + case W_COLLAPSE_AND_USELESS: + ret="Collapse and useless"; + break; + case W_COLLAPSE_EL: + ret="Collapse on ElementaryNode"; + break; + case W_COLLAPSE_EL_AND_USELESS: + ret+="Collapse on ElementaryNode and useless"; + break; + case W_BACK_COLLAPSE: + ret+="Back collapse"; + break; + case W_BACK_COLLAPSE_AND_USELESS: + ret+="Back collapse and useless"; + break; + case W_BACK_COLLAPSE_EL: + ret+="Back collapse on ElementaryNode"; + break; + case W_BACK_COLLAPSE_EL_AND_USELESS: + ret+="Back collapse and useless on ElementaryNode"; + } + ret+=" "; ret+=LINK_REPR; + return ret; +} + +std::string LinkInfo::getStringReprOfE(ErrReason reason) +{ + string ret; + if(reason==E_NEVER_SET_INPUTPORT) + return "Never set InPort "; + if(reason==E_ONLY_BACKWARD_DEFINED) + return "Never set InPort only back defined "; + switch(reason) + { + case E_DS_LINK_UNESTABLISHABLE: + ret="DS unestablishable"; + break; + case E_COLLAPSE_DFDS: + ret="DF/DS collapse"; + break; + case E_COLLAPSE_DS: + ret="Inter DS collapse"; + break; + case E_UNPREDICTABLE_FED: + ret="Unpredictable fed"; + } + ret+=" "; ret+=LINK_REPR; + return ret; +} + +std::string LinkInfo::printThereIsAre(unsigned val, const std::string& other) +{ + ostringstream ret; + ret << "There "; + if(val==0) + ret << "are no"; + else if(val==1) + ret << "is one"; + else + ret << "are " << val; + ret << " " << other; + if(val==0 || val>1) + ret << "s"; + return ret.str(); +} diff --git a/src/engine/LinkInfo.hxx b/src/engine/LinkInfo.hxx new file mode 100644 index 000000000..554fd31ca --- /dev/null +++ b/src/engine/LinkInfo.hxx @@ -0,0 +1,108 @@ +#ifndef __LINKINFO_HXX__ +#define __LINKINFO_HXX__ + +#include "Exception.hxx" + +#include +#include +#include +#include + +namespace YACS +{ + namespace ENGINE + { + class Node; + class InGate; + class InPort; + class OutGate; + class OutPort; + class ComposedNode; + + typedef enum + { + I_CF_USELESS = 41, + I_USELESS = 42, + I_BACK = 43,//In loop context + I_BACK_USELESS = 44,//In loop context - Not implemented yet + I_BACK_CRAZY = 45,//Out of loop context + I_DFDS = 46, + I_ALL = 49, + } InfoReason; + + typedef enum + { + W_COLLAPSE = 141, + W_COLLAPSE_AND_USELESS = 142, + W_COLLAPSE_EL = 143, + W_COLLAPSE_EL_AND_USELESS = 144, + W_BACK_COLLAPSE = 145, + W_BACK_COLLAPSE_AND_USELESS = 146, + W_BACK_COLLAPSE_EL = 147, + W_BACK_COLLAPSE_EL_AND_USELESS = 148, + W_ALL = 149 + } WarnReason; + + typedef enum + { + E_NEVER_SET_INPUTPORT = 241, + E_ONLY_BACKWARD_DEFINED = 242, + E_DS_LINK_UNESTABLISHABLE = 243, + E_COLLAPSE_DFDS = 244, + E_COLLAPSE_DS = 245, + E_UNPREDICTABLE_FED = 246, + E_ALL = 249 + } ErrReason; + + /*! + * \brief Class that deal with list of \b semantics links for high level analysis. + */ + class LinkInfo + { + private: + ComposedNode *_pov; + unsigned int _level; + unsigned char _levelOfInfo; + std::vector _unsetInPort; + std::vector _onlyBackDefined; + std::set< std::pair > _uselessLinks; + std::map > > _infos; + std::map > > > _collapse; + std::map > > _errors; + public: + LinkInfo(unsigned char level); + void clearAll(); + void startCollapseTransac(); + void endCollapseTransac() throw(Exception); + void setPointOfView(ComposedNode *pov); + void pushInfoLink(OutPort *semStart, InPort *end, InfoReason reason); + void pushWarnLink(OutPort *semStart, InPort *end, WarnReason reason); + void pushErrLink(OutPort *semStart, InPort *end, ErrReason reason) throw(Exception); + void pushUselessCFLink(Node *start, Node *end); + void takeDecision() const throw(Exception); + //Typically methods for high level use. + std::string getGlobalRepr() const; + std::string getInfoRepr() const; + std::string getWarnRepr() const; + std::string getErrRepr() const; + unsigned getNumberOfInfoLinks(InfoReason reason) const; + unsigned getNumberOfWarnLinksGrp(WarnReason reason) const; + unsigned getNumberOfErrLinks(ErrReason reason) const; + std::set< std::pair > getInfoUselessLinks() const; + std::pair getInfoLink(unsigned id, InfoReason reason) const; + std::vector< std::pair > getWarnLink(unsigned id, WarnReason reason) const; + std::pair getErrLink(unsigned id, ErrReason reason) const; + protected: + static std::string getStringReprOfI(InfoReason reason); + static std::string getStringReprOfW(WarnReason reason); + static std::string getStringReprOfE(ErrReason reason); + static std::string printThereIsAre(unsigned val, const std::string& other); + public: + static const unsigned char ALL_STOP_ASAP = 1; + static const unsigned char ALL_DONT_STOP = 2; + static const unsigned char ERR_ONLY_DONT_STOP = 3; + }; + } +} + +#endif diff --git a/src/engine/Loop.cxx b/src/engine/Loop.cxx index b9a2960b7..344a59c4b 100644 --- a/src/engine/Loop.cxx +++ b/src/engine/Loop.cxx @@ -4,134 +4,402 @@ #include "InputDataStreamPort.hxx" #include "OutputDataStreamPort.hxx" #include "Runtime.hxx" - -//#include "TypeCheckerDataStream.hxx" +#include "Visitor.hxx" +#include +#include using namespace YACS::ENGINE; using namespace std; -DFToDSForLoop::DFToDSForLoop(Loop *loop, const string& name, TypeCode* type):ElementaryNode(""),_nbOfTimeUsed(1) +InputPort4DF2DS::InputPort4DF2DS(DFToDSForLoop *node, TypeCode* type): + InputPort("", node, type), + DataPort("", node, type), + Port(node),_data(0) +{ +} + +void InputPort4DF2DS::getAllRepresentants(std::set& repr) const +{ + set s=_node->getOutputDataStreamPort("")->edSetInPort(); + repr.insert(s.begin(),s.end()); +} + +void *InputPort4DF2DS::get() const throw(Exception) +{ + if(!_data) + { + std::string what="InputPort4DF2DS::get : no value currently in input whith name \""; what+=_name; what+="\""; + throw Exception(what); + } + return (void *)_data; +} + +void InputPort4DF2DS::exRestoreInit() +{ + if(!_initValue) + return; + if(_data) + _data->decrRef(); + _data=_initValue; + _data->incrRef(); +} + +void InputPort4DF2DS::exSaveInit() +{ + if(_initValue) + _initValue->decrRef(); + _initValue=_data; + _initValue->incrRef(); +} + +void InputPort4DF2DS::put(const void *data) throw(ConversionException) +{ + put((Any *)data); +} + +InputPort *InputPort4DF2DS::clone(Node *newHelder) const +{ + throw Exception("InputPort4DF2DS::clone : internal error"); +} + +void InputPort4DF2DS::put(Any *data) +{ + if(_data) + _data->decrRef(); + _data=data; + _data->incrRef(); +} + +InputPort4DF2DS::~InputPort4DF2DS() +{ + if(_data) + _data->decrRef(); +} + +DFToDSForLoop::DFToDSForLoop(Loop *loop, const std::string& name, TypeCode* type):ElementaryNode(""),_nbOfTimeUsed(1) { _name="DF2DS For "; _name+=loop->getName(); _name+=" representing port "; _name+=name; _father=loop; -// _setOfInputPort.insert(new InputPort("",this,type)); // probleme si constructeur protege, a voir - _setOfOutputDataStreamPort.insert(new OutputDataStreamPort("",this,Loop::MappingDF2DS(type))); + _setOfInputPort.push_back(new InputPort4DF2DS(this,type)); + _setOfOutputDataStreamPort.push_back(new OutputDataStreamPort("",this,Loop::MappingDF2DS(type))); } DFToDSForLoop::~DFToDSForLoop() { } -InputPort *DFToDSForLoop::getInputPort(const string& name) const throw(Exception) +void DFToDSForLoop::getReadyTasks(std::vector& tasks) { - set::iterator it =_setOfInputPort.begin(); +} + +InputPort *DFToDSForLoop::getInputPort(const std::string& name) const throw(Exception) +{ + list::const_iterator it =_setOfInputPort.begin(); return (*it); } -OutputDataStreamPort *DFToDSForLoop::getOutputDataStreamPort(const string& name) const throw(Exception) +OutputDataStreamPort *DFToDSForLoop::getOutputDataStreamPort(const std::string& name) const throw(Exception) { - set ::iterator it =_setOfOutputDataStreamPort.begin(); + list::const_iterator it =_setOfOutputDataStreamPort.begin(); return (*it); } +void DFToDSForLoop::load() +{ +} + void DFToDSForLoop::execute() { //TO IMPLEMENT } -DSToDFForLoop::DSToDFForLoop(Loop *loop, const string& name, TypeCode* type):ElementaryNode(""),_nbOfTimeUsed(1) +Node *DFToDSForLoop::simpleClone(ComposedNode *father, bool editionOnly) const +{ + throw Exception("DFToDSForLoop::simpleClone : Internal error"); +} + +OutputPort4DS2DF::OutputPort4DS2DF(DSToDFForLoop *node, TypeCode *type): + OutputPort("", node, type), + DataPort("", node, type), + Port(node),_data(0) +{ +} + +void OutputPort4DS2DF::getAllRepresented(std::set& represented) const +{ + set setO=_node->getInputDataStreamPort("")->edSetOutPort(); + for(set::iterator iter=setO.begin();iter!=setO.end();iter++) + (*iter)->getAllRepresented(represented); +} + +void OutputPort4DS2DF::put(const void *data) throw(ConversionException) +{ + put((Any *)data); + OutputPort::put(data); +} + +OutputPort *OutputPort4DS2DF::clone(Node *newHelder) const +{ + throw Exception("OutputPort4DS2DF::clone : Internal error"); +} + +void OutputPort4DS2DF::put(Any *data) +{ + if(_data) + _data->decrRef(); + _data=data; + _data->incrRef(); +} + +OutputPort4DS2DF::~OutputPort4DS2DF() +{ + if(_data) + _data->decrRef(); +} + +InputDataStreamPort4DS2DF::InputDataStreamPort4DS2DF(DSToDFForLoop *node, TypeCode* type): + InputDataStreamPort("", node, type), + DataPort("", node, type), + Port(node) +{ +} + +void InputDataStreamPort4DS2DF::getAllRepresentants(std::set& repr) const +{ + set s=_node->getOutputPort("")->edSetInPort(); + repr.insert(s.begin(),s.end()); +} + +DSToDFForLoop::DSToDFForLoop(Loop *loop, const std::string& name, TypeCode* type):ElementaryNode(""),_nbOfTimeUsed(1) { _name="DS2DF For "; _name+=loop->getName(); _name+=" representing port "; _name+=name; _father=loop; - // _setOfOutputPort.insert(new OutputPort("",this,Loop::MappingDS2DF(type))); // probleme si constructeur protege, a voir - _setOfInputDataStreamPort.insert(new InputDataStreamPort("",this,type)); + _setOfOutputPort.push_back(new OutputPort4DS2DF(this,type)); + _setOfInputDataStreamPort.push_back(new InputDataStreamPort4DS2DF(this,type)); +} + +Node *DSToDFForLoop::simpleClone(ComposedNode *father, bool editionOnly) const +{ + throw Exception("DSToDFForLoop::simpleClone : Internal error"); } DSToDFForLoop::~DSToDFForLoop() { } -OutputPort *DSToDFForLoop::getOutputPort(const string& name) const throw(Exception) +void DSToDFForLoop::getReadyTasks(std::vector& tasks) { - set::iterator it = _setOfOutputPort.begin(); +} + +OutputPort *DSToDFForLoop::getOutputPort(const std::string& name) const throw(Exception) +{ + list::const_iterator it = _setOfOutputPort.begin(); return (*it); } -InputDataStreamPort *DSToDFForLoop::getInputDataStreamPort(const string& name) const throw(Exception) +InputDataStreamPort *DSToDFForLoop::getInputDataStreamPort(const std::string& name) const throw(Exception) { - set::iterator it = _setOfInputDataStreamPort.begin(); + list::const_iterator it = _setOfInputDataStreamPort.begin(); return (*it); } +void DSToDFForLoop::load() +{ +} + void DSToDFForLoop::execute() { //TO IMPLEMENT } -Loop::Loop(const string& name):ComposedNode(name),_node(0) +FakeNodeForLoop::FakeNodeForLoop(Loop *loop, bool normalFinish, bool internalError):ElementaryNode("thisIsAFakeNode"), + _loop(loop), + _normalFinish(normalFinish), + _internalError(internalError) +{ + setState(YACS::TOACTIVATE); + _father=_loop->getFather(); +} + +FakeNodeForLoop::FakeNodeForLoop(const FakeNodeForLoop& other):ElementaryNode(other),_loop(0), + _normalFinish(false),_internalError(true) +{ +} + +Node *FakeNodeForLoop::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new FakeNodeForLoop(*this); +} + +void FakeNodeForLoop::exForwardFailed() +{ + _loop->exForwardFailed(); + FakeNodeForLoop *normallyThis=_loop->_nodeForNullTurnOfLoops; + _loop->_nodeForNullTurnOfLoops=0; + delete normallyThis; +} + +void FakeNodeForLoop::exForwardFinished() +{ + _loop->exForwardFinished(); + FakeNodeForLoop *normallyThis=_loop->_nodeForNullTurnOfLoops; + _loop->_nodeForNullTurnOfLoops=0; + delete normallyThis; +} + +void FakeNodeForLoop::execute() +{ + if(!_normalFinish) + throw Exception("");//only to trigger ABORT on Executor +} + +void FakeNodeForLoop::aborted() +{ + if(_internalError) + _loop->setState(YACS::INTERNALERR); + else + _loop->setState(YACS::ERROR); +} + +void FakeNodeForLoop::finished() +{ + _loop->setState(YACS::DONE); +} + +Loop::Loop(const Loop& other, ComposedNode *father, bool editionOnly):StaticDefinedComposedNode(other,father),_nbOfTurns(0),_nodeForNullTurnOfLoops(0) +{ + if(other._node) + _node=other._node->simpleClone(this,editionOnly); +} + +Loop::Loop(const std::string& name):StaticDefinedComposedNode(name),_node(0),_nbOfTurns(0),_nodeForNullTurnOfLoops(0) { } Loop::~Loop() { delete _node; + delete _nodeForNullTurnOfLoops; + for(set::iterator iter1=_inputsTraducer.begin();iter1!=_inputsTraducer.end();iter1++) + delete (*iter1); + for(set::iterator iter2=_outputsTraducer.begin();iter2!=_outputsTraducer.end();iter2++) + delete (*iter2); } -void Loop::edSetNode(Node *node) +void Loop::init(bool start) { - delete _node; - _node=node; + StaticDefinedComposedNode::init(start); + _nbOfTurns=0; + if(_node) + _node->init(start); // if start is true, refresh the internal node + else + throw Exception("Loop::initLoop : no nodes specifies to be repeated "); + delete _nodeForNullTurnOfLoops; + _nodeForNullTurnOfLoops=0; } -void Loop::edAddExtraInputPort(const string& inputPortName, TypeCode* type) throw(Exception) +Node *Loop::edSetNode(Node *node) { - InputPort *ret = 0; - if (edCheckAddPort(inputPortName,_setOfInputPort,type)) + if(_node==node) + return 0; + if(node) { - //InputPort *ret=edAddPort(inputPortName,_setOfInputPort,type); - ret = getRuntime()->createInputPort(inputPortName, _implementation, this, type); - _setOfExtraInputPort.insert(ret); + if(node->_father) + { + string what = "Loop::edSetNode: node "; what += node->getName(); what += " is not orphan ! "; + throw Exception(what); + } } - //edAddPort(inputPortName,_setOfExtraInputPort,type); + StaticDefinedComposedNode::edRemoveChild(_node); + Node *ret=_node; + _node=node; + _node->_father=this; + return ret; } -void Loop::edRemoveExtraInputPort(InputPort *inputPort) +Node *Loop::edRemoveNode() { - edRemovePortTypedFromSet(inputPort,_setOfExtraInputPort); + StaticDefinedComposedNode::edRemoveChild(_node); + Node *ret=_node; + _node=0; + return ret; } -TypeCode* Loop::MappingDF2DS(TypeCode* type) throw(Exception) +//! Collect all the child nodes that are ready +/*! + * \param tasks : vector of tasks to collect ready nodes + */ +void Loop::getReadyTasks(std::vector& tasks) +{ + if(!_node) + return; + /* + * To change the way ComposedNode state is handled, uncomment the following line + * see Bloc::getReadyTasks + */ + if(_state==YACS::TOACTIVATE) setState(YACS::ACTIVATED); + if(_state==YACS::TOACTIVATE || _state==YACS::ACTIVATED) + if(_nodeForNullTurnOfLoops) + _nodeForNullTurnOfLoops->getReadyTasks(tasks); + else + { + _node->getReadyTasks(tasks); + for(set::iterator iter1=_inputsTraducer.begin();iter1!=_inputsTraducer.end();iter1++) + (*iter1)->getReadyTasks(tasks); + for(set::iterator iter2=_outputsTraducer.begin();iter2!=_outputsTraducer.end();iter2++) + (*iter2)->getReadyTasks(tasks); + } +} + +void Loop::edRemoveChild(Node *node) throw(Exception) +{ + StaticDefinedComposedNode::edRemoveChild(node); + if(_node==node) + _node=0; +} + +void Loop::selectRunnableTasks(std::vector& tasks) +{ +} + +std::set Loop::edGetDirectDescendants() const +{ + set ret; + if(_node) + ret.insert(_node); + return ret; +} + +void Loop::checkConsistency(ComposedNode *pointOfView) const throw(Exception) +{ +} + +Node *Loop::getChildByShortName(const std::string& name) const throw(Exception) { -// switch(type) -// { -// case Double: -// return SDouble; -// } - string what("Loop::MappingDF2DS : unable to perform DataFlow to DataStream traduction for dataflow type "); - //what+=Data::edGetTypeInPrintableForm(type); + if(name==_node->getName()) + return _node; + string what("node "); what+= name ; what+=" is not a child of loop node "; what += getName(); throw Exception(what); } +TypeCode* Loop::MappingDF2DS(TypeCode* type) throw(Exception) +{ + return type; +} + TypeCode* Loop::MappingDS2DF(TypeCode* type) throw(Exception) { -// 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); + return type; } -InPort *Loop::buildDelegateOf(InPort *port, const set& pointsOfView) +void Loop::buildDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView) { string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); - if(typeOfPortInstance!=InputPort::NAME) - return port; - else - if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) - return port; + if(typeOfPortInstance!=InputPort::NAME or + (typeOfPortInstance == InputPort::NAME and + initialStart->getNameOfTypeOfCurrentInstance()== OutputPort::NAME and + !isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) ) + return ; InputPort *portCasted=(InputPort *)port; set::iterator iter; //Determinig if a DSToDFForLoop node has already been created for delegation of 'port' @@ -140,52 +408,55 @@ InPort *Loop::buildDelegateOf(InPort *port, const set& pointsOfV break; if(iter==_inputsTraducer.end()) {//first time that 'port' is delegated on higher level - _inputsTraducer.insert(new DSToDFForLoop(this,portCasted->getName(),Loop::MappingDF2DS(portCasted->edGetType()))); - iter=_inputsTraducer.end(); iter--; - (*iter)->getOutputPort("")->edAddInputPort(portCasted); - //WARNING control flow has to be added - (*iter)->getOutGate()->edAddInGate(portCasted->getNode()->getInGate());//WARNING HERE MAYBE HAS TO BE IMPROVED - SEPARATE COUNTERS + pair::iterator, bool> iter2=_inputsTraducer.insert(new DSToDFForLoop(this,portCasted->getName(),Loop::MappingDF2DS(portCasted->edGetType()))); + iter=iter2.first; + (*iter)->getOutputPort("")->addInPort(portCasted); } else (*iter)->loopHasOneMoreRef(); - return (*iter)->getInputDataStreamPort(""); + port=(*iter)->getInputDataStreamPort(""); } -OutPort *Loop::buildDelegateOf(OutPort *port, const set& pointsOfView) +void Loop::buildDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) { - string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); - if(typeOfPortInstance!=OutputPort::NAME) - return port; - else - if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) - return port; - OutputPort *portCasted=(OutputPort *)port; + string typeOfPortInstance=(port.first)->getNameOfTypeOfCurrentInstance(); + if(typeOfPortInstance!=OutputPort::NAME or + ( typeOfPortInstance == OutputPort::NAME and + finalTarget->getNameOfTypeOfCurrentInstance()== InputPort::NAME and + !isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) ) + return ; + OutPort *portCasted=port.first; 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->isAlreadyInSet((*iter)->getInputPort(""))) + if(portCasted->isAlreadyLinkedWith((*iter)->getInputPort(""))) break; + DFToDSForLoop *kl; if(iter==_outputsTraducer.end()) {//first time that 'port' is delegated on higher level - _outputsTraducer.insert(new DFToDSForLoop(this,portCasted->getName(),portCasted->edGetType())); - iter=_outputsTraducer.end(); iter--; - portCasted->edAddInputPort((*iter)->getInputPort("")); - //WARNING control flow has to be added - portCasted->getNode()->getOutGate()->edAddInGate((*iter)->getInGate());//WARNING HERE MAYBE HAS TO BE IMPROVED - SEPARATE COUNTERS + //_outputsTraducer.insert(new DFToDSForLoop(this,portCasted->getName(),portCasted->edGetType())); + kl=new DFToDSForLoop(this,portCasted->getName(),portCasted->edGetType()); + pair::iterator, bool> iter2=_outputsTraducer.insert(kl); + iter=iter2.first; + portCasted->addInPort((*iter)->getInputPort("")); } else - (*iter)->loopHasOneMoreRef(); - return (*iter)->getOutputDataStreamPort(""); + { + kl=*iter; + kl->loopHasOneMoreRef(); + } + edAddLink(isInMyDescendance((port.first)->getNode())->getOutGate(),kl->getInGate()); + port.first=(*iter)->getOutputDataStreamPort(""); } -InPort *Loop::getDelegateOf(InPort *port, const set& pointsOfView) throw(Exception) +void Loop::getDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView) throw(Exception) { string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); - if(typeOfPortInstance!=InputPort::NAME) - return port; - else - if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) - return port; + if(typeOfPortInstance!=InputPort::NAME or + (typeOfPortInstance == InputPort::NAME and + initialStart->getNameOfTypeOfCurrentInstance()== OutputPort::NAME and + !isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) ) + return ; InputPort *portCasted=(InputPort *)port; set::iterator iter; for(iter=_inputsTraducer.begin();iter!=_inputsTraducer.end();iter++) @@ -193,43 +464,44 @@ InPort *Loop::getDelegateOf(InPort *port, const set& pointsOfVie break; if(iter==_inputsTraducer.end()) { - 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(""); + port=(*iter)->getInputDataStreamPort(""); } -OutPort *Loop::getDelegateOf(OutPort *port, const set& pointsOfView) throw(Exception) +void Loop::getDelegateOf(std::pair& port, InPort *finalTarget, + const std::set& pointsOfView) throw(Exception) { - string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); - if(typeOfPortInstance!=OutputPort::NAME) - return port; - else - if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) - return port; - OutputPort *portCasted=(OutputPort *)port; + string typeOfPortInstance=(port.first)->getNameOfTypeOfCurrentInstance(); + if(typeOfPortInstance!=OutputPort::NAME or + ( typeOfPortInstance == OutputPort::NAME and + finalTarget->getNameOfTypeOfCurrentInstance()== InputPort::NAME and + !isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) ) + return ; + OutPort *portCasted=port.first; set::iterator iter; for(iter=_outputsTraducer.begin();iter!=_outputsTraducer.end();iter++) - if(portCasted->isAlreadyInSet((*iter)->getInputPort(""))) + if(portCasted->isAlreadyLinkedWith((*iter)->getInputPort(""))) break; if(iter==_outputsTraducer.end()) { - 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(""); + port.first=(*iter)->getOutputDataStreamPort(""); } -InPort *Loop::releaseDelegateOf(InPort *port, const set& pointsOfView) throw(Exception) +void Loop::releaseDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView) throw(Exception) { string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); - if(typeOfPortInstance!=InputPort::NAME) - return port; - else - if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) - return port; + if(typeOfPortInstance!=InputPort::NAME or + ( typeOfPortInstance == InputPort::NAME and + initialStart->getNameOfTypeOfCurrentInstance()== OutputPort::NAME and + !isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) ) + return ; InputPort *portCasted=(InputPort *)port; set::iterator iter; for(iter=_inputsTraducer.begin();iter!=_inputsTraducer.end();iter++) @@ -242,55 +514,94 @@ InPort *Loop::releaseDelegateOf(InPort *port, const set& pointsO } else { - InPort *ret=(*iter)->getInputDataStreamPort(""); + port=(*iter)->getInputDataStreamPort(""); if((*iter)->loopHasOneLessRef()) - _inputsTraducer.erase(iter); - return ret; + { + (*iter)->getOutputPort("")->removeInPort(portCasted,false); + delete (*iter); + _inputsTraducer.erase(iter); + } } } -OutPort *Loop::releaseDelegateOf(OutPort *port, const set& pointsOfView) throw(Exception) +void Loop::releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::set& pointsOfView) throw(Exception) { - string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance(); - if(typeOfPortInstance!=OutputPort::NAME) - return port; - else - if(!isNecessaryToBuildSpecificDelegateDF2DS(pointsOfView)) - return port; - OutputPort *portCasted=(OutputPort *)port; + if(portDwn==portUp) + return ; set::iterator iter; for(iter=_outputsTraducer.begin();iter!=_outputsTraducer.end();iter++) - if(portCasted->isAlreadyInSet((*iter)->getInputPort(""))) + if((*iter)->getOutputDataStreamPort("")==portUp) break; - if(iter==_outputsTraducer.end()) + if((*iter)->loopHasOneLessRef()) { - string what("Loop::releaseDelegateOf Port with name "); what+=portCasted->getName(); what+=" not exported by loop "; what+=_name; - throw Exception(what); - } - else - { - OutPort *ret=(*iter)->getOutputDataStreamPort(""); - if((*iter)->loopHasOneLessRef()) - _outputsTraducer.erase(iter); - return ret; + portDwn->removeInPort((*iter)->getInputPort(""),false); + delete (*iter); + _outputsTraducer.erase(iter); } } void Loop::checkNoCyclePassingThrough(Node *node) throw(Exception) { - throw Exception("Loop::checkNoCyclePassingThrough : Internal error occured"); + //throw Exception("Loop::checkNoCyclePassingThrough : Internal error occured"); } -/** - * @note : States if a DF port must be considered on an upper level in hierarchy as a DS port or not from 'pointsOfView' observers. - * @return : +/*! + * \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 set& pointsOfView) +bool Loop::isNecessaryToBuildSpecificDelegateDF2DS(const std::set& pointsOfView) { bool ret=false; for(set::const_iterator iter=pointsOfView.begin();iter!=pointsOfView.end() && !ret;iter++) ret=(*iter)->isRepeatedUnpredictablySeveralTimes(); return ret; } + +//! Connect an OutPort to an InPort and add control link if necessary +/*! + * Connect the ports with a data link (edAddLink) + * In a Loop don't add control flow link : use this only to add data back links + * + * \param start : the OutPort to connect + * \param end : the InPort to connect + * \return true if a new link has been created, false otherwise. + */ +bool Loop::edAddDFLink(OutPort *start, InPort *end) throw(Exception) +{ + return edAddLink(start,end); +} + +//! Dump the node state to a stream +/*! + * \param os : the output stream + */ +void Loop::writeDot(std::ostream &os) +{ + os << " subgraph cluster_" << getId() << " {\n" ; + //only one node in a loop + _node->writeDot(os); + os << getId() << " -> " << _node->getId() << ";\n"; + os << "}\n" ; + os << getId() << "[fillcolor=\"" ; + YACS::StatesForNode state=getEffectiveState(); + os << getColorState(state); + os << "\" label=\"" << "Loop:" ; + os << getQualifiedName() <<"\"];\n"; +} + + +void Loop::accept(Visitor *visitor) +{ + visitor->visitLoop(this); +} + +/*! + * For use only when loading a previously saved execution + */ + +void YACS::ENGINE::NbDoneLoader(Loop* node, int val) +{ + node->_nbOfTurns = val; +} diff --git a/src/engine/Loop.hxx b/src/engine/Loop.hxx index f3ed0eb32..6a6caedd9 100644 --- a/src/engine/Loop.hxx +++ b/src/engine/Loop.hxx @@ -1,15 +1,38 @@ #ifndef __LOOP_HXX__ #define __LOOP_HXX__ -#include "ComposedNode.hxx" +#include "StaticDefinedComposedNode.hxx" +#include "InputDataStreamPort.hxx" #include "ElementaryNode.hxx" +#include "OutputPort.hxx" +#include "InputPort.hxx" namespace YACS { namespace ENGINE { class Loop; - + class ForLoop; + class WhileLoop; + class DFToDSForLoop; + class DSToDFForLoop; + + class InputPort4DF2DS : public InputPort + { + public: + InputPort4DF2DS(DFToDSForLoop *node, TypeCode* type); + void getAllRepresentants(std::set& repr) const; + void put(const void *data) throw(ConversionException); + InputPort *clone(Node *newHelder) const; + void *get() const throw(Exception); + void exRestoreInit(); + void exSaveInit(); + void put(Any *data); + ~InputPort4DF2DS(); + protected: + Any *_data; + }; + class DFToDSForLoop : public ElementaryNode { friend class Loop; @@ -20,14 +43,37 @@ namespace YACS DFToDSForLoop(Loop *loop, const std::string& name, TypeCode* type); void loopHasOneMoreRef() { _nbOfTimeUsed++; } bool loopHasOneLessRef() { return --_nbOfTimeUsed==0; } + void getReadyTasks(std::vector& tasks); InputPort *getInputPort(const std::string& name) const throw(Exception); OutputDataStreamPort *getOutputDataStreamPort(const std::string& name) const throw(Exception); + Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; //run part void execute(); + void load(); public: ~DFToDSForLoop(); }; + class OutputPort4DS2DF : public OutputPort + { + public: + OutputPort4DS2DF(DSToDFForLoop *node, TypeCode *type); + void getAllRepresented(std::set& represented) const; + void put(const void *data) throw(ConversionException); + OutputPort *clone(Node *newHelder) const; + void put(Any *data); + ~OutputPort4DS2DF(); + protected: + Any *_data; + }; + + class InputDataStreamPort4DS2DF : public InputDataStreamPort + { + public: + InputDataStreamPort4DS2DF(DSToDFForLoop *node, TypeCode* type); + void getAllRepresentants(std::set& repr) const; + }; + class DSToDFForLoop : public ElementaryNode { friend class Loop; @@ -36,42 +82,88 @@ namespace YACS Loop *_loopArtificiallyBuiltMe; private: DSToDFForLoop(Loop *loop, const std::string& name, TypeCode* type); + Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; void loopHasOneMoreRef() { _nbOfTimeUsed++; } bool loopHasOneLessRef() { return --_nbOfTimeUsed==0; } + void getReadyTasks(std::vector& tasks); OutputPort *getOutputPort(const std::string& name) const throw(Exception); InputDataStreamPort *getInputDataStreamPort(const std::string& name) const throw(Exception); //run part void execute(); + void load(); public: ~DSToDFForLoop(); }; - class Loop : public ComposedNode + class FakeNodeForLoop : public ElementaryNode { + friend class ForLoop; + friend class WhileLoop; + private: + Loop *_loop; + bool _normalFinish; + bool _internalError; + private: + FakeNodeForLoop(Loop *loop, bool normalFinish, bool internalError=false); + FakeNodeForLoop(const FakeNodeForLoop& other); + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + void exForwardFailed(); + void exForwardFinished(); + void execute(); + void aborted(); + void finished(); + }; + +/*! \brief Base class for loop node + * + * \ingroup Nodes + * + * \see ForLoop + * \see WhileLoop + */ + class Loop : public StaticDefinedComposedNode + { + friend class DSToDFForLoop; + friend class FakeNodeForLoop; + friend void NbDoneLoader(Loop* node, int val); protected: Node *_node; - std::set _setOfExtraInputPort; + int _nbOfTurns; + FakeNodeForLoop *_nodeForNullTurnOfLoops; std::set _inputsTraducer; std::set _outputsTraducer; public: + Loop(const Loop& other, ComposedNode *father, bool editionOnly); Loop(const std::string& name); ~Loop(); - void edSetNode(Node *node); - void edAddExtraInputPort(const std::string& inputPortName, TypeCode* type) throw(Exception); - void edRemoveExtraInputPort(InputPort *inputPort); + void init(bool start=true); + int getNbOfTurns() const { return _nbOfTurns; } + Node *edSetNode(Node *node); + Node *edRemoveNode(); + void getReadyTasks(std::vector& tasks); + void edRemoveChild(Node *node) throw(Exception); bool isRepeatedUnpredictablySeveralTimes() const { return true; } + void selectRunnableTasks(std::vector& tasks); + std::set edGetDirectDescendants() const; + void checkConsistency(ComposedNode *pointOfView) const throw(Exception); + Node *getChildByShortName(const std::string& name) const throw(Exception); static TypeCode* MappingDF2DS(TypeCode* type) throw(Exception); static TypeCode* MappingDS2DF(TypeCode* type) throw(Exception); + virtual bool edAddDFLink(OutPort *start, InPort *end) throw(Exception); + void writeDot(std::ostream &os); + virtual void accept(Visitor *visitor); protected: - 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 buildDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView); + void buildDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView); + void getDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView) throw(Exception); + void getDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) throw(Exception); + void releaseDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView) throw(Exception); + void releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::set& pointsOfView) throw(Exception); void checkNoCyclePassingThrough(Node *node) throw(Exception); static bool isNecessaryToBuildSpecificDelegateDF2DS(const std::set& pointsOfView); }; + + void NbDoneLoader(Loop* node, int val); } } diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am index 476b4cf33..250466b18 100644 --- a/src/engine/Makefile.am +++ b/src/engine/Makefile.am @@ -1,35 +1,115 @@ - include $(top_srcdir)/adm/unix/make_begin.am -SUBDIRS = Test +SUBDIRS = Plugin Test lib_LTLIBRARIES = libYACSEngine.la -libYACSEngine_la_SOURCES = \ - TypeCode.cxx \ - ConversionException.cxx \ - Port.cxx InGate.cxx \ - OutGate.cxx \ - DataFlowPort.cxx \ - InPort.cxx \ - OutPort.cxx \ - InputPort.cxx \ - OutputPort.cxx \ - DataStreamPort.cxx \ - InputDataStreamPort.cxx \ - OutputDataStreamPort.cxx \ - Node.cxx \ - ElementaryNode.cxx \ - ComposedNode.cxx \ - Bloc.cxx \ - Loop.cxx \ - Switch.cxx \ - Runtime.cxx \ - Scheduler.hxx \ - Task.hxx \ - Executor.cxx \ +libYACSEngine_la_SOURCES = \ + TypeCode.cxx \ + RefCounter.cxx \ + LinkInfo.cxx \ + ConversionException.cxx \ + InvalidExtractionException.cxx \ + ConditionInputPort.cxx \ + AnyInputPort.cxx \ + Port.cxx InGate.cxx \ + OutGate.cxx \ + DataPort.cxx \ + DataFlowPort.cxx \ + InPort.cxx \ + OutPort.cxx \ + InputPort.cxx \ + OutputPort.cxx \ + DataStreamPort.cxx \ + InputDataStreamPort.cxx \ + OutputDataStreamPort.cxx \ + Any.cxx \ + Pool.cxx \ + Node.cxx \ + ElementaryNode.cxx \ + ComposedNode.cxx \ + InlineNode.cxx \ + ServiceNode.cxx \ + ServiceInlineNode.cxx \ + StaticDefinedComposedNode.cxx \ + Bloc.cxx \ + Proc.cxx \ + Loop.cxx \ + ForLoop.cxx \ + WhileLoop.cxx \ + Switch.cxx \ + DynParaLoop.cxx \ + ForEachLoop.cxx \ + OptimizerAlg.cxx \ + OptimizerLoop.cxx \ + Runtime.cxx \ + Scheduler.hxx \ + Task.hxx \ + Executor.cxx \ + Visitor.cxx \ + VisitorSaveState.cxx \ + VisitorSaveSchema.cxx \ + ComponentInstance.cxx \ + Dispatcher.cxx \ + Container.cxx \ + DeploymentTree.cxx \ $(__dummy__) +salomeinclude_HEADERS = \ + Any.hxx \ + AnyInputPort.hxx \ + Bloc.hxx \ + ComponentInstance.hxx \ + ComposedNode.hxx \ + ConditionInputPort.hxx \ + Container.hxx \ + ConversionException.hxx \ + DataFlowPort.hxx \ + DataPort.hxx \ + DataStreamPort.hxx \ + DeploymentTree.hxx \ + Dispatcher.hxx \ + DynParaLoop.hxx \ + ElementaryNode.hxx \ + Executor.hxx \ + ExecutorSwig.hxx \ + ForEachLoop.hxx \ + ForLoop.hxx \ + InGate.hxx \ + InlineNode.hxx \ + InPort.hxx \ + InputDataStreamPort.hxx \ + InputPort.hxx \ + InvalidExtractionException.hxx \ + LinkInfo.hxx \ + Loop.hxx \ + Node.hxx \ + OptimizerAlg.hxx \ + OptimizerLoop.hxx \ + OutGate.hxx \ + OutPort.hxx \ + OutputDataStreamPort.hxx \ + OutputPort.hxx \ + Pool.hxx \ + Port.hxx \ + Proc.hxx \ + RefCounter.hxx \ + Runtime.hxx \ + Scheduler.hxx \ + ServiceInlineNode.hxx \ + ServiceNode.hxx \ + SharedPtr.hxx \ + StaticDefinedComposedNode.hxx \ + Switch.hxx \ + Task.hxx \ + TypeCode.hxx \ + Visitor.hxx \ + VisitorSaveSchema.hxx \ + VisitorSaveState.hxx \ + WhileLoop.hxx \ + $(__dummy__) + + EXTRA_libYACSEngine_la_SOURCES = \ $(__dummy__) @@ -38,4 +118,29 @@ libYACSEngine_la_LIBADD = ../bases/libYACSBases.la AM_CXXFLAGS = $(THREAD_DEF) \ -I$(srcdir)/../bases + +BUILT_SOURCES = pilotWRAP.cxx + +MYSWIG_FLAGS = -noexcept -I$(srcdir)/../bases + +pkgpython_PYTHON = pilot.py +pkgpyexec_LTLIBRARIES = _pilot.la + +pilotWRAP.cxx:pilot.i InlineNode.hxx ServiceNode.hxx + $(SWIG) $(SWIG_PYTHON_OPT) $(SWIG_PYTHON_INCLUDES) $(MYSWIG_FLAGS) -o $@ $< + +_pilot_la_SOURCES = \ + pilotWRAP.cxx \ + ExecutorSwig.cxx + +_pilot_la_CXXFLAGS = \ + $(THREAD_DEF) \ + $(PYTHON_CPPFLAGS) \ + -I$(srcdir)/../bases + +_pilot_la_LDFLAGS = -module + +_pilot_la_LIBADD = libYACSEngine.la + + include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/engine/Node.cxx b/src/engine/Node.cxx index 5f08eea00..1febe8749 100644 --- a/src/engine/Node.cxx +++ b/src/engine/Node.cxx @@ -2,14 +2,36 @@ #include "InputPort.hxx" #include "OutputPort.hxx" #include "ComposedNode.hxx" +#include "Dispatcher.hxx" #include "InputDataStreamPort.hxx" #include "OutputDataStreamPort.hxx" +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" using namespace YACS::ENGINE; using namespace std; -Node::Node(const string& name):_name(name),_inGate(this),_outGate(this),_father(0),_colour(YACS::White),_state(YACS::INITED) +const char Node::SEP_CHAR_IN_PORT[]="."; + +int Node::_total = 0; +std::map Node::idMap; + +Node::Node(const std::string& name):_name(name),_inGate(this),_outGate(this),_father(0),_state(YACS::INITED), + _implementation(Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME) { + // Should be protected by lock ?? + _numId = _total++; + idMap[_numId]=this; +} + +Node::Node(const Node& other, ComposedNode *father):_inGate(this),_outGate(this),_name(other._name),_father(father), + _state(YACS::INITED),_implementation(other._implementation), + _propertyMap(other._propertyMap) +{ + _numId = _total++; + idMap[_numId]=this; } Node::~Node() @@ -20,17 +42,23 @@ Node::~Node() * initialisation of all input and output ports and gates, for execution */ -void Node::init() +void Node::init(bool start) { _inGate.exReset(); - for(set::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++) - (*iter)->exInit(); - for(set::iterator iter2=_setOfInputPort.begin();iter2!=_setOfInputPort.end();iter2++) - (*iter2)->exInit(); - if(_inGate.exIsReady()) - _state=YACS::TOACTIVATE; - else - _state=YACS::INITED; + _outGate.exReset(); + if(_state == YACS::DISABLED) + { + exDisabledState(); // to refresh propagation of DISABLED state + return; + } + setState(YACS::INITED); +} + +Node *Node::clone(ComposedNode *father, bool editionOnly) const +{ + Node *ret=simpleClone(father,editionOnly); + ret->performDuplicationOfPlacement(*this); + return ret; } /** @@ -46,65 +74,116 @@ set Node::getOutNodes() const return ret; } -/** - * @note : Update the '_state' attribute. +bool Node::exIsControlReady() const +{ + return _inGate.exIsReady(); +} + +/*! + * \note : Update the '_state' attribute. * Typically called by 'this->_inGate' when 'this->_inGate' is ready. + * + * Called by InGate::exNotifyFromPrecursor */ void Node::exUpdateState() { + if(_state==YACS::DISABLED)return; if(_inGate.exIsReady()) - if(areAllInputPortsValid()) - _state=YACS::TOACTIVATE; - else - { - 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); - } + setState(YACS::TOACTIVATE); } -int Node::getNumberOfInputPorts() const +//! Notify this node that its execution has failed +/*! + * The node goes in FAILED state and + * propagate the notification through the outGate port + * + */ +void Node::exFailedState() { - return _setOfInputPort.size(); + DEBTRACE( "Node::exFailedState: " << getName() ); + setState(YACS::FAILED); + _outGate.exNotifyFailed(); } -int Node::getNumberOfOutputPorts() const +//! Notify this node that it has been disabled +/*! + * The node goes in DISABLED state and + * propagate the notification through the outGate port + * + */ +void Node::exDisabledState() { - return _setOfOutputPort.size(); + DEBTRACE( "Node::exDisabledState: " << getName() ); + setState(YACS::DISABLED); + _outGate.exNotifyDisabled(); } -InputPort *Node::getInputPort(const string& name) const throw(Exception) +InPort *Node::getInPort(const std::string& name) const throw(Exception) { - return getPort(name,_setOfInputPort); + InPort *ret; + try + { + ret=getInputPort(name); + } + catch(Exception& e) + { + ret=getInputDataStreamPort(name); + } + return ret; } -OutputPort *Node::getOutputPort(const string& name) const throw(Exception) +/*! + * \note: Contrary to getOutputPort method, this method returns the output port at highest level, possible. + * That is to say in some ComposedNode, like ForEachLoop or Switch, an outport inside 'this' is seen differently than the true outport. + */ +OutPort *Node::getOutPort(const std::string& name) const throw(Exception) { - return getPort(name,_setOfOutputPort); + OutPort *ret; + try + { + ret=getOutputPort(name); + } + catch(Exception& e) + { + ret=getOutputDataStreamPort(name); + } + return ret; } -InputDataStreamPort *Node::getInputDataStreamPort(const string& name) const throw(Exception) +std::list Node::getSetOfInPort() const { - return getPort(name,_setOfInputDataStreamPort); + list ret; + list data=getSetOfInputPort(); + ret.insert(ret.end(),data.begin(),data.end()); + list ds=getSetOfInputDataStreamPort(); + ret.insert(ret.end(),ds.begin(),ds.end()); + return ret; } -OutputDataStreamPort *Node::getOutputDataStreamPort(const string& name) const throw(Exception) +std::list Node::getSetOfOutPort() const { - return getPort(name,_setOfOutputDataStreamPort); + list ret; + list data=getSetOfOutputPort(); + ret.insert(ret.end(),data.begin(),data.end()); + list ds=getSetOfOutputDataStreamPort(); + ret.insert(ret.end(),ds.begin(),ds.end()); + return ret; } - /** * gets a set of the composed nodes that constitute the ascendancy of this node, starting from root * or from a particular ancestor + * \b WARNING : returned set is not sorted ! * @param levelToStop composed node which is the oldest ancestor required * @return ascendancy, direct father first in set. */ -set Node::getAllAscendanceOf(ComposedNode *levelToStop) +std::set Node::getAllAscendanceOf(ComposedNode *levelToStop) { set ret; + if(this==levelToStop) + return ret; for(ComposedNode *iter=_father;iter!=levelToStop && iter!=0; iter=iter->_father) ret.insert(iter); return ret; @@ -122,20 +201,49 @@ 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 +//! Becomes deprecated soon. Replaced by ComposedNode::CheckConsistency. +set Node::edGetSetOfUnitializedInputPort() const { - bool ret=true; - for(set::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + set setOfUnitializedInputPort; + list allOfInputPorts=getSetOfInputPort(); + for(list::const_iterator iter=allOfInputPorts.begin();iter!=allOfInputPorts.end();iter++) { - ret=!(*iter)->isEmpty(); - if (!ret) break; + if ( ! (*iter)->edIsInitialized() ) + setOfUnitializedInputPort.insert(*iter); } - return ret; + return setOfUnitializedInputPort; +} + +//! Becomes deprecated soon. Replaced by ComposedNode::CheckConsistency. +bool Node::edAreAllInputPortInitialized() const +{ + set setOfUnitializedInputPort = edGetSetOfUnitializedInputPort(); + return ( setOfUnitializedInputPort.size() == 0); +} + +/*! + * Called typically by Bloc to notify failure on potentially next nodes on the same scope of 'this' + */ +void Node::exForwardFailed() +{ + _outGate.exNotifyFailed(); +} + +/*! + * Called typically by Bloc to activate potentially next nodes on the same scope of 'this' + */ +void Node::exForwardFinished() +{ + _outGate.exNotifyDone(); +} + +/*! + * Called typically by ComposedNode to correctly update DF/CF/DS links + */ +void Node::edDisconnectAllLinksWithMe() +{ + _inGate.edDisconnectAllLinksToMe(); + _outGate.edDisconnectAllLinksFromMe(); } ComposedNode *Node::getRootNode() throw(Exception) @@ -153,7 +261,7 @@ ComposedNode *Node::getRootNode() throw(Exception) * USAGE NOT CLEAR, not used so far, when are those characters set ? */ -void Node::checkValidityOfPortName(const string& name) throw(Exception) +void Node::checkValidityOfPortName(const std::string& name) throw(Exception) { if(name.find(SEP_CHAR_IN_PORT, 0 )!=string::npos) { @@ -171,20 +279,170 @@ ComposedNode *Node::checkHavingCommonFather(Node *node1, Node *node2) throw(Exce if(node1!=0 && node2!=0) { if(node1->_father==node2->_father) - return node1->_father; + return node1->_father; } throw Exception("check failed : nodes have not the same father"); } -/** - * set color for inGates : display - * USAGE NOT CLEAR, not used so far +const std::string Node::getId() +{ + std::string id=getRootNode()->getName(); + if(getRootNode() != this) + id= id+'.'+ getRootNode()->getChildName(this); + string::size_type debut =id.find_first_of('.'); + while(debut != std::string::npos){ + id[debut]='_'; + debut=id.find_first_of('.',debut); + } + return id; +} + +void Node::setProperty(const std::string& name, const std::string& value) +{ + _propertyMap[name]=value; +} + +//! Return the node state in the context of its father +/*! + * \return the effective node state + * + * The node state is stored in a private attribute _state. + * This state is relative to its father state : a node with a + * TOACTIVATE state with a father node in a INITED state is not + * to activate. Its effective state is only INITED. + * This method returns the effective state of the node taking + * into account that of its father. */ +YACS::StatesForNode Node::getEffectiveState() +{ + if(!_father) //the root node + return _state; + if(_state==YACS::DISABLED) + return YACS::DISABLED; + return _father->getEffectiveState(this); +} -void Node::initForDFS() const +//! Return the effective state of a node in the context of this one (its father) +/*! + * \param node: the node which effective state is queried + * \return the effective node state + */ +YACS::StatesForNode Node::getEffectiveState(Node* node) { - _colour=YACS::White; - set inGates=_outGate.edSetInGate(); - for(set::iterator iter=inGates.begin();iter!=inGates.end();iter++) - (*iter)->initForDFS(); + if(node->getState()==YACS::DISABLED) + return YACS::DISABLED; + + YACS::StatesForNode effectiveState=getEffectiveState(); + switch(effectiveState) + { + case YACS::INITED: + return YACS::INITED; + case YACS::TOACTIVATE: + return YACS::INITED; + case YACS::DISABLED: + return YACS::DISABLED; + case YACS::ERROR: + return YACS::FAILED; + default: + return node->getState(); + } +} + +//! Return the color associated to a state +/*! + * \param state : the node state + * \return the associated color + */ +std::string Node::getColorState(YACS::StatesForNode state) +{ + switch(state) + { + case YACS::INITED: + return "pink"; + case YACS::TOLOAD: + return "magenta"; + case YACS::LOADED: + return "magenta"; + case YACS::TOACTIVATE: + return "purple"; + case YACS::ACTIVATED: + return "blue"; + case YACS::DONE: + return "green"; + case YACS::ERROR: + return "red"; + case YACS::FAILED: + return "orange"; + case YACS::DISABLED: + return "grey"; + case YACS::PAUSE: + return "white"; + default: + return "white"; + } +} + +//! Dump to the input stream a dot representation of the node +/*! + * \param os : the input stream + */ +void Node::writeDot(std::ostream &os) +{ + os << getId() << "[fillcolor=\"" ; + YACS::StatesForNode state=getEffectiveState(); + os << getColorState(state); + os << "\" label=\"" << getImplementation() << "Node:" ; + os << getQualifiedName() <<"\"];\n"; +} + +//! same as Node::getName() in most cases, but differs for children of switch +/*! + * used by writeDot to distinguish children of switch, by adding a prefix to the name. + * prefix is built on case id. + */ + +std::string Node::getQualifiedName() const +{ + if(_father) + return _father->getMyQualifiedName(this); + return getName(); +} + +//! return node instance identifiant, unique for each node instance +/*! + * node instance identifiant is used to check if to nodes pointers refers to the same instance + */ +int Node::getNumId() +{ + return _numId; +} + +//! Sets the given state for node. +/*! It is strongly recommended to use this function if you want to + * change the state of the node, instead of direct access to _state field (_state = ...). + */ +void Node::setState(YACS::StatesForNode theState) +{ + _state = theState; + // emit notification to all observers registered with the dispatcher on any change of the node's state + sendEvent("status"); +} + +//! emit notification to all observers registered with the dispatcher +/*! + * The dispatcher is unique and can be obtained by getDispatcher() + */ +void Node::sendEvent(const std::string& event) +{ + Dispatcher* disp=Dispatcher::getDispatcher(); + disp->dispatch(this,event); +} + +/*! + * For use only when loading a previously saved execution + */ + +void YACS::ENGINE::StateLoader(Node* node, YACS::StatesForNode state) +{ + node->setState(state); } diff --git a/src/engine/Node.hxx b/src/engine/Node.hxx index fda509861..7f72ee2a0 100644 --- a/src/engine/Node.hxx +++ b/src/engine/Node.hxx @@ -9,164 +9,127 @@ #include #include #include +#include namespace YACS { namespace ENGINE { class Task; + class InPort; + class OutPort; class InputPort; class OutputPort; + class DynParaLoop; + class ForEachLoop; class ComposedNode; class ElementaryNode; + class Switch; class InputDataStreamPort; class OutputDataStreamPort; + class Visitor; +/*! \brief Base class for all nodes + * + * \ingroup Nodes + * + * + */ class Node { friend class Bloc; + friend class Loop; + friend class Switch; + friend class InputPort; + friend class OutputPort; + friend class DynParaLoop; + friend class ForEachLoop; friend class ComposedNode; friend class ElementaryNode; + friend class Visitor; + friend void StateLoader(Node* node, YACS::StatesForNode state); + public: + mutable YACS::Colour _colour; protected: InGate _inGate; OutGate _outGate; std::string _name; ComposedNode *_father; YACS::StatesForNode _state; - std::set _setOfInputPort; - std::set _setOfOutputPort; - std::set _setOfInputDataStreamPort; - std::set _setOfOutputDataStreamPort; - static const char SEP_CHAR_IN_PORT='?'; + static const char SEP_CHAR_IN_PORT[]; + static int _total; + int _numId; std::string _implementation; - private: - //for graphs algorithms - mutable YACS::Colour _colour; + std::map _propertyMap; protected: Node(const std::string& name); + Node(const Node& other, ComposedNode *father); + virtual void performDuplicationOfPlacement(const Node& other) = 0; + virtual Node *simpleClone(ComposedNode *father, bool editionOnly=true) const = 0; public: virtual ~Node(); - virtual void init(); + virtual void init(bool start=true); + //! \b This method \b MUST \b NEVER \b BE \b VIRTUAL + Node *clone(ComposedNode *father, bool editionOnly=true) const; + void setState(YACS::StatesForNode theState); // To centralize state changes + virtual YACS::StatesForNode getState() const { return _state; } + virtual YACS::StatesForNode getEffectiveState(); + virtual YACS::StatesForNode getEffectiveState(Node*); + std::string getColorState(YACS::StatesForNode state); InGate *getInGate() { return &_inGate; } OutGate *getOutGate() { return &_outGate; } const std::string& getName() const { return _name; } + ComposedNode * getFather() const { return _father; } + const std::string getId(); + bool exIsControlReady() const; std::set getOutNodes() const; + virtual void writeDot(std::ostream &os); virtual void exUpdateState(); + virtual void exFailedState(); + virtual void exDisabledState(); virtual void getReadyTasks(std::vector& tasks) = 0; - virtual std::set getRecursiveConstituents() = 0; - virtual int getNumberOfInputPorts() const; - virtual int getNumberOfOutputPorts() const; - 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 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); + virtual std::set getRecursiveConstituents() const = 0; + virtual int getNumberOfInputPorts() const = 0; + virtual int getNumberOfOutputPorts() const = 0; + std::list getSetOfInPort() const; + std::list getSetOfOutPort() const; + virtual std::list getSetOfInputPort() const = 0; + virtual std::list getSetOfOutputPort() const = 0; + virtual std::list getLocalInputPorts() const = 0; + virtual std::list getLocalOutputPorts() const = 0; + virtual std::set edGetSetOfUnitializedInputPort() const; + virtual bool edAreAllInputPortInitialized() const; + virtual std::string getInPortName(const InPort *) const throw (Exception) = 0; + virtual std::string getOutPortName(const OutPort *) const throw (Exception) = 0; + virtual std::list getSetOfInputDataStreamPort() const = 0; + virtual std::list getSetOfOutputDataStreamPort() const = 0; + InPort *getInPort(const std::string& name) const throw(Exception); + virtual OutPort *getOutPort(const std::string& name) const throw(Exception); + virtual std::set getAllOutPortsLeavingCurrentScope() const = 0; + virtual std::set getAllInPortsComingFromOutsideOfCurrentScope() const = 0; + virtual InputPort *getInputPort(const std::string& name) const throw(Exception) = 0; + virtual OutputPort *getOutputPort(const std::string& name) const throw(Exception) = 0; + virtual InputDataStreamPort *getInputDataStreamPort(const std::string& name) const throw(Exception) = 0; + virtual OutputDataStreamPort *getOutputDataStreamPort(const std::string& name) const throw(Exception) = 0; std::set getAllAscendanceOf(ComposedNode *levelToStop = 0); std::string getImplementation(); - protected: - bool areAllInputPortsValid() const; virtual ComposedNode *getRootNode() throw(Exception); - virtual void disconnectAllLinksConnectedTo(Node *node) = 0; + virtual void setProperty(const std::string& name,const std::string& value); + virtual Node *getChildByName(const std::string& name) const throw(Exception) = 0; + virtual void accept(Visitor *visitor) = 0; + std::string getQualifiedName() const; + int getNumId(); + virtual void sendEvent(const std::string& event); + static std::map idMap; + protected: + virtual void exForwardFailed(); + virtual void exForwardFinished(); + virtual void edDisconnectAllLinksWithMe(); 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::set& setOfPorts) const throw(Exception); - template - 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 edRemovePortTypedFromSet(PORT *port, std::set& setOfPorts) throw(Exception); - template - 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::set& setOfPorts) const throw(Exception) - { - for(typename std::set::const_iterator iter=setOfPorts.begin();iter!=setOfPorts.end();iter++) - { - if((*iter)->getName()==name) - return *iter; - } - std::string what="Node::getPort : unexisting "; what+=PORT::NAME; - what+=" with name "; - what+=name; - throw Exception(what); - } - - /** - * 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::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()->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::edRemovePortTypedFromSet(PORT *port, std::set& setOfPorts) throw(Exception) - { - 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::set& setOfPorts) - { - for(typename std::set::const_iterator iter=setOfPorts.begin();iter!=setOfPorts.end();iter++) - { - if((*iter)->getName()==portName) - return true; - } - return false; - } + void StateLoader(Node* node, YACS::StatesForNode state); } } diff --git a/src/engine/OptimizerAlg.cxx b/src/engine/OptimizerAlg.cxx new file mode 100644 index 000000000..9d9d05da6 --- /dev/null +++ b/src/engine/OptimizerAlg.cxx @@ -0,0 +1,37 @@ +#include "OptimizerAlg.hxx" + +using namespace YACS::ENGINE; + +OptimizerAlgBase::OptimizerAlgBase(Pool *pool):_pool(pool) +{ +} + +OptimizerAlgBase::~OptimizerAlgBase() +{ +} + +OptimizerAlgSync::OptimizerAlgSync(Pool *pool):OptimizerAlgBase(pool) +{ +} + +OptimizerAlgSync::~OptimizerAlgSync() +{ +} + +TypeOfAlgInterface OptimizerAlgSync::getType() const +{ + return EVENT_ORIENTED; +} + +OptimizerAlgASync::OptimizerAlgASync(Pool *pool):OptimizerAlgBase(pool) +{ +} + +OptimizerAlgASync::~OptimizerAlgASync() +{ +} + +TypeOfAlgInterface OptimizerAlgASync::getType() const +{ + return NOT_EVENT_ORIENTED; +} diff --git a/src/engine/OptimizerAlg.hxx b/src/engine/OptimizerAlg.hxx new file mode 100644 index 000000000..a9a2dde9e --- /dev/null +++ b/src/engine/OptimizerAlg.hxx @@ -0,0 +1,81 @@ +#ifndef __OPTIMIZERALG_HXX__ +#define __OPTIMIZERALG_HXX__ + +#include "RefCounter.hxx" +#include "Exception.hxx" +#include "DrivenCondition.hxx" + +#include + +namespace YACS +{ + namespace ENGINE + { + class Any; + class Pool; + class TypeCode; + + typedef enum + { + EVENT_ORIENTED = 26, + NOT_EVENT_ORIENTED = 28 + } TypeOfAlgInterface; + + /*! + * \brief Base class factorizing common methods for all algorithms interfaces. + */ + class OptimizerAlgBase : public RefCounter + { + protected: + Pool *_pool; + protected: + OptimizerAlgBase(Pool *pool); + virtual ~OptimizerAlgBase(); + public: + //! returns typecode of type expected as Input. OwnerShip of returned pointer is held by this. + virtual TypeCode *getTCForIn() const = 0; + //! returns typecode of type expected as Output. OwnerShip of returned pointer is held by this. + virtual TypeCode *getTCForOut() const = 0; + virtual void parseFileToInit(const std::string& fileName) = 0; + virtual TypeOfAlgInterface getType() const = 0; + virtual void initialize(const Any *input) throw (Exception) = 0; + virtual void finish() = 0;//! Called when optimization has succeed. + }; + + /*! + * \brief Base class to implement in external dynamic lib in case of optimizer event oriented. + */ + class OptimizerAlgSync : public OptimizerAlgBase + { + protected: + OptimizerAlgSync(Pool *pool); + public: + TypeOfAlgInterface getType() const; + virtual ~OptimizerAlgSync(); + virtual void start() = 0;//! Update _pool attribute before performing anything. + virtual void takeDecision() = 0;//! _pool->getCurrentId gives the \b id at the origin of this call. + //! Perform the job of analysing to know what new jobs to do (_pool->pushInSample) + //! or in case of convergence _pool->destroyAll + }; + + /*! + * \brief Base class to implement in external dynamic lib in case of optimizer non event oriented. + */ + class OptimizerAlgASync : public OptimizerAlgBase + { + protected: + OptimizerAlgASync(Pool *pool); + public: + TypeOfAlgInterface getType() const; + virtual ~OptimizerAlgASync(); + virtual void startToTakeDecision(::YACS::BASES::DrivenCondition *condition) = 0;//! _pool->getCurrentId gives the \b id at the origin of this call. + //! Perform the job between 2 'condition->wait()' of analysing to know what new jobs to do + //! (_pool->pushInSample) or in case of convergence _pool->destroyAll + //! WARNING ! 'condition->wait()' must be called before any analyse of Pool. + }; + + typedef OptimizerAlgBase *(*OptimizerAlgBaseFactory)(Pool *pool); + } +} + +#endif diff --git a/src/engine/OptimizerLoop.cxx b/src/engine/OptimizerLoop.cxx new file mode 100644 index 000000000..f1ded1304 --- /dev/null +++ b/src/engine/OptimizerLoop.cxx @@ -0,0 +1,549 @@ +#include "OptimizerLoop.hxx" +#include "OutputPort.hxx" + +#include + +using namespace YACS::ENGINE; +using namespace std; + +const char FakeNodeForOptimizerLoop::NAME[]="thisIsAFakeNode"; + +const int OptimizerLoop::NOT_RUNNING_BRANCH_ID=-1979020617; + +const char OptimizerLoop::NAME_OF_FILENAME_INPUT[]="FileNameInitAlg"; + +const char OptimizerLoop::NAME_OF_OUT_POOL_INPUT[]="retPortForOutPool"; + +OptimizerAlgStandardized::OptimizerAlgStandardized(Pool *pool, OptimizerAlgBase *alg) + : OptimizerAlgSync(pool),_algBehind(alg),_threadInCaseOfNotEvent(0) +{ + if(_algBehind) + _algBehind->incrRef(); +} + +OptimizerAlgStandardized::~OptimizerAlgStandardized() +{ + if(_algBehind) + _algBehind->decrRef(); +} + +TypeCode *OptimizerAlgStandardized::getTCForIn() const +{ + return _algBehind->getTCForIn(); +} + +TypeCode *OptimizerAlgStandardized::getTCForOut() const +{ + return _algBehind->getTCForOut(); +} + +void OptimizerAlgStandardized::setAlgPointer(OptimizerAlgBaseFactory algFactory) +{ + if(_algBehind) + _algBehind->decrRef(); + _algBehind=algFactory(_pool); +} + +void OptimizerAlgStandardized::parseFileToInit(const std::string& fileName) +{ + _algBehind->parseFileToInit(fileName); +} + +void OptimizerAlgStandardized::initialize(const Any *input) throw (Exception) +{ + _algBehind->initialize(input); +} + +void OptimizerAlgStandardized::takeDecision() +{ + switch(_algBehind->getType()) + { + case EVENT_ORIENTED: + { + ((OptimizerAlgSync *) _algBehind)->takeDecision(); + break; + } + case NOT_EVENT_ORIENTED: + { + _condition.notifyOneSync(); + break; + } + default: + throw Exception("Unrecognized type of algorithm. Only 2 types are available : EVENT_ORIENTED or NOT_EVENT_ORIENTED."); + } +} + +void OptimizerAlgStandardized::finish() +{ + _algBehind->finish(); +} + +void OptimizerAlgStandardized::start() +{ + switch(_algBehind->getType()) + { + case EVENT_ORIENTED: + { + ((OptimizerAlgSync *) _algBehind)->start(); + break; + } + case NOT_EVENT_ORIENTED: + { + void **stackForNewTh= new void* [2]; + stackForNewTh[0]=(void *) ((OptimizerAlgASync *)(_algBehind));//In case of virtual inheritance + stackForNewTh[1]=(void *) &_condition; + _threadInCaseOfNotEvent=new ::YACS::BASES::Thread(threadFctForAsync,stackForNewTh); + _condition.waitForAWait(); + break; + } + default: + throw Exception("Unrecognized type of algorithm. Only 2 types are available : EVENT_ORIENTED or NOT_EVENT_ORIENTED."); + } +} + +void *OptimizerAlgStandardized::threadFctForAsync(void* ownStack) +{ + void **ownStackCst=(void **)ownStack; + OptimizerAlgASync *alg=(OptimizerAlgASync *)ownStackCst[0]; + ::YACS::BASES::DrivenCondition *cond=(::YACS::BASES::DrivenCondition *)ownStackCst[1]; + delete [] ownStackCst; + alg->startToTakeDecision(cond); +} + +FakeNodeForOptimizerLoop::FakeNodeForOptimizerLoop(OptimizerLoop *loop, bool normal, unsigned reason):ElementaryNode(NAME),_loop(loop), + _normal(normal), + _reason(reason) +{ + _state=YACS::TOACTIVATE; + _father=_loop->getFather(); +} + +FakeNodeForOptimizerLoop::FakeNodeForOptimizerLoop(const FakeNodeForOptimizerLoop& other):ElementaryNode(other),_loop(0), + _normal(false) +{ +} + +Node *FakeNodeForOptimizerLoop::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new FakeNodeForOptimizerLoop(*this); +} + +void FakeNodeForOptimizerLoop::exForwardFailed() +{ + _loop->exForwardFailed(); + FakeNodeForOptimizerLoop *normallyThis=_loop->_nodeForSpecialCases; + _loop->_nodeForSpecialCases=0; + delete normallyThis; +} + +void FakeNodeForOptimizerLoop::exForwardFinished() +{ + _loop->exForwardFinished(); + FakeNodeForOptimizerLoop *normallyThis=_loop->_nodeForSpecialCases; + _loop->_nodeForSpecialCases=0; + delete normallyThis; +} + +void FakeNodeForOptimizerLoop::execute() +{ + if(!_normal) + { + string what; + if(_reason==ALG_WITHOUT_START_CASES) + what="Alg initialization of optimizerNode with name "; what+=_loop->getName(); what+=" returns no new case(s) to launch"; + throw Exception(what); + } +} + +void FakeNodeForOptimizerLoop::aborted() +{ + _loop->_state=YACS::ERROR; +} + +void FakeNodeForOptimizerLoop::finished() +{ + +} + +OptimizerLoop::OptimizerLoop(const std::string& name, const std::string& algLibWthOutExt, + const std::string& symbolNameToOptimizerAlgBaseInstanceFactory, + bool algInitOnFile) throw(Exception) + try : DynParaLoop(name,Runtime::_tc_string),_loader(algLibWthOutExt),_algInitOnFile(algInitOnFile), + _portForInitFile(NAME_OF_FILENAME_INPUT,this,Runtime::_tc_string), + _alg(new OptimizerAlgStandardized(&_myPool,0)),_convergenceReachedWithOtherCalc(false), + _retPortForOutPool(NAME_OF_OUT_POOL_INPUT,this,Runtime::_tc_string), + _nodeForSpecialCases(0),_symbol(symbolNameToOptimizerAlgBaseInstanceFactory) +{ + OptimizerAlgBaseFactory algFactory=(OptimizerAlgBaseFactory)_loader.getHandleOnSymbolWithName(_symbol); + if(!algFactory) + throw Exception("Problem during library loading."); + _alg->setAlgPointer(algFactory); + _splittedPort.edSetType(_alg->getTCForIn()); + _retPortForOutPool.edSetType(_alg->getTCForOut()); +} +catch(Exception& e) +{ +} + +OptimizerLoop::OptimizerLoop(const OptimizerLoop& other, ComposedNode *father, bool editionOnly): + DynParaLoop(other,father,editionOnly),_algInitOnFile(other._algInitOnFile),_loader(other._loader.getLibNameWithoutExt()),_convergenceReachedWithOtherCalc(false), + _alg(new OptimizerAlgStandardized(&_myPool,0)),_portForInitFile(other._portForInitFile,this),_retPortForOutPool(other._retPortForOutPool,this),_nodeForSpecialCases(0),_symbol(other._symbol) +{ + OptimizerAlgBaseFactory algFactory=(OptimizerAlgBaseFactory)_loader.getHandleOnSymbolWithName(_symbol); + _alg->setAlgPointer(algFactory); + _splittedPort.edSetType(_alg->getTCForIn()); + _retPortForOutPool.edSetType(_alg->getTCForOut()); +} + +OptimizerLoop::~OptimizerLoop() +{ + _alg->decrRef(); + cleanDynGraph(); + cleanInterceptors(); +} + +Node *OptimizerLoop::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new OptimizerLoop(*this,father,editionOnly); +} + +void OptimizerLoop::init(bool start) +{ + DynParaLoop::init(start); + _portForInitFile.exInit(start); + _convergenceReachedWithOtherCalc=false; + cleanDynGraph(); + cleanInterceptors(); +} + +void OptimizerLoop::exUpdateState() +{ + if(_state == YACS::DISABLED) + return; + if(_inGate.exIsReady()) + { + _state=YACS::TOACTIVATE; + //internal graph update + int i; + int nbOfBr=_nbOfBranches.getIntValue(); + if(nbOfBr==0) + { + delete _nodeForSpecialCases; + _nodeForSpecialCases=new FakeNodeForOptimizerLoop(this,getAllOutPortsLeavingCurrentScope().empty(),FakeNodeForOptimizerLoop::NO_BRANCHES); + return; + } + + if(_portForInitFile.isEmpty()) + { + delete _nodeForSpecialCases; + _nodeForSpecialCases=new FakeNodeForOptimizerLoop(this,getAllOutPortsLeavingCurrentScope().empty(),FakeNodeForOptimizerLoop::NO_ALG_INITIALIZATION); + return; + } + _execNodes.resize(nbOfBr); + _execIds.resize(nbOfBr); + if(_initNode) + { + _execInitNodes.resize(nbOfBr); + _initNodeUpdated.resize(nbOfBr); + for(i=0;iclone(this,false); + if(_initNode) + _execInitNodes[i]=_initNode->clone(this,false); + prepareInputsFromOutOfScope(i); + } + initInterceptors(nbOfBr); + _alg->parseFileToInit(_portForInitFile.getValue()->getStringValue()); + _alg->start(); + int id; + unsigned char priority; + Any *val=_myPool.getNextSampleWithHighestPriority(id,priority); + if(!val) + { + delete _nodeForSpecialCases; + _nodeForSpecialCases=new FakeNodeForOptimizerLoop(this,getAllOutPortsLeavingCurrentScope().empty(),FakeNodeForOptimizerLoop::ALG_WITHOUT_START_CASES); + return; + } + launchMaxOfSamples(true); + } +} + +int OptimizerLoop::getNumberOfInputPorts() const +{ + return DynParaLoop::getNumberOfInputPorts()+2; +} + +InputPort *OptimizerLoop::getInputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_OF_FILENAME_INPUT) + return (InputPort *)&_portForInitFile; + else if(name==NAME_OF_OUT_POOL_INPUT) + return (InputPort *)&_retPortForOutPool; + else + return DynParaLoop::getInputPort(name); +} + +std::list OptimizerLoop::getSetOfInputPort() const +{ + list ret=DynParaLoop::getSetOfInputPort(); + ret.push_back((InputPort *)&_portForInitFile); + ret.push_back((InputPort *)&_retPortForOutPool); + return ret; +} + +void OptimizerLoop::selectRunnableTasks(std::vector& tasks) +{ +} + +void OptimizerLoop::getReadyTasks(std::vector& tasks) +{ + if(!_node) + return; + if(_state==YACS::TOACTIVATE || _state==YACS::ACTIVATED) + { + if(_nodeForSpecialCases) + { + _nodeForSpecialCases->getReadyTasks(tasks); + return ; + } + for(vector::iterator iter=_execNodes.begin();iter!=_execNodes.end();iter++) + (*iter)->getReadyTasks(tasks); + for(vector::iterator iter2=_execInitNodes.begin();iter2!=_execInitNodes.end();iter2++) + (*iter2)->getReadyTasks(tasks); + } + return; + +} + +YACS::Event OptimizerLoop::updateStateOnFinishedEventFrom(Node *node) +{ + unsigned int id; + switch(getIdentityOfNotifyerNode(node,id)) + { + case INIT_NODE: + _execNodes[id]->exUpdateState(); + _nbOfEltConsumed++; + break; + case WORK_NODE: + if(_state==YACS::DONE)//This case happend when alg has reached its convergence whereas other calculations still compute. + { + if(isFullyLazy()) + _condForCompletenessB4Relaunch.wait(); + return YACS::NOEVENT; + } + _myPool.putOutSampleAt(_execIds[id],_interceptorsForOutPool[id]->getValue()); + _myPool.setCurrentId(_execIds[id]); + _alg->takeDecision(); + _myPool.destroyCurrentCase(); + if(_myPool.empty()) + { + pushValueOutOfScopeForCase(id); + _execIds[id]=NOT_RUNNING_BRANCH_ID; + if(!isFullyLazy())// This case happens when the hand is returned to continue, whereas some other are working in parallel for nothing. + _convergenceReachedWithOtherCalc=true; + _state=YACS::DONE; + return YACS::FINISH; + } + _execIds[id]=NOT_RUNNING_BRANCH_ID; + int newId; + unsigned char priority; + Any *val=_myPool.getNextSampleWithHighestPriority(newId, priority); + if(!val) + { + bool isFinished=true; + for(int i=0;i<_execIds.size() and isFinished;i++) + isFinished=(_execIds[i]==NOT_RUNNING_BRANCH_ID); + if(isFinished) + { + std::cerr <<"OptimizerLoop::updateStateOnFinishedEventFrom: Alg has not inserted more cases whereas last element has been calculated !" << std::endl; + exForwardFailed(); + _state=YACS::INTERNALERR; + return YACS::FINISH; + } + return YACS::NOEVENT; + } + launchMaxOfSamples(false); + } + return YACS::NOEVENT; +} + +void OptimizerLoop::checkNoCyclePassingThrough(Node *node) throw(Exception) +{ +} + +void OptimizerLoop::checkConsistency(ComposedNode *pointOfView) const throw(Exception) +{ +} + +void OptimizerLoop::buildDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView) +{ + DynParaLoop::buildDelegateOf(port,initialStart,pointsOfView); + if(port==&_retPortForOutPool) + throw Exception("OptimizerLoop::buildDelegateOf : uncorrect OptimizerLoop link : out pool port must be linked within the scope of OptimizerLoop node it belongs to."); +} + +void OptimizerLoop::buildDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) +{ + DynParaLoop::buildDelegateOf(port,finalTarget,pointsOfView); + string typeOfPortInstance=(port.first)->getNameOfTypeOfCurrentInstance(); + if(typeOfPortInstance!=OutputPort::NAME) + throw Exception("OptimizerLoop::buildDelegateOf : not implemented for DS because not specified "); +} + +void OptimizerLoop::cleanInterceptors() +{ + //the destruction of interceptors whereas some running nodes can push value on them can lead to SIG SEGV. + if(!_execNodes.empty()) + { + if(_convergenceReachedWithOtherCalc) + { + cout << "Waiting completion of last other useless cases." << endl; + _condForCompletenessB4Relaunch.waitForAWait(); + } + } + // At this point all garanties taken let's clean all. + map >::iterator iter=_interceptors.begin(); + for(;iter!=_interceptors.end();iter++) + for(vector::iterator iter2=(*iter).second.begin();iter2!=(*iter).second.end();iter2++) + delete (*iter2); + _interceptors.clear(); + for(vector::iterator iter3=_interceptorsForOutPool.begin();iter3!=_interceptorsForOutPool.end();iter3++) + delete (*iter3); + _interceptorsForOutPool.clear(); +} + +void OptimizerLoop::launchMaxOfSamples(bool first) +{ + int id; + unsigned char priority; + Any *val; + unsigned i; + for(val=_myPool.getNextSampleWithHighestPriority(id,priority);!isFullyBusy(i) && val;val=_myPool.getNextSampleWithHighestPriority(id,priority)) + { + _execIds[i]=id; + _myPool.markIdAsInUse(id); + if(_initNode) + { + if(!_initNodeUpdated[i]) + { + putValueOnBranch(val,i,first); + _execInitNodes[i]->exUpdateState(); + _initNodeUpdated[i]=true; + } + else + { + putValueOnBranch(val,i,first); + _execNodes[i]->exUpdateState(); + _nbOfEltConsumed++; + } + } + else + { + if(!first) + _execNodes[i]->init(first); + putValueOnBranch(val,i,first); + _execNodes[i]->exUpdateState(); + _nbOfEltConsumed++; + } + } +} + +bool OptimizerLoop::isFullyLazy() const +{ + bool isLazy=true; + for(unsigned i=0;i<_execIds.size() and isLazy;i++) + isLazy=(_execIds[i]==NOT_RUNNING_BRANCH_ID); + return isLazy; +} + +/*! + * Returns if a dynamic branch is available. + * \param branchId Out param. Only usable if returned value is equal to \b false. + */ +bool OptimizerLoop::isFullyBusy(unsigned& branchId) const +{ + bool isFinished=true; + unsigned i; + for(i=0;i<_execIds.size() and isFinished;i++) + isFinished=(_execIds[i]!=NOT_RUNNING_BRANCH_ID); + if(!isFinished) + branchId=i-1; + return isFinished; +} + +/*! + * Perform initialization of interceptors. \b WARNING _execNodes have to be created before. + */ +void OptimizerLoop::initInterceptors(unsigned nbOfBr) +{ + //For all classical outputports leaving 'this' + set portsToIntercept=getAllOutPortsLeavingCurrentScope(); + for(set::iterator iter=portsToIntercept.begin();iter!=portsToIntercept.end();iter++) + { + OutputPort *portC=(OutputPort *)(*iter);//Warrantied by OptimizerLoop::buildDelegateOf + const set& links=portC->getSetOfPhyLinks(); + for(set::const_iterator iter2=links.begin();iter2!=links.end();iter2++) + { + InputPort *reprCur=(*iter2)->getPublicRepresentant(); + if(!isInMyDescendance(reprCur->getNode())) + {//here we've got an out of scope link : Let's intercept it + if(_interceptors.find(reprCur)==_interceptors.end()) + { + _interceptors[reprCur].resize(nbOfBr); + for(unsigned i=0;igetOutputPort(_node->getOutPortName(portC)); + InputPort *clone=reprCur->clone(0); + _interceptors[reprCur][i]=clone; + portExecC->edAddInputPort(clone); + } + } + else + { + for(unsigned i=0;igetOutputPort(_node->getOutPortName(portC)); + portExecC->edAddInputPort(_interceptors[reprCur][i]); + } + } + } + } + } + // For out pool + _interceptorsForOutPool.resize(nbOfBr); + set< OutPort * > links=_retPortForOutPool.edSetOutPort(); + for(unsigned i=0;i::iterator iter2=links.begin();iter2!=links.end();iter2++) + for(unsigned j=0;jgetNode()); + if(whatType==_node) + { + portExec=_execNodes[j]->getOutPort(_node->getOutPortName(*iter2)); + portExec->addInPort(_interceptorsForOutPool[j]); + } + else if(whatType==_initNode && whatType!=0)//This case should never happend. Useless ! + { + portExec=_execInitNodes[j]->getOutPort(_node->getOutPortName(*iter2)); + portExec->addInPort(_interceptorsForOutPool[j]); + } + } +} + +/*! + * Typically called when _alg has decided that convergence has been reached. In this case the links leaving the current scope are activated and filled + * with value of the branch specified by 'branchId' that is the branch in which the convergence has been reached. + */ +void OptimizerLoop::pushValueOutOfScopeForCase(unsigned branchId) +{ + map >::iterator iter; + for(iter=_interceptors.begin();iter!=_interceptors.end();iter++) + (*iter).first->put((*iter).second[branchId]->get()); +} + diff --git a/src/engine/OptimizerLoop.hxx b/src/engine/OptimizerLoop.hxx new file mode 100644 index 000000000..2ad819615 --- /dev/null +++ b/src/engine/OptimizerLoop.hxx @@ -0,0 +1,118 @@ +#ifndef __OPTIMIZERLOOP_HXX__ +#define __OPTIMIZERLOOP_HXX__ + +#include "Pool.hxx" +#include "Thread.hxx" +#include "DynParaLoop.hxx" +#include "DynLibLoader.hxx" +#include "OptimizerAlg.hxx" +#include "ElementaryNode.hxx" +#include "DrivenCondition.hxx" + +namespace YACS +{ + namespace ENGINE + { + class OptimizerAlgStandardized : public OptimizerAlgSync + { + private: + ::YACS::BASES::Thread *_threadInCaseOfNotEvent; + ::YACS::BASES::DrivenCondition _condition; + OptimizerAlgBase *_algBehind; + public: + OptimizerAlgStandardized(Pool *pool, OptimizerAlgBase *alg); + ~OptimizerAlgStandardized(); + TypeCode *getTCForIn() const; + TypeCode *getTCForOut() const; + void setAlgPointer(OptimizerAlgBaseFactory algFactory); + void parseFileToInit(const std::string& fileName); + void initialize(const Any *input) throw (Exception); + void takeDecision(); + void finish(); + void start(); + private: + static void *threadFctForAsync(void* ownStack); + }; + + class OptimizerLoop; + + class FakeNodeForOptimizerLoop : public ElementaryNode + { + friend class OptimizerLoop; + private: + OptimizerLoop *_loop; + unsigned _reason; + bool _normal; + private: + FakeNodeForOptimizerLoop(OptimizerLoop *loop, bool normal, unsigned reason); + FakeNodeForOptimizerLoop(const FakeNodeForOptimizerLoop& other); + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + void exForwardFailed(); + void exForwardFinished(); + void execute(); + void aborted(); + void finished(); + private: + static const char NAME[]; + static const unsigned char ALG_WITHOUT_START_CASES = 52; + static const unsigned char NO_BRANCHES = 53; + static const unsigned char NO_ALG_INITIALIZATION = 54; + }; + + class OptimizerLoop : public DynParaLoop + { + friend class FakeNodeForOptimizerLoop; + + protected: + Pool _myPool; + bool _algInitOnFile; + std::string _symbol; + AnyInputPort _portForInitFile; + ::YACS::BASES::DynLibLoader _loader; + OptimizerAlgStandardized *_alg; + AnyInputPort _retPortForOutPool; + std::vector _initNodeUpdated; + bool _convergenceReachedWithOtherCalc; + FakeNodeForOptimizerLoop *_nodeForSpecialCases; + std::vector _interceptorsForOutPool; + ::YACS::BASES::DrivenCondition _condForCompletenessB4Relaunch; + //! outputports interceptors leaving current scope. + std::map > _interceptors; + public: + OptimizerLoop(const std::string& name, const std::string& algLibWthOutExt, + const std::string& symbolNameToOptimizerAlgBaseInstanceFactory, + bool algInitOnFile) throw(Exception); + OptimizerLoop(const OptimizerLoop& other, ComposedNode *father, bool editionOnly); + ~OptimizerLoop(); + void init(bool start=true); + void exUpdateState(); + int getNumberOfInputPorts() const; + InputPort *edGetPortForOutPool() { return &_retPortForOutPool; } + InputPort *edGetPortForInitFile() { return &_portForInitFile; } + InputPort *getInputPort(const std::string& name) const throw(Exception); + std::list getSetOfInputPort() const; + void selectRunnableTasks(std::vector& tasks); + void getReadyTasks(std::vector& tasks); + YACS::Event updateStateOnFinishedEventFrom(Node *node); + void checkNoCyclePassingThrough(Node *node) throw(Exception); + void checkConsistency(ComposedNode *pointOfView) const throw(Exception); + protected: + void buildDelegateOf(InPort * & port, OutPort *initialStart, const std::set& pointsOfView); + void buildDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView); + protected: + void cleanInterceptors(); + void launchMaxOfSamples(bool first); + bool isFullyLazy() const; + bool isFullyBusy(unsigned& branchId) const; + void initInterceptors(unsigned nbOfBr); + void pushValueOutOfScopeForCase(unsigned branchId); + Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; + protected: + static const int NOT_RUNNING_BRANCH_ID; + static const char NAME_OF_FILENAME_INPUT[]; + static const char NAME_OF_OUT_POOL_INPUT[]; + }; + } +} + +#endif diff --git a/src/engine/OutGate.cxx b/src/engine/OutGate.cxx index 3781918fd..18683cec9 100644 --- a/src/engine/OutGate.cxx +++ b/src/engine/OutGate.cxx @@ -15,40 +15,84 @@ string OutGate::getNameOfTypeOfCurrentInstance() const return NAME; } +void OutGate::exReset() +{ + for(map::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + (*iter).second=false; +} + +//! Notify this port that its node is finished +/*! + * Calls (notify) all the connected ingates : InGate::exNotifyFromPrecursor + * + * Called by Bloc::updateStateOnFinishedEventFrom + */ + void OutGate::exNotifyDone() { - for(set::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) - (*iter)->exNotifyFromPrecursor(); + for(map::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + (*iter).first->exNotifyFromPrecursor(this); +} + +//! Notify this port that its node has failed +/*! + * + */ +void OutGate::exNotifyFailed() +{ + for(map::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + (*iter).first->exNotifyFailed(); +} + +//! Notify this port that its node has been disabled +/*! + * + */ +void OutGate::exNotifyDisabled() +{ + for(map::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + (*iter).first->exNotifyDisabled(); +} + +void OutGate::edDisconnectAllLinksFromMe() +{ + for(map::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + (*iter).first->edRemovePrecursor(this); + _setOfInGate.clear(); } bool OutGate::edAddInGate(InGate *inGate) { if(!isAlreadyInSet(inGate)) { - inGate->edAppendPrecursor(); - _setOfInGate.insert(inGate); + inGate->edAppendPrecursor(this); + _setOfInGate[inGate]=false; return true; } else return false; } -set OutGate::edSetInGate() const +std::set OutGate::edSetInGate() const { - return _setOfInGate; + set ret; + for(map::const_iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + ret.insert((*iter).first); + return ret; } -void OutGate::edRemoveInGate(InGate *inGate) throw(Exception) +void OutGate::edRemoveInGate(InGate *inGate, bool coherenceWithInGate) throw(Exception) { - bool found=false; - for(set::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end() && !found;iter++) - if((*iter)==inGate) + map::iterator iter; + for(iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + if((*iter).first==inGate) { - _setOfInGate.erase(iter); - inGate->edRemovePrecursor(); - found=true; + _setOfInGate.erase(iter); + if(coherenceWithInGate) + inGate->edRemovePrecursor(this); + break; } - if(!found) + if(iter==_setOfInGate.end()) throw Exception("InGate not already connected to OutGate"); } @@ -56,22 +100,18 @@ void OutGate::edRemoveInGate(InGate *inGate) throw(Exception) void OutGate::edRemoveInGateOneWay(InGate *inGate) { bool found=false; - for(set::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end() && !found;iter++) - if((*iter)==inGate) + for(map::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end() && !found;iter++) + if((*iter).first==inGate) { - _setOfInGate.erase(iter); - inGate->edRemovePrecursor(); - found=true; + _setOfInGate.erase(iter); + inGate->edRemovePrecursor(this); + found=true; } } bool OutGate::isAlreadyInSet(InGate *inGate) const { - bool ret=false; - for(set::const_iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end() && !ret;iter++) - if((*iter)==inGate) - ret=true; - return ret; + return _setOfInGate.find(inGate)!=_setOfInGate.end(); } int OutGate::getNbOfInGatesConnected() const diff --git a/src/engine/OutGate.hxx b/src/engine/OutGate.hxx index 05f430fd4..18694094a 100644 --- a/src/engine/OutGate.hxx +++ b/src/engine/OutGate.hxx @@ -4,6 +4,7 @@ #include "Port.hxx" #include "Exception.hxx" +#include #include namespace YACS @@ -17,16 +18,21 @@ namespace YACS { friend class ElementaryNode; protected: - std::set _setOfInGate; + std::map _setOfInGate; public: static const char NAME[]; public: OutGate(Node *node); std::string getNameOfTypeOfCurrentInstance() const; + void exReset(); void exNotifyDone(); + void exNotifyFailed(); + void exNotifyDisabled(); + void edDisconnectAllLinksFromMe(); bool edAddInGate(InGate *inGate); + std::map& edMapInGate() { return _setOfInGate; } std::set edSetInGate() const; - void edRemoveInGate(InGate *inGate) throw(Exception); + void edRemoveInGate(InGate *inGate, bool coherenceWithInGate=true) throw(Exception); int getNbOfInGatesConnected() const; protected: void edRemoveInGateOneWay(InGate *inGate); diff --git a/src/engine/OutPort.cxx b/src/engine/OutPort.cxx index c54603591..c21f6c985 100644 --- a/src/engine/OutPort.cxx +++ b/src/engine/OutPort.cxx @@ -1,7 +1,70 @@ #include "OutPort.hxx" +#include "InPort.hxx" +#include "ComposedNode.hxx" +#include +#include using namespace YACS::ENGINE; +using namespace std; -OutPort::OutPort(Node *node):Port(node) +OutPort::OutPort(const OutPort& other, Node *newHelder):DataPort(other,newHelder),Port(other,newHelder) { } + +OutPort::OutPort(const std::string& name, Node *node, TypeCode* type):DataPort(name,node,type),Port(node) +{ +} + +OutPort::~OutPort() +{ +} + +void OutPort::getAllRepresented(std::set& represented) const +{ + represented.insert((OutPort *)this); +} + +int OutPort::edGetNumberOfOutLinks() const +{ + return edSetInPort().size(); +} + +std::vector OutPort::calculateHistoryOfLinkWith(InPort *end) +{ + if(!isAlreadyLinkedWith(end)) + throw Exception("ComposedNode::edRemoveLink : unexisting link"); + vector ret; + ComposedNode* lwstCmnAnctr=ComposedNode::getLowestCommonAncestor(getNode(),end->getNode()); + set allAscendanceOfNodeStart=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=getNode()->getFather(); + pair currentPortO(this,this); + ret.push_back(currentPortO.first); + while(iterS!=lwstCmnAnctr) + { + iterS->getDelegateOf(currentPortO, end, allAscendanceOfNodeEnd); + if(currentPortO.first!=ret.back()) + ret.push_back(currentPortO.first); + iterS=iterS->_father; + } + iterS=end->getNode()->getFather(); + InPort *currentPortI=end; + int i=0; + while(iterS!=lwstCmnAnctr) + { + vector::iterator iter2; + iterS->getDelegateOf(currentPortI, this, allAscendanceOfNodeStart); + if(currentPortI!=ret.back()) + { + i++; + ret.push_back(currentPortI); + } + iterS=iterS->_father; + } + vector::iterator iter=ret.end(); iter-=i; + reverse(iter,ret.end()); + return ret; +} diff --git a/src/engine/OutPort.hxx b/src/engine/OutPort.hxx index 500c101c3..177ca3c03 100644 --- a/src/engine/OutPort.hxx +++ b/src/engine/OutPort.hxx @@ -1,21 +1,31 @@ #ifndef __OUTPORT_HXX__ #define __OUTPORT_HXX__ -#include "Port.hxx" +#include "DataPort.hxx" #include "Exception.hxx" +#include +#include + namespace YACS { namespace ENGINE { class InPort; - class OutPort : public virtual Port + class OutPort : public virtual DataPort { protected: - OutPort(Node *node); + OutPort(const OutPort& other, Node *newHelder); + OutPort(const std::string& name, Node *node, TypeCode* type); public: + virtual int edGetNumberOfOutLinks() const; + virtual std::set edSetInPort() const = 0; + virtual bool isAlreadyLinkedWith(InPort *with) const = 0; + virtual void getAllRepresented(std::set& represented) const; virtual bool addInPort(InPort *inPort) throw(Exception) = 0; - virtual void removeInPort(InPort *inPort) throw(Exception) = 0; + virtual int removeInPort(InPort *inPort, bool forward) throw(Exception) = 0; + virtual ~OutPort(); + std::vector calculateHistoryOfLinkWith(InPort *end); }; } } diff --git a/src/engine/OutputDataStreamPort.cxx b/src/engine/OutputDataStreamPort.cxx index 9f4f59614..c81c35656 100644 --- a/src/engine/OutputDataStreamPort.cxx +++ b/src/engine/OutputDataStreamPort.cxx @@ -1,25 +1,68 @@ #include "OutputDataStreamPort.hxx" #include "InputDataStreamPort.hxx" -//#include "TypeCheckerDataStream.hxx" +#include "ComposedNode.hxx" +#include "InPort.hxx" +#include using namespace YACS::ENGINE; using namespace std; const char OutputDataStreamPort::NAME[]="OutputDataStreamPort"; -OutputDataStreamPort::OutputDataStreamPort(const string& name, Node *node, TypeCode* type):DataStreamPort(name,node,type),OutPort(node),Port(node) +OutputDataStreamPort::OutputDataStreamPort(const OutputDataStreamPort& other, Node *newHelder):DataStreamPort(other,newHelder), + OutPort(other,newHelder), + DataPort(other,newHelder), + Port(other,newHelder) { } +OutputDataStreamPort::OutputDataStreamPort(const std::string& name, Node *node, TypeCode* type):DataStreamPort(name,node,type), +OutPort(name,node,type), +DataPort(name,node,type), +Port(node) +{ +} + +OutputDataStreamPort::~OutputDataStreamPort() +{ +} + +OutputDataStreamPort *OutputDataStreamPort::clone(Node *newHelder) const +{ + return new OutputDataStreamPort(*this,newHelder); +} + +std::set OutputDataStreamPort::edSetInPort() const +{ + set s; + for(set::iterator iter=_setOfInputDataStreamPort.begin();iter!=_setOfInputDataStreamPort.end();iter++) + (*iter)->getAllRepresentants(s); + return s; +} + +bool OutputDataStreamPort::isAlreadyLinkedWith(InPort *with) const +{ + set s; + set::iterator iter; + for(iter=_setOfInputDataStreamPort.begin();iter!=_setOfInputDataStreamPort.end();iter++) + if(*iter==with) + return true; + for(iter=_setOfInputDataStreamPort.begin();iter!=_setOfInputDataStreamPort.end();iter++) + (*iter)->getAllRepresentants(s); + for(set::iterator iter2=s.begin();iter2!=s.end();iter2++) + if((*iter2)==with) + return true; + return false; +} + string OutputDataStreamPort::getNameOfTypeOfCurrentInstance() const { return NAME; } -bool OutputDataStreamPort::edAddInputDataStreamPort(InputDataStreamPort *port) throw(ConversionException) +bool OutputDataStreamPort::edAddInputDataStreamPort(InputDataStreamPort *port) + throw(ConversionException) { -// 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)) { _setOfInputDataStreamPort.insert(port); @@ -29,38 +72,61 @@ bool OutputDataStreamPort::edAddInputDataStreamPort(InputDataStreamPort *port) t return false; } -void OutputDataStreamPort::edRemoveInputDataStreamPort(InputDataStreamPort *inputPort) throw(Exception) +int OutputDataStreamPort::edRemoveInputDataStreamPort(InputDataStreamPort *inPort, bool forward) throw(Exception) { - 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); + if(forward) + { + set s; + inPort->getAllRepresentants(s); + for(set::iterator iter=s.begin();iter!=s.end();iter++) + _node->getRootNode()->edRemoveLink(this,*iter); + return -1; + } + else + { + set::iterator iter=_setOfInputDataStreamPort.find(inPort); + if(iter!=_setOfInputDataStreamPort.end()) + { + _setOfInputDataStreamPort.erase(iter); + return edGetNumberOfOutLinks(); + } + else + throw Exception("OutputDataStreamPort::edRemoveInputPort : link does not exist, unable to remove it"); + } } bool OutputDataStreamPort::addInPort(InPort *inPort) throw(Exception) { + if(inPort->getNameOfTypeOfCurrentInstance()!=InputDataStreamPort::NAME) + { + string what="not compatible type of port requested during building of link FROM "; + what+=NAME; what+=" TO "; what+=inPort->getNameOfTypeOfCurrentInstance(); + throw Exception(what); + } + return edAddInputDataStreamPort(static_cast(inPort)); } -void OutputDataStreamPort::removeInPort(InPort *inPort) throw(Exception) +void OutputDataStreamPort::edRemoveAllLinksLinkedWithMe() throw(Exception) { + set::iterator iter; + set vec(_setOfInputDataStreamPort); + for( set::iterator iter2=vec.begin();iter2!=vec.end();iter2++) + edRemoveInputDataStreamPort(*iter2,true); + _setOfInputDataStreamPort.clear(); } -bool OutputDataStreamPort::isLinked() +int OutputDataStreamPort::removeInPort(InPort *inPort, bool forward) throw(Exception) { - return _setOfInputDataStreamPort.empty(); + if(inPort->getNameOfTypeOfCurrentInstance()!=InputDataStreamPort::NAME && !forward) + { + string what="not compatible type of port requested during destruction of for link FROM "; + what+=NAME; what+=" TO "; what+=inPort->getNameOfTypeOfCurrentInstance(); + throw Exception(what); + } + return edRemoveInputDataStreamPort(static_cast(inPort),forward); } -bool OutputDataStreamPort::isAlreadyInSet(InputDataStreamPort *inputPort) const +bool OutputDataStreamPort::isAlreadyInSet(InputDataStreamPort *inPort) const { - bool ret=false; - for(set::const_iterator iter=_setOfInputDataStreamPort.begin();iter!=_setOfInputDataStreamPort.end();iter++) - if((*iter)==inputPort) - ret=true; - return ret; + return _setOfInputDataStreamPort.find(inPort)!=_setOfInputDataStreamPort.end(); } diff --git a/src/engine/OutputDataStreamPort.hxx b/src/engine/OutputDataStreamPort.hxx index 163f56793..5eca25a06 100644 --- a/src/engine/OutputDataStreamPort.hxx +++ b/src/engine/OutputDataStreamPort.hxx @@ -22,17 +22,20 @@ namespace YACS public: static const char NAME[]; public: + OutputDataStreamPort(const OutputDataStreamPort& other, Node *newHelder); OutputDataStreamPort(const std::string& name, Node *node, TypeCode* type); - std::string getNameOfTypeOfCurrentInstance() const; - bool edAddInputDataStreamPort(InputDataStreamPort *port) throw(ConversionException); - 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); + virtual ~OutputDataStreamPort(); + virtual OutputDataStreamPort *clone(Node *newHelder) const; + std::set edSetInPort() const; + bool isAlreadyLinkedWith(InPort *with) const; + virtual std::string getNameOfTypeOfCurrentInstance() const; + virtual bool addInPort(InPort *inPort) throw(Exception); + virtual bool edAddInputDataStreamPort(InputDataStreamPort *port) throw(ConversionException); + int edRemoveInputDataStreamPort(InputDataStreamPort *inPort, bool forward) throw(Exception); + void edRemoveAllLinksLinkedWithMe() throw(Exception); + int removeInPort(InPort *inPort, bool forward) throw(Exception); private: - bool isAlreadyInSet(InputDataStreamPort *inputPort) const; + bool isAlreadyInSet(InputDataStreamPort *inPort) const; }; } } diff --git a/src/engine/OutputPort.cxx b/src/engine/OutputPort.cxx index 36db4f2cc..7a3e62a12 100644 --- a/src/engine/OutputPort.cxx +++ b/src/engine/OutputPort.cxx @@ -1,16 +1,27 @@ #include "OutputPort.hxx" +#include "ComposedNode.hxx" #include "InputPort.hxx" #include "Runtime.hxx" +#include "Node.hxx" #include #include +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + using namespace YACS::ENGINE; using namespace std; const char OutputPort::NAME[]="OutputPort"; -OutputPort::OutputPort(const string& name, Node *node, TypeCode* type):DataFlowPort(name,node,type),OutPort(node),Port(node) +OutputPort::OutputPort(const OutputPort& other, Node *newHelder):DataFlowPort(other,newHelder),OutPort(other,newHelder), + DataPort(other,newHelder),Port(other,newHelder) +{ +} + +OutputPort::OutputPort(const std::string& name, Node *node, TypeCode* type):DataFlowPort(name,node,type),OutPort(name,node,type), + DataPort(name,node,type),Port(node) { } @@ -19,87 +30,117 @@ string OutputPort::getNameOfTypeOfCurrentInstance() const return NAME; } -void OutputPort::exInit() +void OutputPort::edRemoveAllLinksLinkedWithMe() throw(Exception) { -// _data.exInit(); + set::iterator iter; + set vec(_setOfInputPort); + for( set::iterator iter2=vec.begin();iter2!=vec.end();iter2++) + edRemoveInputPort(*iter2,true); + _setOfInputPort.clear(); } +void OutputPort::exInit() +{ +} void OutputPort::put(const void *data) throw(ConversionException) { -// _data = (void *)data; - cerr << _name << endl; - cerr << _impl << endl; - stringstream msg; - msg << "Not implemented (" << __FILE__ << ":" << __LINE__ << ")"; - throw Exception(msg.str()); - } - + for(set::iterator iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++) + (*iter)->put(data); +} /** * check if output type is an input type and if a data converter exists before link */ - -bool OutputPort::edAddInputPort(InputPort *inputPort) throw(ConversionException) +bool OutputPort::edAddInputPort(InputPort *phyPort) throw(Exception) { - InputPort *pwrap = getRuntime()->adapt(inputPort->getImpl(), - inputPort, - this->getImpl(), - this->type()); - - if(!isAlreadyInSet(pwrap)) + if(!isAlreadyInSet(phyPort)) { + InputPort *pwrap = getRuntime()->adapt(phyPort, + _node->getImplementation(), + this->edGetType()); _setOfInputPort.insert(pwrap); - inputPort->edNotifyReferenced(); return true; } else - { - if ( dynamic_cast (pwrap) ) - { - cerr << "ProxyPort destruction, while creating the same link twice..." << endl; - delete pwrap; - } - return false; - } -} - -set OutputPort::edSetInputPort() -{ - return _setOfInputPort; + return false; } -void OutputPort::edRemoveInputPort(InputPort *inputPort) throw(Exception) +/** + * Remove a link by performing not only the deletion in _setOfInputPort but also dereference to the target inputPort. + * If 'forward' == true the forward deletion + * If 'forward' == false no forward deletion performed, oneway deletion without update 'inputPort' side. + */ +int OutputPort::edRemoveInputPort(InputPort *inputPort, bool forward) throw(Exception) { - if(isAlreadyInSet(inputPort)) - _setOfInputPort.erase(inputPort); + if(forward) + { + set s; + inputPort->getAllRepresentants(s); + for(set::iterator iter=s.begin();iter!=s.end();iter++) + _node->getRootNode()->edRemoveLink(this,*iter); + return -1; + } else - throw Exception("OutputPort::edRemoveInputPort : link does not exist, unable to remove it"); + { + InputPort *publicRepr=inputPort->getPublicRepresentant(); + set::iterator iter; + for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + if((*iter)->getPublicRepresentant()==publicRepr) + break; + if(iter!=_setOfInputPort.end()) + { + if((*iter)->isIntermediate()) + delete (*iter); + _setOfInputPort.erase(iter); + return edGetNumberOfOutLinks(); + } + 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) +OutputPort::~OutputPort() { - _setOfInputPort.erase(inputPort); + set::iterator iter; + for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + { + delete (*iter); + } } -OutputPort::~OutputPort() +bool OutputPort::isAlreadyLinkedWith(InPort *with) const { + InPort *publicRepr=with->getPublicRepresentant(); + set s; + set::iterator iter; + for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + { + if((*iter)->getPublicRepresentant() == publicRepr) + return true; + } + for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + (*iter)->getAllRepresentants(s); + for(set::iterator iter2=s.begin();iter2!=s.end();iter2++) + { + if((*iter2)->getPublicRepresentant() == publicRepr) + return true; + } + return false; } bool OutputPort::isAlreadyInSet(InputPort *inputPort) const { - bool ret=false; - for(set::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end() && !ret;iter++) - if((*iter)==inputPort) - ret=true; - return ret; + InputPort *publicRepr=inputPort->getPublicRepresentant(); + for(set::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + if((*iter)->getPublicRepresentant()==publicRepr) + return true; + return false; } /** - * check compatibility of port class ( an inputPort) before trying to create the link + * 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) @@ -111,18 +152,37 @@ bool OutputPort::addInPort(InPort *inPort) throw(Exception) return edAddInputPort(static_cast(inPort)); } -void OutputPort::removeInPort(InPort *inPort) throw(Exception) +/** + * check compatibility of port class ( an inputPort ) before trying to remove link WITHOUT forward. + */ +int OutputPort::removeInPort(InPort *inPort, bool forward) throw(Exception) { - if(inPort->getNameOfTypeOfCurrentInstance()!=InputPort::NAME) + if(inPort->getNameOfTypeOfCurrentInstance()!=InputPort::NAME && !forward) { string what="not compatible type of port requested during destruction of for link FROM "; what+=NAME; what+=" TO "; what+=inPort->getNameOfTypeOfCurrentInstance(); throw Exception(what); } - edRemoveInputPort(static_cast(inPort)); + return edRemoveInputPort(static_cast(inPort),forward); +} + +std::set OutputPort::edSetInPort() const +{ + set s; + for(set::iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + (*iter)->getAllRepresentants(s); + return s; } -bool OutputPort::isLinked() +std::string OutputPort::dump() { - return _setOfInputPort.empty(); + string xmldump = " NO_SERIALISATION_AVAILABLE "; + return xmldump; +} + + +//! Returns physical links linked to this. Contrary to edSetInPort that returns semantic links. +const std::set& OutputPort::getSetOfPhyLinks() const +{ + return _setOfInputPort; } diff --git a/src/engine/OutputPort.hxx b/src/engine/OutputPort.hxx index 1f878a985..1d2b0e949 100644 --- a/src/engine/OutputPort.hxx +++ b/src/engine/OutputPort.hxx @@ -1,11 +1,8 @@ #ifndef __OUTPUTPORT_HXX__ #define __OUTPUTPORT_HXX__ -//#include -//#include - -#include "TypeCode.hxx" #include "OutPort.hxx" +#include "TypeCode.hxx" #include "DataFlowPort.hxx" #include "ConversionException.hxx" @@ -15,37 +12,46 @@ namespace YACS { namespace ENGINE { + class InPort; + class Runtime; class InputPort; + class OptimizerLoop; class ElementaryNode; - class Runtime; + class CollectorSwOutputPort; class OutputPort : public DataFlowPort, public OutPort { - friend class ElementaryNode; // for disconnect... - friend class Runtime; // for port creation + friend class CollectorSwOutputPort; // for conect + friend class ElementaryNode; // for disconnect... + friend class OptimizerLoop; // for interceptors + friend class InputPort; + friend class Runtime; // for port creation public: - ~OutputPort(); - - std::string getNameOfTypeOfCurrentInstance() const; - std::set edSetInputPort(); - bool isLinked(); + virtual ~OutputPort(); + std::set edSetInPort() const; + bool isAlreadyLinkedWith(InPort *with) const; bool isAlreadyInSet(InputPort *inputPort) const; - - virtual bool addInPort(InPort *inPort) throw(Exception); - bool edAddInputPort(InputPort *inputPort) throw(ConversionException); - virtual void removeInPort(InPort *inPort) throw(Exception); - void edRemoveInputPort(InputPort *inputPort) throw(Exception); - - void exInit(); + std::string getNameOfTypeOfCurrentInstance() const; + int removeInPort(InPort *inPort, bool forward) throw(Exception); + virtual bool edAddInputPort(InputPort *phyPort) throw(Exception); + virtual int edRemoveInputPort(InputPort *inputPort, bool forward) throw(Exception); + bool addInPort(InPort *inPort) throw(Exception); + void edRemoveAllLinksLinkedWithMe() throw(Exception);//entry point for forward port deletion + virtual void exInit(); + virtual OutputPort *clone(Node *newHelder) const = 0; + virtual std::string dump(); virtual void put(const void *data) throw(ConversionException); - static const char NAME[]; - protected: + OutputPort(const OutputPort& other, Node *newHelder); OutputPort(const std::string& name, Node *node, TypeCode* type); - void edRemoveInputPortOneWay(InputPort *inputPort); - std::set _setOfInputPort; + protected: + const std::set& getSetOfPhyLinks() const; + protected: + std::set _setOfInputPort;//Key is for physical Data link + public: + static const char NAME[]; }; } } diff --git a/src/engine/Plugin/Makefile.am b/src/engine/Plugin/Makefile.am new file mode 100644 index 000000000..10abb72bc --- /dev/null +++ b/src/engine/Plugin/Makefile.am @@ -0,0 +1,15 @@ + +include $(top_srcdir)/adm/unix/make_begin.am + +lib_LTLIBRARIES = libPluginSimplex.la + +libPluginSimplex_la_SOURCES = PluginSimplex.cxx \ + maestro.cxx decode.cxx point.cxx aleas.cxx \ + salomevent.cxx simplex.cxx solution.cxx \ + local.cxx mt19937ar.cxx + +libPluginSimplex_la_CXXFLAGS = $(THREAD_DEF) \ + -I$(srcdir)/.. \ + -I$(srcdir)/../../bases + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/engine/Plugin/PluginSimplex.cxx b/src/engine/Plugin/PluginSimplex.cxx new file mode 100644 index 000000000..65c681321 --- /dev/null +++ b/src/engine/Plugin/PluginSimplex.cxx @@ -0,0 +1,97 @@ +#include "PluginSimplex.hxx" +#include "TypeCode.hxx" +#include "Pool.hxx" + +#include "saconst.h" + +#include "solution.hxx" + +#include + +using namespace YACS::ENGINE; + +PluginSimplex::PluginSimplex(Pool *pool):OptimizerAlgSync(pool),_tc(0) +{ + // type + TypeCode *tctmp=new TypeCode(Double); + _tc=new TypeCodeSeq("", "", tctmp); + tctmp->decrRef(); + // distribution + dst = (SalomeEventLoop *) NULL; + dec = (LinearDecoder *) NULL; + mtr = (Maestro *) NULL; + // swarm + solv = (Simplex *) NULL; + +} + +PluginSimplex::~PluginSimplex() +{ + _tc->decrRef(); + // distribution + delete dst; + delete dec; + delete mtr; + // swarm + delete solv; +} + +TypeCode *PluginSimplex::getTCForIn() const +{ + return _tc; +} + +TypeCode *PluginSimplex::getTCForOut() const +{ + return _tc; +} + +void PluginSimplex::parseFileToInit(const std::string& fileName) +{ + std::vector > dom(NBGENE); + long i; + + // domaine de recherche + for (i=0; isetStop(NBEVAL); +} + +void PluginSimplex::start() +{ + solv->start(); +} + +void PluginSimplex::takeDecision() +{ + int rien; + rien = solv->next(); +} + +void PluginSimplex::initialize(const Any *input) throw (Exception) +{ +} + +void PluginSimplex::finish() +{ + Solution *res; + + solv->finish(); + res = solv->solution(); + dec->echo(*res); +} + +OptimizerAlgBase *PluginSimplexFactory(Pool *pool) +{ + return new PluginSimplex(pool); +} + diff --git a/src/engine/Plugin/PluginSimplex.hxx b/src/engine/Plugin/PluginSimplex.hxx new file mode 100644 index 000000000..de0a4a7f5 --- /dev/null +++ b/src/engine/Plugin/PluginSimplex.hxx @@ -0,0 +1,49 @@ +#ifndef __PLUGINSIMPLEX_HXX__ +#define __PLUGINSIMPLEX_HXX__ + +#include "OptimizerAlg.hxx" + +#include "decode.hxx" +#include "salomevent.hxx" +#include "maestro.hxx" +#include "simplex.hxx" + +extern "C" +{ + YACS::ENGINE::OptimizerAlgBase *PluginSimplexFactory(YACS::ENGINE::Pool *pool); +} + +namespace YACS +{ + namespace ENGINE + { + class PluginSimplex : public OptimizerAlgSync + { + private: + int _idTest; + TypeCode *_tc; + TypeCode *_tcOut; + protected : + //Superviseur *super; + // distribution + SalomeEventLoop *dst; + LinearDecoder *dec; + Maestro *mtr; + // swarm + Simplex *solv; + + public: + PluginSimplex(Pool *pool); + virtual ~PluginSimplex(); + TypeCode *getTCForIn() const; + TypeCode *getTCForOut() const; + void parseFileToInit(const std::string& fileName); + void start(); + void takeDecision(); + void initialize(const Any *input) throw(Exception); + void finish(); + }; + } +} + +#endif diff --git a/src/engine/Plugin/SConscript b/src/engine/Plugin/SConscript new file mode 100644 index 000000000..dc17470ab --- /dev/null +++ b/src/engine/Plugin/SConscript @@ -0,0 +1,17 @@ + +import glob + +## environnement +Import('env') + +lenv = env.Copy( + CPPPATH=['/opt/hpmpi/include', '#'], +) + +## target +def shared(lfile) : + return [lenv.SharedObject(f) for f in lfile] + +src = glob.glob('*.cxx') +lib = lenv.Library('dist', shared(src)) + diff --git a/src/engine/Plugin/aleas.cxx b/src/engine/Plugin/aleas.cxx new file mode 100644 index 000000000..f029a5eec --- /dev/null +++ b/src/engine/Plugin/aleas.cxx @@ -0,0 +1,158 @@ +// --- C++ --- +// --- coding: latin_1 --- +// +// File +// creation : 2007-02-21.09.50.46 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// tirage aleatoire +// +//___________________________________________________________________ + +#include +#include +#include +#include + +// #include "mt19937ar.h +extern void init_by_array(unsigned long [], int); +extern double genrand_real1(void); +extern double genrand_real3(void); + +#include "aleas.hxx" + +#define NOALEAS + +static void initrand(void) +{ + static long done=0; + unsigned long vec[]={ + 31081996, 21012006, 17921963, 0, + 11101998, 2112003, 25111964, 0 + }; + + if (! done) { +#ifdef NOALEAS + vec[3] = vec[7] = 2082007; +#else + vec[3] = (unsigned long) getpid(); + vec[7] = (unsigned long) time(NULL); +#endif + init_by_array(vec, 8); + done += 1; + } +} +// utilitaire +/*static void initrand(void) +{ + static long done=0; + unsigned long vec[]={ + 31081996, 21012006, 17921963, 0, + 11101998, 2112003, 25111964, 0 + }; + + if (! done) { + vec[3] = (unsigned long) getpid(); + vec[7] = (unsigned long) time(NULL); + init_by_array(vec, 8); + done += 1; + } +}*/ + +static double randGauss(void) +{ + static double next; + static int flag=0; + double v2, d, fac; + + if (flag) { + flag = 0; + return next; + } + else { + do { + next = 2.0*genrand_real3() - 1.0; + v2 = 2.0*genrand_real3() - 1.0; + d = next*next + v2*v2; + } while (d >= 1.0 || d == 0.0); + fac = sqrt(-2.0*log(d)/d); + next *= fac; + flag = 1; + return v2 * fac; + } + +} + +// class Aleatoire +Aleatoire::Aleatoire(long sz) +{ + size = sz; + initrand(); +} + +void Aleatoire::fill(std::vector &ret) +{ + int i; + + for (i=0; i *Aleatoire::gen() +{ + std::vector *ret; + + ret = new std::vector(size); + fill(*ret); + return ret; +} + +// class Cube +double Cube::tire() +{ + return genrand_real1(); +} + +// class NormalPositif +double NormalePositif::tire() +{ + return randGauss() * 0.25 + 0.5 ; +} + +// class Normal +double Normale::tire() +{ + return randGauss(); +} + +// class Sphere +void Sphere::fill(std::vector &ret) +{ + long i; + double cum, r; + + Normale::fill(ret); + for (cum=0, i=0; i &ret) +{ + long i; + + Sphere::fill(ret); + for (i=0; i + + +class Aleatoire { + private : + protected : + long size; + public : + Aleatoire(long); + virtual std::vector *gen(void); + virtual void fill(std::vector &); + virtual double tire(void) = 0; +}; + +class Cube : public Aleatoire { + public : + Cube(long s) : Aleatoire(s) {}; + virtual double tire(void); +}; + +class Normale : public Aleatoire { + public : + Normale(long s) : Aleatoire(s) {}; + virtual double tire(void); +}; + +class NormalePositif : public Aleatoire { + public : + NormalePositif(long s) : Aleatoire(s) {}; + virtual double tire(void); +}; + +class Sphere : public Normale { + public: + Sphere(long s) : Normale(s) {}; + virtual void fill(std::vector &); +}; + +class SpherePositif : public Sphere { + public: + SpherePositif(long s) : Sphere(s) {}; + virtual void fill(std::vector &); +}; + +#endif diff --git a/src/engine/Plugin/critere.hxx b/src/engine/Plugin/critere.hxx new file mode 100644 index 000000000..681ae5fef --- /dev/null +++ b/src/engine/Plugin/critere.hxx @@ -0,0 +1,32 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-03-18.22.39.34 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// critere classique en optimisation +// +//___________________________________________________________________ + + +#ifndef __CRITERE__ +#define __CRITERE__ + +#include + +class Critere { + public : + virtual std::vector *eval(std::vector &) = 0; +}; + + +#endif + diff --git a/src/engine/Plugin/decode.cxx b/src/engine/Plugin/decode.cxx new file mode 100644 index 000000000..01f698067 --- /dev/null +++ b/src/engine/Plugin/decode.cxx @@ -0,0 +1,79 @@ +// --- C++ --- +// --- coding: latin_1 --- +// +// File +// creation : 2007-02-21.13.37.58 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// decodage deu genotype +// +//___________________________________________________________________ + +#include "decode.hxx" + +#include + +// Decoder +void Decoder::echo(Solution &sol) +{ + std::vector *tmp; + std::vector::iterator j; + + tmp = decode(*sol.param); + for (j=tmp->begin(); j!= tmp->end(); j++) + std::cout << *j << " " ; + std::cout << std::endl << "->"; + delete tmp; + tmp = sol.obj; + for (j=tmp->begin(); j!= tmp->end(); j++) + std::cout << " " << *j ; + std::cout << std::endl ; + + return; +} + +// LinearDecoder +LinearDecoder::LinearDecoder(std::vector > &borne) +{ + int i; + + size = borne.size(); + a.resize(size); + b.resize(size); + for (i=0; i < size; i++) { + a[i] = borne[i].second - borne[i].first; + b[i] = borne[i].first; + } +} + +// representation interne -> representation physique +std::vector *LinearDecoder::decode(std::vector &in) +{ + std::vector *ret; + long i; + + ret = new std::vector(size); + for (i=0; i representation interne +std::vector *LinearDecoder::code(std::vector &in) +{ + std::vector *ret; + long i; + + ret = new std::vector(size); + for (i=0; i +#include + +#include "solution.hxx" + +class Decoder { + protected: + long size; + public: + virtual std::vector *code(std::vector &) = 0; + virtual std::vector *decode(std::vector &) = 0; + void echo(Solution &); +}; + +class LinearDecoder : public Decoder { + private : + std::vector a,b; + public : + LinearDecoder(std::vector > &); + virtual std::vector *code(std::vector &); + virtual std::vector *decode(std::vector &); +}; + +#endif diff --git a/src/engine/Plugin/distrib.hxx b/src/engine/Plugin/distrib.hxx new file mode 100644 index 000000000..01f19c14b --- /dev/null +++ b/src/engine/Plugin/distrib.hxx @@ -0,0 +1,34 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-02-26.03.14.22 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// distribution des calculs +// +//___________________________________________________________________ + + +#ifndef __DISTRIB__ +#define __DISTRIB__ + +#include +#include + + +class Distrib { + public : + virtual void put(long, std::vector &) = 0; + virtual std::vector *get(long *) = 0; +}; + +#endif + diff --git a/src/engine/Plugin/fonction.hxx b/src/engine/Plugin/fonction.hxx new file mode 100644 index 000000000..a58bbe52c --- /dev/null +++ b/src/engine/Plugin/fonction.hxx @@ -0,0 +1,30 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-02-26.04.24.28 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// prototype de la fonction d evaluation +// +//___________________________________________________________________ + + +#ifndef __FONCTION__ +#define __FONCTION__ + +#include + +class UserFun { + public : + virtual std::vector *eval(std::vector &) = 0; +}; + +#endif diff --git a/src/engine/Plugin/local.cxx b/src/engine/Plugin/local.cxx new file mode 100644 index 000000000..be34950db --- /dev/null +++ b/src/engine/Plugin/local.cxx @@ -0,0 +1,58 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-02-26.03.40.35 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// realisation des calculs en local +// +//___________________________________________________________________ + + +#include "local.hxx" + +Local::Local(UserFun &f) +{ + fun = &f; +} + +Local::~Local(void) +{ + std::pair *> pa; + + while (! q.empty()) { + pa = q.front(); + q.pop(); + delete pa.second; + } +} + +void Local::put(long id, std::vector &cal) +{ + std::pair *> *tmp; + + tmp = new std::pair *>(id, &cal); + q.push(*tmp); + delete tmp; +} + +std::vector *Local::get(long *id) +{ + std::vector *cal, *res; + std::pair *> pa; + + pa = q.front(); q.pop(); + *id = pa.first; cal = pa.second; + res = fun->eval(*cal); + delete cal; + return res; +} + diff --git a/src/engine/Plugin/local.hxx b/src/engine/Plugin/local.hxx new file mode 100644 index 000000000..5b5b0a615 --- /dev/null +++ b/src/engine/Plugin/local.hxx @@ -0,0 +1,42 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-02-26.03.40.22 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// realisation des calculs en local +// +//___________________________________________________________________ + + +#ifndef __LOCAL__ +#define __LOCAL__ + +#include +#include +#include + +#include "distrib.hxx" +#include "fonction.hxx" + + +class Local : Distrib { + protected : + UserFun *fun; + std::queue *> > q; + public : + Local(UserFun &); + ~Local(void); + virtual void put(long, std::vector &); + virtual std::vector *get(long *); +}; + +#endif diff --git a/src/engine/Plugin/maestro.cxx b/src/engine/Plugin/maestro.cxx new file mode 100644 index 000000000..aa3f41441 --- /dev/null +++ b/src/engine/Plugin/maestro.cxx @@ -0,0 +1,51 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-02-26.04.25.45 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// gestionnaire des calculs +// +//___________________________________________________________________ + +#include "maestro.hxx" + +Maestro::Maestro(Decoder &dm, Critere *crt, Distrib &dst) +{ + dom = &dm; + dist = &dst; + crit = crt; +} + +void Maestro::put(long id, std::vector &inp) +{ + std::vector *tmp; + + tmp = dom->decode(inp); + dist->put(id, *tmp); + return; +} + +std::vector *Maestro::get(long *id) +{ + std::vector *res, *crt; + + res = dist->get(id); + if (crit) { + crt = crit->eval(*res); + delete res; + } + else + crt = res; + return crt; +} + + diff --git a/src/engine/Plugin/maestro.hxx b/src/engine/Plugin/maestro.hxx new file mode 100644 index 000000000..9ca9ea28c --- /dev/null +++ b/src/engine/Plugin/maestro.hxx @@ -0,0 +1,41 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-02-26.04.25.36 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// gestionnaire des calculs +// +//___________________________________________________________________ + +#ifndef __MAESTRO__ +#define __MAESTRO__ + +#include + +#include "decode.hxx" +#include "distrib.hxx" +#include "critere.hxx" + +class Maestro { + private : + Decoder *dom; + Distrib *dist; + Critere *crit; + + public : + Maestro(Decoder &, Critere *, Distrib &); + void put(long, std::vector &); + std::vector *get(long *); +}; + +#endif + diff --git a/src/engine/Plugin/mt19937ar.cxx b/src/engine/Plugin/mt19937ar.cxx new file mode 100644 index 000000000..8a95d9a44 --- /dev/null +++ b/src/engine/Plugin/mt19937ar.cxx @@ -0,0 +1,192 @@ +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +#include + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializes mt[N] with a seed */ +void init_genrand(unsigned long s) +{ + mt[0]= s & 0xffffffffUL; + for (mti=1; mti> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +void init_by_array(unsigned long init_key[], int key_length) +{ + int i, j, k; + init_genrand(19650218UL); + i=1; j=0; + k = (N>key_length ? N : key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + + init_key[j] + j; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=N-1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) + - i; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + } + + mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void) +{ + unsigned long y; + static unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + if (mti == N+1) /* if init_genrand() has not been called, */ + init_genrand(5489UL); /* a default initial seed is used */ + + for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + } + for (;kk> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +/* generates a random number on [0,0x7fffffff]-interval */ +long genrand_int31(void) +{ + return (long)(genrand_int32()>>1); +} + +/* generates a random number on [0,1]-real-interval */ +double genrand_real1(void) +{ + return genrand_int32()*(1.0/4294967295.0); + /* divided by 2^32-1 */ +} + +/* generates a random number on [0,1)-real-interval */ +double genrand_real2(void) +{ + return genrand_int32()*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on (0,1)-real-interval */ +double genrand_real3(void) +{ + return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on [0,1) with 53-bit resolution*/ +double genrand_res53(void) +{ + unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; + return(a*67108864.0+b)*(1.0/9007199254740992.0); +} +/* These real versions are due to Isaku Wada, 2002/01/09 added */ + +#ifdef MT_TEST +int main(void) +{ + int i; + unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4; + init_by_array(init, length); + printf("1000 outputs of genrand_int32()\n"); + for (i=0; i<1000; i++) { + printf("%10lu ", genrand_int32()); + if (i%5==4) printf("\n"); + } + printf("\n1000 outputs of genrand_real2()\n"); + for (i=0; i<1000; i++) { + printf("%10.8f ", genrand_real2()); + if (i%5==4) printf("\n"); + } + return 0; +} +#endif diff --git a/src/engine/Plugin/point.cxx b/src/engine/Plugin/point.cxx new file mode 100644 index 000000000..1af7828b2 --- /dev/null +++ b/src/engine/Plugin/point.cxx @@ -0,0 +1,238 @@ +// --- C++ --- +// --- coding: latin_1 --- +// +// File +// creation : 2007-03-30.16.58.42 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// particules du simplex +// +//___________________________________________________________________ + + +#include "point.hxx" + +#include + +#define START 0 +#define FIRST 1 +#define GOOD 2 +#define SOGOOD 3 +#define TOOGOOD 4 +#define BAD 5 +#define TOOBAD 6 +#define SOBAD 7 +#define BADEST 8 + +#define SEUIL 1.0e-10 + +Point::Point(long sz) +{ + size = sz; + etat = START; + epsil = SEUIL; + rnd = new Cube(size); + start = (Solution *) NULL; + courant = (std::vector *) NULL; + baryc = (std::vector *) NULL; + minim = (std::vector *) NULL; +} + +Point::~Point(void) +{ + delete rnd; + if (courant) + delete courant; + if (start) { + delete start; + delete baryc; + delete minim; + } +} + +Solution *Point::inform(std::vector &obj) +{ + Solution *res, *tmp; + + res = (Solution *) NULL; + switch (etat) { + case START : +#ifdef SHOW + std::cout << "@" ; +#endif + res = new Solution(*courant, obj); + break; + case FIRST : + if (obj[0] > (*start->obj)[0]) { +#ifdef SHOW + std::cout << "-" ; +#endif + etat = BAD ; + delete courant; + delete &obj; + } + else { +#ifdef SHOW + std::cout << "+" ; +#endif + etat = GOOD ; + tmp = start; + start = new Solution(*courant, obj); + delete tmp; + } + break; + case GOOD : + if (obj[0] > (*start->obj)[0]) { +#ifdef SHOW + std::cout << "P" ; +#endif + etat = SOGOOD; + delete courant; + delete &obj; + res = start; + delete baryc; + delete minim; + start = (Solution *) NULL; + } + else { +#ifdef SHOW + std::cout << "p" ; +#endif + etat = TOOGOOD; + res = new Solution(*courant, obj); + } + break; + case BAD : + if (obj[0] > (*start->obj)[0]) { +#ifdef SHOW + std::cout << "M" ; +#endif + etat = TOOBAD; + delete courant; + delete &obj; + } + else { +#ifdef SHOW + std::cout << "m" ; +#endif + etat = SOBAD; + res = new Solution(*courant, obj); + } + break; + case TOOBAD: +#ifdef SHOW + std::cout << "X" ; +#endif + etat = BADEST; + res = new Solution(*courant, obj); + break; + default : + std::cout << "pbl inform" << std::endl ; + break; + } + return res; +} + +void Point::mute(Solution &pt, std::vector &bary, std::vector &minm) +{ + std::vector *tmp; + + if (start) { + delete baryc; + delete minim; + delete start; + } + start = &pt; + baryc = &bary; + minim = &minm; + etat = FIRST; +} + +void Point::reinit(void) +{ + etat = START; +} + +std::vector *Point::next(void) +{ + double d, dd; + int i; + + switch (etat) { + case START : + courant = rnd->gen(); + break; + case FIRST : + courant = symetrique(*start->param, *baryc); + break; + case GOOD : + courant = symetrique(*baryc, *start->param); + break; + case BAD : + courant = milieu(*baryc, *start->param); + break; + case TOOBAD : + courant = milieu(*minim, *start->param); + break; + default: + // raise + std::cout << "pbl next" << std::endl ; + } + if (baryc) { + d=0.0; + for (i=0; i *) NULL; + } + else + return courant; +} + +std::vector *Point::symetrique(std::vector &pt, std::vector ¢r) +{ + long i; + double coef, tmp; + std::vector *res; + + // bounded coef + coef = 1.0; + for (i=0; i 0.0) ? + (1.0 - centr[i]) / (centr[i] - pt[i]) : + centr[i] / (pt[i] - centr[i]) ; + coef = (coef < tmp) ? coef : tmp ; + } + // + res = new std::vector(size); + for (i=0; i *Point::milieu(std::vector &un, std::vector &deux) +{ + long i; + std::vector *res; + + res = new std::vector(size); + for (i=0; i + +#include "aleas.hxx" +#include "solution.hxx" + +class Point { + private: + int size, etat; + double epsil; + Cube *rnd; + Solution *start; + std::vector *courant, *baryc, *minim; + + std::vector *symetrique(std::vector &, std::vector &); + std::vector *milieu(std::vector &, std::vector &); + + public: + Point(long); + ~Point(void); + void reinit(void); + void mute(Solution &, std::vector &, std::vector &); + Solution *inform(std::vector &); + std::vector *next(void); +}; + +#endif + diff --git a/src/engine/Plugin/saclass.cxx b/src/engine/Plugin/saclass.cxx new file mode 100644 index 000000000..5c3db2a9e --- /dev/null +++ b/src/engine/Plugin/saclass.cxx @@ -0,0 +1,106 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-03-22.23.34.31 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// class pour test salome +// +//___________________________________________________________________ + + +#include "saclass.hxx" + +#include + +#include "topologie.hxx" + +#include "saconst.h" + + + +SalomeTest::SalomeTest(Superviseur &t) +{ + super = &t; + rnd1 = (SpherePositif *) NULL; + st1 = (Traditionnel *) NULL; + rnd2 = (Sphere *) NULL; + st2 = (Pivot *) NULL; + // distribution + dst = (SalomeEventLoop *) NULL; + dec = (LinearDecoder *) NULL; + mtr = (Maestro *) NULL; + // swarm + swrm = (MonoSwarm *) NULL; + +} + +SalomeTest::~SalomeTest(void) +{ + delete rnd1; + delete rnd2; + delete st1; + delete st2; + // distribution + delete dst; + delete dec; + delete mtr; + // swarm + delete swrm; +} + +void SalomeTest::readFromFile(std::string rien) +{ + std::vector > dom(NBGENE); + long i; + + // domaine de recherche + for (i=0; isetStop(NBEVAL); +} + +void SalomeTest::start(void) +{ + swrm->start(); +} + +void SalomeTest::next(void) +{ + int rien; + rien = swrm->next(); +} + +void SalomeTest::finish(void) +{ + Solution *res; + + swrm->finish(); + res = swrm->solution(); + dec->echo(*res); +} + diff --git a/src/engine/Plugin/saclass.hxx b/src/engine/Plugin/saclass.hxx new file mode 100644 index 000000000..227b6f2d3 --- /dev/null +++ b/src/engine/Plugin/saclass.hxx @@ -0,0 +1,59 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-03-22.23.34.41 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// class pour test salome +// +//___________________________________________________________________ + +#ifndef __SACLASS__ +#define __SACLASS__ + +#include + +#include "aleas.hxx" +#include "decode.hxx" +#include "salomevent.hxx" +#include "topologie.hxx" +#include "movement.hxx" +#include "maestro.hxx" +#include "mono.hxx" +#include "solution.hxx" + +#include "salomesup.hxx" + +class SalomeTest { + protected : + Superviseur *super; + SpherePositif *rnd1; + Sphere *rnd2; + Traditionnel *st1; + Pivot *st2; + // distribution + SalomeEventLoop *dst; + LinearDecoder *dec; + Maestro *mtr; + // swarm + MonoSwarm *swrm; + + public : + SalomeTest(Superviseur &); + ~SalomeTest(void); + void readFromFile(std::string); + void start(void); + void next(void); + void finish(void); +}; + +#endif + diff --git a/src/engine/Plugin/saconst.h b/src/engine/Plugin/saconst.h new file mode 100644 index 000000000..42a489df7 --- /dev/null +++ b/src/engine/Plugin/saconst.h @@ -0,0 +1,60 @@ +/* --- Ansi C --- */ +/* --- coding: latin_1 --- + + File + creation : 2007-06-27.09.30.21 + revision : $Id$ + + Copyright © 2007 Commissariat à l'Energie Atomique + par Gilles ARNAUD (DM2S/SFME/LETR) + C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France + Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 + Gilles.Arnaud@cea.fr + + Object + paramétrage utilisateur + +___________________________________________________________________*/ + +/* choix utilisateur */ +// nombre de ressources de parrallelisme +/* simplex */ +// #define NBNODE 1 +// #define NBNODE 4 +// #define NBNODE 16 +// #define NBNODE 64 +// #define NBNODE 256 +// #define NBNODE 1024 +#define NBNODE 2 +/* essaim particulaire */ +#define PLAN 36 +#define COTE 6 +// nombre maximum d'evaluation +#define NBEVAL 100000 + +// choix de la fonction a evaluer +// #define ROSENBROCK +// #define TRIPOD +// #define GRIEWANK +// + +#define ROSENBROCK + +/* constante dépendant du choix de l'évaluateur */ + +// nombre de paramètre +#ifdef GRIEWANK +#define NBGENE 30 +#else +#define NBGENE 2 +#endif + +// domaine de recherche +#ifdef ROSENBROCK +#define BORNEMIN -2.0 +#define BORNEMAX 2.0 +#else +#define BORNEMIN -100.0 +#define BORNEMAX 100.0 +#endif + diff --git a/src/engine/Plugin/saemul.cxx b/src/engine/Plugin/saemul.cxx new file mode 100644 index 000000000..fb1e6adc1 --- /dev/null +++ b/src/engine/Plugin/saemul.cxx @@ -0,0 +1,123 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-03-23.02.08.59 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// class emulateur superviseur salome +// +//___________________________________________________________________ + +#include "saemul.hxx" + +#include "saconst.h" + +#include "math.h" + +Emulator::Emulator(void) +{ + solver = new SalomeTest((Superviseur &) *this); +} + +Emulator::~Emulator(void) +{ + delete solver; + destroyAll(); +} + +void Emulator::destroyAll(void) +{ + std::pair *> pa; + + while (! q.empty()) { + pa = q.front(); + q.pop(); + delete pa.second; + } +} + +void Emulator::push(long id, std::vector &cal) +{ + std::pair *> *tmp; + + tmp = new std::pair *>(id, &cal); + q.push(*tmp); + delete tmp; +} + +long Emulator::getCurrentId(void) +{ + std::vector *cal; + std::pair *> pa; + + pa = q.front(); q.pop(); + cal = pa.second; + out = eval(*cal); + delete cal; + return pa.first; +} + +std::vector *Emulator::getCurrentOut(void) +{ + return out; +} + +std::vector *Emulator::eval(std::vector &x) +{ + std::vector *res; + res = new std::vector(1); +#ifdef TRIPOD + //Tripod + double x1, x2; + + x1 = x[0]; x2 = x[1]; + + if (x2 < 0) + (*res)[0] = fabs(x1) + fabs(x2+50); + else { + (*res)[0] = fabs(x2-50); + if (x1 < 0) + (*res)[0] += 1 + fabs(x1+50); + else + (*res)[0] += 2 + fabs(x1-50); + } +#endif +#ifdef ROSENBROCK + // rosenbrock + double x1, x2; + + x1 = x[0] ; x2 = x1*x1 - x[1]; x1 -= 1; + (*res)[0] = x1*x1 + 100*x2*x2 ; +#endif +#ifdef GRIEWANK + double x1, x2, y; + int i; + + x1 = 0.0; x2 = 1.0; + for (i=0; ireadFromFile("caca"); + solver->start(); + while (! q.empty()) + solver->next(); + solver->finish(); +} + diff --git a/src/engine/Plugin/saemul.hxx b/src/engine/Plugin/saemul.hxx new file mode 100644 index 000000000..4539e4e81 --- /dev/null +++ b/src/engine/Plugin/saemul.hxx @@ -0,0 +1,48 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-03-23.02.09.11 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// class emulateur superviseur salome +// +//___________________________________________________________________ + +#ifndef __SASUPER__ +#define __SASUPER__ + +#include +#include +#include + +#include "salomesup.hxx" + +#include "saclass.hxx" + +class Emulator : public Superviseur { + protected : + SalomeTest *solver; + std::queue *> > q; + std::vector *out; + + std::vector *eval(std::vector &x); + public : + Emulator(void); + ~Emulator(void); + void destroyAll(void); + void push(long id, std::vector &cal); + long getCurrentId(void); + std::vector *getCurrentOut(void); + void run(void); +}; + +#endif + diff --git a/src/engine/Plugin/salomesup.hxx b/src/engine/Plugin/salomesup.hxx new file mode 100644 index 000000000..a76ee67c2 --- /dev/null +++ b/src/engine/Plugin/salomesup.hxx @@ -0,0 +1,33 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-03-23.03.16.40 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// interface du superviseur salome +// +//___________________________________________________________________ + + + +#ifndef __SALOMESUP__ +#define __SALOMESUP__ + +class Superviseur { + public : + virtual void destroyAll(void) = 0; + virtual void push(long id, std::vector &cal) = 0; + virtual long getCurrentId(void) = 0; + virtual std::vector *getCurrentOut(void) = 0; +}; + +#endif + diff --git a/src/engine/Plugin/salomevent.cxx b/src/engine/Plugin/salomevent.cxx new file mode 100644 index 000000000..4f90ea007 --- /dev/null +++ b/src/engine/Plugin/salomevent.cxx @@ -0,0 +1,53 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-03-22.23.17.58 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// distribution via superviseur salome +// +//___________________________________________________________________ + + +#include "salomevent.hxx" + +#include "Any.hxx" + +using namespace YACS::ENGINE; + +SalomeEventLoop::SalomeEventLoop(Pool *sup) +{ + super = sup; +} + +void SalomeEventLoop::put(long i, std::vector &cal) +{ + SequenceAny *tmp = SequenceAny::New(cal); + super->pushInSample(i, (Any *)tmp); +} + +std::vector *SalomeEventLoop::get(long *id) +{ + SequenceAny *tmp; + std::vector *ret; + unsigned int nb, i; + + *id = super->getCurrentId(); + tmp = (SequenceAny *) super->getCurrentOutSample(); + nb = tmp->size(); + ret = new std::vector(nb); + for (i=0; igetDoubleValue(); + tmp->decrRef(); + + return ret; +} + diff --git a/src/engine/Plugin/salomevent.hxx b/src/engine/Plugin/salomevent.hxx new file mode 100644 index 000000000..c0b3b0762 --- /dev/null +++ b/src/engine/Plugin/salomevent.hxx @@ -0,0 +1,38 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-03-22.23.18.15 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// distribution via superviseur salome +// +//___________________________________________________________________ + + +#ifndef __SALOMEVENT__ +#define __SALOMEVENT__ + +#include "Pool.hxx" + +#include "distrib.hxx" + +class SalomeEventLoop : Distrib { + protected : + YACS::ENGINE::Pool *super; + public : + SalomeEventLoop(YACS::ENGINE::Pool *); + virtual void put(long, std::vector &); + virtual std::vector *get(long *); +}; + + +#endif + diff --git a/src/engine/Plugin/sasimpl.cxx b/src/engine/Plugin/sasimpl.cxx new file mode 100644 index 000000000..7b405af4d --- /dev/null +++ b/src/engine/Plugin/sasimpl.cxx @@ -0,0 +1,86 @@ +// --- C++ --- +// --- coding: latin_1 --- +// +// File +// creation : 2007-04-03.11.38.54 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// simplexe via salome evenementiel +// +//___________________________________________________________________ + +#include "sasimpl.hxx" + +#include "saconst.h" + +#include "solution.hxx" + +SalomeTest::SalomeTest(Superviseur &t) +{ + super = &t; + // distribution + dst = (SalomeEventLoop *) NULL; + dec = (LinearDecoder *) NULL; + mtr = (Maestro *) NULL; + // swarm + solv = (Simplex *) NULL; + +} + +SalomeTest::~SalomeTest(void) +{ + // distribution + delete dst; + delete dec; + delete mtr; + // swarm + delete solv; +} + +void SalomeTest::readFromFile(std::string rien) +{ + std::vector > dom(NBGENE); + long i; + + // domaine de recherche + for (i=0; isetStop(NBEVAL); +} + +void SalomeTest::start(void) +{ + solv->start(); +} + +void SalomeTest::next(void) +{ + int rien; + rien = solv->next(); +} + +void SalomeTest::finish(void) +{ + Solution *res; + + solv->finish(); + res = solv->solution(); + dec->echo(*res); +} + diff --git a/src/engine/Plugin/sasimpl.hxx b/src/engine/Plugin/sasimpl.hxx new file mode 100644 index 000000000..631e02535 --- /dev/null +++ b/src/engine/Plugin/sasimpl.hxx @@ -0,0 +1,52 @@ +// --- C++ --- +// --- coding: latin_1 --- +// +// File +// creation : 2007-04-03.11.39.15 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// simplexe via salome evenementiel +// +//___________________________________________________________________ + + +#ifndef __SASIMPL__ +#define __SASIMPL__ + +#include + +#include "decode.hxx" +#include "salomevent.hxx" +#include "maestro.hxx" +#include "simplex.hxx" + +#include "salomesup.hxx" + +class SalomeTest { + protected : + Superviseur *super; + // distribution + SalomeEventLoop *dst; + LinearDecoder *dec; + Maestro *mtr; + // swarm + Simplex *solv; + + public : + SalomeTest(Superviseur &); + ~SalomeTest(void); + void readFromFile(std::string); + void start(void); + void next(void); + void finish(void); +}; + +#endif + diff --git a/src/engine/Plugin/satest.cxx b/src/engine/Plugin/satest.cxx new file mode 100644 index 000000000..a98805887 --- /dev/null +++ b/src/engine/Plugin/satest.cxx @@ -0,0 +1,26 @@ +// -*- C++ -*- +// -*- coding: latin_1 -*- +// +// File +// creation : 2007-03-23.02.57.44 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// test superviseur salome via emulateur +// +//___________________________________________________________________ + +#include "saemul.hxx" + +int main(void) +{ + Emulator sup; + + sup.run(); +} diff --git a/src/engine/Plugin/simplex.cxx b/src/engine/Plugin/simplex.cxx new file mode 100644 index 000000000..b5ba49108 --- /dev/null +++ b/src/engine/Plugin/simplex.cxx @@ -0,0 +1,152 @@ +// --- C++ --- +// --- coding: latin_1 --- +// +// File +// creation : 2007-03-30.13.44.14 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// version distribue du simplex de nelder mead +// +//___________________________________________________________________ + + +#include "simplex.hxx" + +#include + +#include "aleas.hxx" + +Simplex::Simplex(long sz, long nbgen, Maestro &maest) +{ + size = sz; + nbin = nbgen; + calc = &maest; + maxe = 40000; + nbeval = 0; +} + +Simplex::~Simplex(void) +{ + int i; + + if (work.size() == size) { + for (i=0; iput(i, *(work[i]->next())); + } + nbeval = maxe; +} + + +int Simplex::next(void) +{ + long id; + Solution *pt, *pnt; + std::vector *next, *res; + + res = calc->get(&id); + nbeval--; + pt = work[id]->inform(*res); + if (pt) { + pnt = add(pt); + if (pnt) + work[id]->mute(*pnt, *barycentre(), *minimum()); + else + work[id]->reinit(); + } + next = work[id]->next(); + if (nbeval > size) + if (next) + calc->put(id, *next); + //else + // nbeval = size - 1; + return (nbeval > 0); +} + +void Simplex::finish(void) +{ + std::cout << maxe - nbeval << std::endl; + return; +} + +Solution *Simplex::solution(void) +{ + return simplx[0]; +} + +Solution *Simplex::add(Solution *sol) +{ + int i; + Solution *ret, *swp; + + if (simplx.size() < nbin) { + ret = (Solution *) NULL; + i = simplx.size(); + simplx.push_back(sol); + while (i && simplx[i]->obj[0] < simplx[i-1]->obj[0]) { + // TODO swap interne + swp = simplx[i]; + simplx[i] = simplx[i-1]; + simplx[i-1] = swp; + i--; + } + } + else if (sol->obj[0] > simplx[nbin-1]->obj[0]) + ret = sol; + else { + i = nbin -1; + ret = simplx[i]; + simplx[i] = sol; + while (i && simplx[i]->obj[0] < simplx[i-1]->obj[0]) { + swp = simplx[i]; + simplx[i] = simplx[i-1]; + simplx[i-1] = swp; + i--; + } + } + return ret; +} + +std::vector *Simplex::minimum(void) +{ + return new std::vector(*simplx[0]->param); +} + +std::vector *Simplex::barycentre(void) +{ + int i,j; + std::vector *ret; + + ret = new std::vector(nbin); + for (i=0; iparam)[i]; + (*ret)[i] /= nbin; + } + return ret; +} diff --git a/src/engine/Plugin/simplex.hxx b/src/engine/Plugin/simplex.hxx new file mode 100644 index 000000000..46a97aefc --- /dev/null +++ b/src/engine/Plugin/simplex.hxx @@ -0,0 +1,50 @@ +// --- C++ --- +// --- coding: latin_1 --- +// +// File +// creation : 2007-03-30.13.46.22 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// version distribue du simplex de nelder mead +// +//___________________________________________________________________ + +#ifndef __SIMPLEX__ +#define __SIMPLEX__ + +#include + +#include "solution.hxx" +#include "point.hxx" +#include "maestro.hxx" + +class Simplex { + protected: + long size, nbin, maxe, nbeval; + std::vector simplx; + std::vector work; + Maestro *calc; + + Solution *add(Solution *); + std::vector *minimum(void); + std::vector *barycentre(void); + + public : + Simplex(long, long, Maestro &); + ~Simplex(void); + void setStop(long); + void start(void); + int next(void); + void finish(void); + void solve(void); + Solution *solution(void); +}; + +#endif diff --git a/src/engine/Plugin/solution.cxx b/src/engine/Plugin/solution.cxx new file mode 100644 index 000000000..9eab08044 --- /dev/null +++ b/src/engine/Plugin/solution.cxx @@ -0,0 +1,46 @@ +// --- C++ --- +// --- coding: latin_1 --- +// +// File +// creation : 2007-02-22.15.08.41 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// individu solution +// +//___________________________________________________________________ + +#include "solution.hxx" + +#include + +Solution::Solution(std::vector &par, std::vector &crt) +{ + param = ∥ + obj = &crt; +} + +Solution::~Solution(void) +{ + delete param; + delete obj; +} + +void Solution::echo(void) +{ + int i; + + for (i=0; isize(); i++) + std::cout << (*param)[i] << " "; + std::cout << std::endl << "->" ; + for (i=0; isize(); i++) + std::cout << " " << (*obj)[i]; + std::cout << std::endl; +} + diff --git a/src/engine/Plugin/solution.hxx b/src/engine/Plugin/solution.hxx new file mode 100644 index 000000000..f1f8bf641 --- /dev/null +++ b/src/engine/Plugin/solution.hxx @@ -0,0 +1,34 @@ +// --- C++ --- +// --- coding: latin_1 --- +// +// File +// creation : 2007-02-22.15.08.27 +// revision : $Id$ +// +// Copyright © 2007 Commissariat à l'Energie Atomique +// par Gilles ARNAUD (DM2S/SFME/LETR) +// C.E. Saclay; Bat 454; 91191 GIF/YVETTE CEDEX; France +// Tel: 01 69 08 38 86; Fax : 33 1 69 08 85 68 +// Gilles.Arnaud@cea.fr +// +// Object +// individu solution +// +//___________________________________________________________________ + + +#ifndef __SOLUTION__ +#define __SOLUTION__ + +#include + +class Solution { + public : + std::vector *param, *obj; + + Solution(std::vector &, std::vector &); + ~Solution(void); + void echo(void); +}; + +#endif diff --git a/src/engine/Pool.cxx b/src/engine/Pool.cxx new file mode 100644 index 000000000..3c5a0e0e0 --- /dev/null +++ b/src/engine/Pool.cxx @@ -0,0 +1,194 @@ +#include "Pool.hxx" +#include "Any.hxx" + +#include +#include + +using namespace YACS::ENGINE; + +Any *Pool::ExpData::NOT_USED_NOR_COMPUTED = 0; + +Any *Pool::ExpData::USED_BUT_NOT_COMPUTED_YET = (Any *) 1; + +const char Pool::MESSAGEFORUNXSTNGID[]="The id specified not exists. Unable to handle with. Either internal error, or invalid use of Pool from Optimizer Algorithm"; + +Pool::ExpData::ExpData(Any *inValue, unsigned char priority):_in(inValue),_out(NOT_USED_NOR_COMPUTED),_priority(priority) +{ + if(_in) + _in->incrRef(); +} + +Pool::ExpData::ExpData(const ExpData& other):_in(other._in),_out(other._out),_priority(other._priority) +{ + if(_in) + _in->incrRef(); +} + +Pool::ExpData::~ExpData() +{ + if(_in) + _in->decrRef(); + if(_out!=USED_BUT_NOT_COMPUTED_YET && _out!=NOT_USED_NOR_COMPUTED) + _out->decrRef(); +} + +/*! + * When used _out is assumed to be equal to 'USED_BUT_NOT_COMPUTED_YET' before call. + */ +void Pool::ExpData::setOutValue(Any *outValue) +{ + if(_out!=USED_BUT_NOT_COMPUTED_YET && _out!=NOT_USED_NOR_COMPUTED) + _out->decrRef();//should absolutely never happend. + _out=outValue; + _out->incrRef(); +} + +/*! + * When called _out is assumed to be equal to 'NOT_USED_NOR_COMPUTED' before call. + */ +void Pool::ExpData::markItAsInUse() +{ + _out=USED_BUT_NOT_COMPUTED_YET; +} + +bool Pool::ExpData::isLaunchable() const +{ + return _out==NOT_USED_NOR_COMPUTED; +} + +//! Push a sample. \b WARNING inSample ownership is released to current Pool instance (this) ! +void Pool::pushInSample(int id, Any *inSample, unsigned char priority) +{ + std::pair eltToAdd(id,Pool::ExpData(inSample,priority)); + _container.push_back(eltToAdd); + inSample->decrRef(); +} + +void Pool::destroyAll() +{ + _container.clear(); +} + +void Pool::destroyCurrentCase() +{ + if(!_container.empty()) + _container.erase(_currentCase); +} + +/*! + * + * This method is typically called by OptimizerNode to check the consistency, that is to say that optimizer algorithm has not + * corrupted 'this'. + * + */ +void Pool::checkConsistency() throw(Exception) +{ + // First check unicity of ids. + std::set ids; + std::list< std::pair >::iterator iter; + for(iter=_container.begin();iter!=_container.end();iter++) + { + std::pair< std::set::iterator, bool > verdict=ids.insert((*iter).first); + if(verdict.second) + { + std::ostringstream what; + what << "Id with value : " << (*iter).first << " appears several times."; + throw Exception(what.str()); + } + } +} + +/*! + * \throw See the \b throw case of pushOutSampleAt method. + */ +void Pool::setCurrentId(int id) throw(Exception) +{ + std::list< std::pair >::iterator iter; + for(iter=_container.begin();iter!=_container.end();iter++) + if((*iter).first==id) + { + _currentCase=iter; + break; + } + if(iter==_container.end()) + throw Exception(MESSAGEFORUNXSTNGID); +} + +/*! + * + * Push a result of case discriminated by \b id. It also sets the \b _currentCase pointer on the case discriminated by \b id. + * So after this call, the call to setCurrentId with the same \b id is useless. + * \throw When case id is not found in 'this'. This is particulary true, if not an internal error, when optimizer algorithm + * has destroyed a case id different from its id. + * + */ +void Pool::putOutSampleAt(int id, Any *outValue) throw(Exception) +{ + std::list< std::pair >::iterator iter; + for(iter=_container.begin();iter!=_container.end();iter++) + if((*iter).first==id) + { + _currentCase=iter; + (*iter).second.setOutValue(outValue); + break; + } + if(iter==_container.end()) + throw Exception(MESSAGEFORUNXSTNGID); +} + +/*! + * + * This method is typically called by OptimizerNode instance owner of 'this' that wants to launch an another job on one branch. + * \return : In case there are more jobs to do 2 parameters are returned. + * - \b id to locate the computation to do. + * - \b priority attached. + * - \b value. + * In case no more jobs are required id and priority stay unchanged and the returned value is equal to 0. + * + */ +Any *Pool::getNextSampleWithHighestPriority(int& id, unsigned char& priority) const +{ + unsigned char myPriority=0; + std::list< std::pair >::const_iterator iter,ptToSelected; + ptToSelected=_container.end(); + for(iter=_container.begin();iter!=_container.end();iter++) + { + if((*iter).second.isLaunchable()) + if((*iter).second.getPriority()>myPriority || ptToSelected==_container.end()) + { + ptToSelected=iter; + myPriority=(*iter).second.getPriority(); + } + } + //Search performed. No performing output writings if needed. + if(ptToSelected==_container.end()) + return 0; + priority=myPriority; + id=(*ptToSelected).first; + return (*ptToSelected).second.inValue(); +} + +/*! + * + * Typically called after 'this->destroyCurrentCase' 'this->checkConsistency' and 'this->getNextSampleWithHighestPriority' have been called. + * At this point the case with id \b id is marked as in use in order to avoid to be used by an another branch of OptimizerNode. + * + */ +void Pool::markIdAsInUse(int id) +{ + std::list< std::pair >::iterator iter; + for(iter=_container.begin();iter!=_container.end();iter++) + if((*iter).first==id) + { + (*iter).second.markItAsInUse(); + break; + } +} + +/*! + * Typically called after takeDecision of OptimizerAlg as been performed. If true is returned, that is to say that convergence has been reached. + */ +bool Pool::empty() const +{ + return _container.empty(); +} diff --git a/src/engine/Pool.hxx b/src/engine/Pool.hxx new file mode 100644 index 000000000..9955b299e --- /dev/null +++ b/src/engine/Pool.hxx @@ -0,0 +1,64 @@ +#ifndef __POOL_HXX__ +#define __POOL_HXX__ + +#include "Exception.hxx" + +#include + +namespace YACS +{ + namespace ENGINE + { + class Any; + class OptimizerLoop; + + class Pool + { + friend class OptimizerLoop; + + class ExpData + { + private: + Any *_in; + Any *_out; + unsigned char _priority; + public: + ExpData(Any *inValue, unsigned char priority); + ExpData(const ExpData& other); + ~ExpData(); + Any *inValue() const { return _in; } + Any *outValue() const { return _out; } + void setOutValue(Any *outValue); + void markItAsInUse(); + bool isLaunchable() const; + unsigned char getPriority() const { return _priority; } + private: + static Any *NOT_USED_NOR_COMPUTED; + static Any *USED_BUT_NOT_COMPUTED_YET; + }; + private: + std::list< std::pair > _container; + std::list< std::pair >::iterator _currentCase; + public: + //For algorithm use + int getCurrentId() const { return (*_currentCase).first; } + Any *getCurrentInSample() const { return (*_currentCase).second.inValue(); } + Any *getCurrentOutSample() const { return (*_currentCase).second.outValue(); } + void pushInSample(int id, Any *inSample, unsigned char priority = 0); + void destroyAll(); + private: + //For OptimizerNode use + void destroyCurrentCase(); + void checkConsistency() throw(Exception); + void setCurrentId(int id) throw(Exception); + void putOutSampleAt(int id, Any *outValue) throw(Exception); + Any *getNextSampleWithHighestPriority(int& id, unsigned char& priority) const; + void markIdAsInUse(int id); + bool empty() const; + private: + static const char MESSAGEFORUNXSTNGID[]; + }; + } +} + +#endif diff --git a/src/engine/Port.cxx b/src/engine/Port.cxx index 9604bdb7f..9476c5100 100644 --- a/src/engine/Port.cxx +++ b/src/engine/Port.cxx @@ -1,16 +1,21 @@ #include "Port.hxx" +#include using namespace YACS::ENGINE; using namespace std; const char Port::NAME[]="Port"; -int Port::total_ = 0; +int Port::_total = 0; -Port::Port(Node *node) - : _node(node) +Port::Port(Node *node):_node(node) { - id_ = total_++; + _id = _total++; +} + +Port::Port(const Port& other, Node *newHelder):_node(newHelder) +{ + _id = _total++; } Port::~Port() @@ -21,8 +26,3 @@ string Port::getNameOfTypeOfCurrentInstance() const { return NAME; } - -// TypeCode * Port::type() -// { -// return _type; -// } diff --git a/src/engine/Port.hxx b/src/engine/Port.hxx index 53ef31a19..b886c0155 100644 --- a/src/engine/Port.hxx +++ b/src/engine/Port.hxx @@ -22,23 +22,17 @@ namespace YACS { 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[]; - + int getNumId() const { return _id; } protected: Port(Node *node); - + Port(const Port& other, Node *newHelder); + protected: Node *_node; - std::string _impl; - TypeCode *_type; - int id_; - static int total_; + int _id; + static int _total; + static const char NAME[]; }; } } diff --git a/src/engine/Proc.cxx b/src/engine/Proc.cxx new file mode 100644 index 000000000..0e9e92805 --- /dev/null +++ b/src/engine/Proc.cxx @@ -0,0 +1,182 @@ +#include "Proc.hxx" +#include "Runtime.hxx" +#include "Container.hxx" +#include "Visitor.hxx" +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +Proc::Proc(const std::string& name):Bloc(name) +{ + Runtime *theRuntime=getRuntime(); + DEBTRACE("theRuntime->_tc_double->ref: " << theRuntime->_tc_double->getRefCnt()); + DEBTRACE("theRuntime->_tc_int->ref: " << theRuntime->_tc_int->getRefCnt()); + DEBTRACE("theRuntime->_tc_string->ref: " << theRuntime->_tc_string->getRefCnt()); + DEBTRACE("theRuntime->_tc_bool->ref: " << theRuntime->_tc_bool->getRefCnt()); + DEBTRACE("theRuntime->_tc_file->ref: " << theRuntime->_tc_file->getRefCnt()); + theRuntime->_tc_double->incrRef(); + theRuntime->_tc_string->incrRef(); + theRuntime->_tc_int->incrRef(); + theRuntime->_tc_bool->incrRef(); + theRuntime->_tc_file->incrRef(); + typeMap["double"]=theRuntime->_tc_double; + typeMap["string"]=theRuntime->_tc_string; + typeMap["int"]=theRuntime->_tc_int; + typeMap["bool"]=theRuntime->_tc_bool; + typeMap["file"]=theRuntime->_tc_file; +} + +Proc::~Proc() +{ + //for the moment all nodes are owned, so no need to manage their destruction + //nodeMap, inlineMap, serviceMap will be cleared automatically + //but we need to destroy TypeCodes + std::map::iterator pt; + for(pt=typeMap.begin();pt!=typeMap.end();pt++) + ((*pt).second)->decrRef(); + + //get rid of containers in container map + std::map::const_iterator it; + for(it=containerMap.begin();it!=containerMap.end();it++) + ((*it).second)->decrRef(); +} + +void Proc::writeDot(std::ostream &os) +{ + os << "digraph " << getQualifiedName() << " {\n" ; + os << "node [ style=\"filled\" ];\n" ; + os << "compound=true;"; + Bloc::writeDot(os); + os << "}\n" ; +} + +std::ostream& operator<< (std::ostream& os, const Proc& p) +{ + os << "Proc" ; + return os; +} + +TypeCode *Proc::createType(const std::string& name, const std::string& kind) +{ + TypeCode* t; + if(kind=="double") + t=getRuntime()->_tc_double; + else if(kind=="string") + t=getRuntime()->_tc_string; + else if(kind=="int") + t=getRuntime()->_tc_int; + else if(kind=="bool") + t=getRuntime()->_tc_bool; + else + throw Exception("Unknown kind"); + + t->incrRef(); + return t; +} + +TypeCode *Proc::createInterfaceTc(const std::string& id, const std::string& name, + std::list ltc) +{ + return TypeCode::interfaceTc(id.c_str(),name.c_str(),ltc); +} + +TypeCode * Proc::createSequenceTc (const std::string& id, const std::string& name, + TypeCode *content) +{ + return TypeCode::sequenceTc(id.c_str(),name.c_str(),content); +} + +TypeCode * Proc::createStructTc (const std::string& id, const std::string& name) +{ + return TypeCode::structTc(id.c_str(),name.c_str()); +} + +TypeCode * Proc::getTypeCode (const std::string& name) +{ + if(typeMap.count(name)==0) + { + std::stringstream msg; + msg << "Type " << name << " does not exist" ; + msg << " (" <<__FILE__ << ":" << __LINE__ << ")"; + throw Exception(msg.str()); + } + return typeMap[name]; +} + +void Proc::setTypeCode (const std::string& name,TypeCode *t) +{ + if(typeMap.count(name)!=0) + typeMap[name]->decrRef(); + typeMap[name]=t; +} + + +void Proc::accept(Visitor *visitor) +{ + visitor->visitProc(this); +} + +void Proc::setName(const std::string& name) +{ + _name = name; +} + +YACS::StatesForNode Proc::getNodeState(int numId) +{ + if(YACS::ENGINE::Node::idMap.count(numId) == 0) + { + cerr << "Unknown node id " << numId << endl; + return YACS::UNDEFINED; + } + YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[numId]; + YACS::StatesForNode state = node->getEffectiveState(); + return state; +} + +std::string Proc::getXMLState(int numId) +{ + if(YACS::ENGINE::Node::idMap.count(numId) == 0) + { + cerr << "Unknown node id " << numId << endl; + return "unknown"; + } + YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[numId]; + stringstream msg; + msg << "" << node->getEffectiveState() << ""; + msg << "" << node->getQualifiedName() << ""; + msg << "" << numId << ""; + return msg.str(); +} + +std::list Proc::getNumIds() +{ + set nodes = getAllRecursiveConstituents(); + int len = nodes.size(); + list numids; + for( set::const_iterator iter = nodes.begin(); + iter != nodes.end(); iter++) + { + numids.push_back((*iter)->getNumId()); + } + numids.push_back(this->getNumId()); + return numids; +} + +std::list Proc::getIds() +{ + set nodes = getAllRecursiveConstituents(); + int len = nodes.size(); + list ids; + for( set::const_iterator iter = nodes.begin(); + iter != nodes.end(); iter++) + { + ids.push_back(getChildName(*iter)); + } + ids.push_back("_root_"); + return ids; +} diff --git a/src/engine/Proc.hxx b/src/engine/Proc.hxx new file mode 100644 index 000000000..77518b8de --- /dev/null +++ b/src/engine/Proc.hxx @@ -0,0 +1,52 @@ +#ifndef _PROC_HXX_ +#define _PROC_HXX_ + +#include "Bloc.hxx" +#include +#include +#include + +namespace YACS +{ + namespace ENGINE + { + class TypeCode; + class TypeCodeObjref; + class InlineNode; + class ServiceNode; + class Container; + + class Proc: public Bloc + { + public: + Proc(const std::string& name); + virtual ~Proc(); + virtual TypeCode *createType(const std::string& name, const std::string& kind); + virtual TypeCode *createInterfaceTc(const std::string& id, const std::string& name, + std::list ltc); + virtual TypeCode *createSequenceTc (const std::string& id, const std::string& name, + TypeCode *content); + virtual TypeCode *createStructTc (const std::string& id, const std::string& name); + virtual TypeCode* getTypeCode(const std::string& name); + virtual void setTypeCode(const std::string& name,TypeCode *t); + virtual void accept(Visitor *visitor); + + YACS::StatesForNode getNodeState(int numId); + std::string getXMLState(int numId); + std::list getNumIds(); + std::list getIds(); + + virtual void writeDot(std::ostream &os); + void setName(const std::string& name); // Used by GUI to display graph name + friend std::ostream & operator<< ( std::ostream &os, const Proc& p); + std::map nodeMap; + std::map serviceMap; + std::map inlineMap; + std::map typeMap; + std::map containerMap; + std::vector names; + }; + } +} + +#endif diff --git a/src/engine/RefCounter.cxx b/src/engine/RefCounter.cxx new file mode 100644 index 000000000..a38f41590 --- /dev/null +++ b/src/engine/RefCounter.cxx @@ -0,0 +1,49 @@ +#include "RefCounter.hxx" +//#define REFCNT + +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; + +unsigned int RefCounter::_totalCnt=0; + +void RefCounter::incrRef() const +{ +#ifdef REFCNT + RefCounter::_totalCnt++; +#endif + _cnt++; +} + +bool RefCounter::decrRef() +{ +#ifdef REFCNT + RefCounter::_totalCnt--; +#endif + bool ret=(--_cnt==0); + if(ret) + delete this; + return ret; +} + +RefCounter::RefCounter():_cnt(1) +{ +#ifdef REFCNT + RefCounter::_totalCnt++; +#endif +} + +RefCounter::~RefCounter() +{ +#ifdef REFCNT + if(_cnt > 0) + { + DEBTRACE("Ref count > 0: " << this << " " << _cnt); + AttachDebugger(); + } +#endif +} diff --git a/src/engine/RefCounter.hxx b/src/engine/RefCounter.hxx new file mode 100644 index 000000000..1d7acdb9a --- /dev/null +++ b/src/engine/RefCounter.hxx @@ -0,0 +1,24 @@ +#ifndef __REFCOUNTER_HXX__ +#define __REFCOUNTER_HXX__ + +namespace YACS +{ + namespace ENGINE + { + class RefCounter + { + public: + unsigned int getRefCnt() const { return _cnt; } + void incrRef() const; + bool decrRef(); + static unsigned int _totalCnt; + protected: + RefCounter(); + virtual ~RefCounter(); + protected: + mutable unsigned int _cnt; + }; + } +} + +#endif diff --git a/src/engine/Runtime.cxx b/src/engine/Runtime.cxx index a9c423a04..b8d44d381 100644 --- a/src/engine/Runtime.cxx +++ b/src/engine/Runtime.cxx @@ -1,17 +1,33 @@ #include "Runtime.hxx" #include +#include "WhileLoop.hxx" +#include "ForLoop.hxx" +#include "ForEachLoop.hxx" +#include "Switch.hxx" +#include "Bloc.hxx" +#include "Proc.hxx" +#include "InputDataStreamPort.hxx" +#include "OutputDataStreamPort.hxx" +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" 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(); -} +// --- init typecodes for edInit with C++ Any + +TypeCode *Runtime::_tc_double = new TypeCode(Double); +TypeCode *Runtime::_tc_int = new TypeCode(Int); +TypeCode *Runtime::_tc_bool = new TypeCode(Bool); +TypeCode *Runtime::_tc_string = new TypeCode(String); +TypeCode *Runtime::_tc_file = new TypeCodeObjref("file", "file"); + +const char Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME[]="Neutral"; // singleton creation must be done before by a derived class @@ -22,32 +38,94 @@ Runtime* YACS::ENGINE::getRuntime() throw(Exception) return Runtime::_singleton; } -ElementaryNode* Runtime::createNode(string implementation, - string name) throw(Exception) +Runtime::~Runtime() +{ + DEBTRACE( "_tc_double refcnt: " << Runtime::_tc_double->getRefCnt() ); + DEBTRACE( "_tc_int refcnt: " << Runtime::_tc_int->getRefCnt() ); + DEBTRACE( "_tc_bool refcnt: " << Runtime::_tc_bool->getRefCnt() ); + DEBTRACE( "_tc_string refcnt: " << Runtime::_tc_string->getRefCnt() ); + DEBTRACE( "_tc_file refcnt: " << Runtime::_tc_file->getRefCnt() ); + Runtime::_tc_double->decrRef(); + Runtime::_tc_int->decrRef(); + Runtime::_tc_bool->decrRef(); + Runtime::_tc_string->decrRef(); + Runtime::_tc_file->decrRef(); + Runtime::_singleton=0; + DEBTRACE( "Total YACS::ENGINE::Refcount: " << RefCounter::_totalCnt ); +} + +InlineFuncNode* Runtime::createFuncNode(const std::string& kind,const std::string& name) +{ + throw Exception("FuncNode factory not implemented"); +} + +InlineNode* Runtime::createScriptNode(const std::string& kind,const std::string& name) +{ + throw Exception("ScriptNode factory not implemented"); +} + +ServiceNode* Runtime::createRefNode(const std::string& kind,const std::string& name) { - return new TestElemNode(name); + throw Exception("RefNode factory not implemented"); } - -InputPort* Runtime::createInputPort(const string& name, - const string& impl, - Node * node, - TypeCode * type) + +ServiceNode* Runtime::createCompoNode(const std::string& kind,const std::string& name) +{ + throw Exception("CompoNode factory not implemented"); +} + +ServiceInlineNode *Runtime::createSInlineNode(const std::string& kind, const std::string& name) +{ + throw Exception("SInlineNode factory not implemented"); +} + +ComponentInstance* Runtime::createComponentInstance(const std::string& name, + const std::string& kind) +{ + throw Exception("ComponentInstance factory not implemented"); +} + +Container *Runtime::createContainer(const std::string& kind) +{ + throw Exception("Container factory not implemented"); +} + +Proc* Runtime::createProc(const std::string& name) +{ + return new Proc(name); +} + +Bloc* Runtime::createBloc(const std::string& name) +{ + return new Bloc(name); +} + +Switch* Runtime::createSwitch(const std::string& name) +{ + return new Switch(name); +} + +WhileLoop* Runtime::createWhileLoop(const std::string& name) +{ + return new WhileLoop(name); +} + +ForLoop* Runtime::createForLoop(const std::string& name) +{ + return new ForLoop(name); +} + +ForEachLoop* Runtime::createForEachLoop(const std::string& name,TypeCode *type) { - return new InputPort(name, node, type); + return new ForEachLoop(name,type); } -OutputPort* Runtime::createOutputPort(const string& name, - const string& impl, - Node * node, - TypeCode * type) +InputDataStreamPort* Runtime::createInputDataStreamPort(const std::string& name,Node *node,TypeCode *type) { - return new OutputPort(name, node, type); + return new InputDataStreamPort(name,node,type); } -InputPort* Runtime::adapt(const string& imp_source, - InputPort* source, - const string& impl,TypeCode * type) - throw (ConversionException) +OutputDataStreamPort* Runtime::createOutputDataStreamPort(const std::string& name,Node *node,TypeCode *type) { - return source; + return new OutputDataStreamPort(name,node,type); } diff --git a/src/engine/Runtime.hxx b/src/engine/Runtime.hxx index 9aa146757..2e8b65f0f 100644 --- a/src/engine/Runtime.hxx +++ b/src/engine/Runtime.hxx @@ -1,69 +1,97 @@ - #ifndef _RUNTIME_HXX_ #define _RUNTIME_HXX_ -#include "TypeCode.hxx" -#include "ElementaryNode.hxx" -#include "OutputPort.hxx" -#include "InputPort.hxx" +#include "ConversionException.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() {}; - }; + Runtime* getRuntime() throw(Exception); // singleton creation + class InputPort; + class OutputPort; + class ForLoop; + class ForEachLoop; + class WhileLoop; + class Switch; + class InlineNode; + class InlineFuncNode; + class ServiceNode; + class Container; + class ServiceInlineNode; + class ComponentInstance; + class Proc; + class Bloc; + class ElementaryNode; + class Node; + class TypeCode; + class InputDataStreamPort; + class OutputDataStreamPort; - class Runtime { + friend Runtime* getRuntime() throw(Exception); public: - static void setRuntime(); // singleton creation - - friend Runtime* getRuntime() throw(Exception); // singleton creation - - virtual void init(){}; - virtual void fini(){}; + virtual void init() { } + virtual void fini() { } + + virtual InlineFuncNode* createFuncNode(const std::string& kind,const std::string& name); + virtual InlineNode* createScriptNode(const std::string& kind,const std::string& name); + + virtual ServiceNode* createRefNode(const std::string& kind,const std::string& name); + virtual ServiceNode* createCompoNode(const std::string& kind,const std::string& name); + virtual ServiceInlineNode *createSInlineNode(const std::string& kind, const std::string& name); + + virtual ComponentInstance* createComponentInstance(const std::string& name, + const std::string& kind=""); + virtual Container *createContainer(const std::string& kind=""); + virtual Proc* createProc(const std::string& name); + virtual Bloc* createBloc(const std::string& name); + virtual WhileLoop* createWhileLoop(const std::string& name); + virtual ForLoop* createForLoop(const std::string& name); + virtual ForEachLoop* createForEachLoop(const std::string& name,TypeCode * type); + virtual Switch* createSwitch(const std::string& name); - 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); + const std::string& impl, + Node * node, + TypeCode * type) = 0; virtual OutputPort* createOutputPort(const std::string& name, - const std::string& impl, - Node * node, - TypeCode * type); + const std::string& impl, + Node * node, + TypeCode * type) = 0; + + virtual InputDataStreamPort* createInputDataStreamPort(const std::string& name, + Node * node, + TypeCode * type); + virtual OutputDataStreamPort* createOutputDataStreamPort(const std::string& name, + Node * node, + TypeCode * type); - virtual InputPort* adapt(const std::string& imp_source, - InputPort* source, - const std::string& impl,TypeCode * type) - throw (ConversionException); + virtual InputPort* adapt(InputPort* source, const std::string& impl, TypeCode * type) throw (ConversionException) = 0; + virtual ~Runtime(); + public: + static const char RUNTIME_ENGINE_INTERACTION_IMPL_NAME[]; + static YACS::ENGINE::TypeCode *_tc_double; + static YACS::ENGINE::TypeCode *_tc_int; + static YACS::ENGINE::TypeCode *_tc_bool; + static YACS::ENGINE::TypeCode *_tc_string; + static YACS::ENGINE::TypeCode *_tc_file; protected: static Runtime* _singleton; - Runtime() {}; + Runtime() { } std::set _setOfImplementation; + }; } } diff --git a/src/engine/Scheduler.hxx b/src/engine/Scheduler.hxx index 00c25cfd2..055397328 100644 --- a/src/engine/Scheduler.hxx +++ b/src/engine/Scheduler.hxx @@ -1,9 +1,13 @@ + #ifndef __SCHEDULER_HXX__ #define __SCHEDULER_HXX__ -#include +#include "DeploymentTree.hxx" #include "define.hxx" +#include +#include + namespace YACS { namespace ENGINE @@ -13,11 +17,19 @@ namespace YACS class Scheduler { public: - virtual void init() = 0; + virtual void init(bool start=true) = 0; virtual bool isFinished() = 0; + virtual void exUpdateState() = 0; + virtual std::string getName() const = 0; + virtual std::string getTaskName(Task *task) const = 0; virtual std::vector getNextTasks(bool& isMore) = 0; virtual void selectRunnableTasks(std::vector& tasks) = 0; virtual void notifyFrom(const Task *sender, YACS::Event event) = 0; + //Placement methods + virtual DeploymentTree getDeploymentTree() const = 0; + virtual bool isPlacementPredictableB4Run() const = 0; + virtual bool isMultiplicitySpecified(unsigned& value) const = 0; + virtual void forceMultiplicity(unsigned value) = 0; }; } } diff --git a/src/engine/ServiceInlineNode.cxx b/src/engine/ServiceInlineNode.cxx new file mode 100644 index 000000000..63d205cb3 --- /dev/null +++ b/src/engine/ServiceInlineNode.cxx @@ -0,0 +1,27 @@ +#include "ServiceInlineNode.hxx" +#include "Visitor.hxx" + +using namespace YACS::ENGINE; + +ServiceInlineNode::ServiceInlineNode(const std::string& name):ServiceNode(name) +{ +} + +ServiceInlineNode::ServiceInlineNode(const ServiceInlineNode& other, ComposedNode *father):ServiceNode(other,father),_script(other._script) +{ +} + +void ServiceInlineNode::setScript (const std::string &script) +{ + _script=script; +} + +std::string ServiceInlineNode::getScript() const +{ + return _script; +} + +void ServiceInlineNode::accept(Visitor *visitor) +{ + visitor->visitServiceInlineNode(this); +} diff --git a/src/engine/ServiceInlineNode.hxx b/src/engine/ServiceInlineNode.hxx new file mode 100644 index 000000000..638008777 --- /dev/null +++ b/src/engine/ServiceInlineNode.hxx @@ -0,0 +1,28 @@ +#ifndef __SERVICEINLINENODE_HXX__ +#define __SERVICEINLINENODE_HXX__ + +#include "ServiceNode.hxx" +#include + +namespace YACS +{ + namespace ENGINE + { + class Visitor; + + class ServiceInlineNode: public ServiceNode + { + protected: + ServiceInlineNode(const std::string& name); + ServiceInlineNode(const ServiceInlineNode& other, ComposedNode *father); + public: + void setScript (const std::string &script); + std::string getScript() const; + void accept(Visitor *visitor); + protected: + std::string _script; + }; + } +} + +#endif diff --git a/src/engine/ServiceNode.cxx b/src/engine/ServiceNode.cxx new file mode 100644 index 000000000..2b4e4bca8 --- /dev/null +++ b/src/engine/ServiceNode.cxx @@ -0,0 +1,133 @@ +#include "ServiceNode.hxx" +#include "Visitor.hxx" +#include "ComponentInstance.hxx" +#include "ComposedNode.hxx" +#include "Runtime.hxx" +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; + +const char ServiceNode::KIND[]=""; + +std::string ServiceNode::getKind() const +{ + return KIND; +} + +ServiceNode::ServiceNode(const std::string& name):ElementaryNode(name),_component(0) +{ +} + +ServiceNode::ServiceNode(const ServiceNode& other, ComposedNode *father) + :ElementaryNode(other,father),_method(other._method),_component(0) +{ +} + +void ServiceNode::performDuplicationOfPlacement(const Node& other) +{ + const ServiceNode &otherC=*(dynamic_cast(&other)); + //if other has no component don't clone: this will not have one + if(otherC._component) + _component=otherC._component->clone(); +} + +ServiceNode::~ServiceNode() +{ + if(_component) + _component->decrRef(); +} + +//! Load the component associated to the node +void ServiceNode::load() +{ + if(_component) + { + if(!_component->isLoaded()) + _component->load(); + } + else + { + std::string what("ServiceNode::load : a load operation requested on ServiceNode called \""); + what+=_name; what+="\" with no component specified."; + throw Exception(what); + } +} + +void ServiceNode::accept(Visitor *visitor) +{ + visitor->visitServiceNode(this); +} + +//! Return the associated component instance +ComponentInstance *ServiceNode::getComponent() +{ + return _component; +} + +//! By definition of ServiceNode class. +bool ServiceNode::isDeployable() const +{ + return true; +} + +//! Associate an existing component instance to this service node \b AND check the consistency regarding the deployment from root node point of view. +void ServiceNode::setComponent(ComponentInstance* compo) throw(Exception) +{ + if(compo) + if(compo->getKind() != this->getKind()) + { + //Not allowed + std::string what("ServiceNode::setComponent : component instance kind not allowed "); + throw Exception(what); + } + if(_component) + { + //The node is already associated with a component instance + _component->decrRef(); + //Don't forget to unassociate + } + _component=compo; + if(_component) + { + if(_father) + try + { + getRootNode()->checkDeploymentTree(false); + } + catch(Exception& e) + { + _component=0; + throw e; + } + _component->incrRef(); + } + assert(_component); +} + +//! Associate a new component instance to this service node +/*! + * A new component instance with type name ref is created (from runtime + * factory createComponentInstance) and associated to the node. + * + */ +void ServiceNode::setRef(const std::string& ref) +{ + _ref = ref; + if(_component) + { + //The node is already associated with a component instance + _component->decrRef(); + //Don't forget to unassociate + } + _component= getRuntime()->createComponentInstance(ref,getKind()); + assert(_component); +} + +std::string ServiceNode::getRef() +{ + return _ref; +} diff --git a/src/engine/ServiceNode.hxx b/src/engine/ServiceNode.hxx new file mode 100644 index 000000000..d8b687d2c --- /dev/null +++ b/src/engine/ServiceNode.hxx @@ -0,0 +1,55 @@ +#ifndef __SERVICENODE_HXX__ +#define __SERVICENODE_HXX__ + +#include "ElementaryNode.hxx" +#include + +namespace YACS +{ + namespace ENGINE + { + class ComponentInstance; + +/*! \brief Class for calculation node associated with a component service + * + * \ingroup Nodes + * + * \see InlineNode + * \see ElementaryNode + */ + class ServiceNode: public ElementaryNode + { + protected: + ServiceNode(const std::string& name); + ServiceNode(const ServiceNode& other, ComposedNode *father); + void performDuplicationOfPlacement(const Node& other); + public: + virtual void load(); + virtual bool isDeployable() const; + virtual void setComponent(ComponentInstance* compo) throw(Exception); + virtual ComponentInstance *getComponent(); + virtual void setRef(const std::string& ref); + virtual std::string getRef(); + virtual void setMethod(const std::string& method){ _method=method; } + virtual std::string getMethod(){return _method;} + virtual ServiceNode *createNode(const std::string& name) = 0; + virtual ~ServiceNode(); + virtual void accept(Visitor *visitor); + +//! Return the service node kind +/*! + * A runtime can provide several implementations of a service node. + * Each implementation has a different kind. A ComponentInstance can be + * associated to a ServiceNode with the same kind. + */ + virtual std::string getKind() const; + static const char KIND[]; + protected: + ComponentInstance* _component; + std::string _method; + std::string _ref; + }; + } +} + +#endif diff --git a/src/engine/SharedPtr.hxx b/src/engine/SharedPtr.hxx new file mode 100644 index 000000000..6091dd315 --- /dev/null +++ b/src/engine/SharedPtr.hxx @@ -0,0 +1,44 @@ +#ifndef __SHAREDPTR_HXX__ +#define __SHAREDPTR_HXX__ + +/*! + * \brief: Allow to manage memory of instances of T. + * The only constraint on T is to have method incrRef and DecrRef. + * Typically T inherits from YACS::ENGINE::RefCounter. + */ +template +class SharedPtr +{ +private: + T *_ptr; +public: + SharedPtr(T *ptr):_ptr(ptr) { } + SharedPtr(const SharedPtr& other):_ptr(other._ptr) { _ptr->incrRef(); } + SharedPtr &operator=(const SharedPtr& other); + T &operator*() { return *_ptr; } + const T &operator*() const { return *_ptr; } + T *operator->() { return _ptr; } + const T *operator->() const { return _ptr; } + ~SharedPtr() { _ptr->decrRef(); } + operator T *() { return _ptr; } + operator const T *() const { return _ptr; } + operator T &() { return *_ptr; } + operator const T &() const { return *_ptr; } + SharedPtr operator[](int i) const; +}; + +template +SharedPtr &SharedPtr::operator=(const SharedPtr& other) +{ + _ptr->decrRef(); + _ptr=other._ptr; + _ptr->incrRef(); +} + +template +SharedPtr SharedPtr::operator[](int i) const +{ + return (*_ptr)[i]; +} + +#endif diff --git a/src/engine/StaticDefinedComposedNode.cxx b/src/engine/StaticDefinedComposedNode.cxx new file mode 100644 index 000000000..8edca1f83 --- /dev/null +++ b/src/engine/StaticDefinedComposedNode.cxx @@ -0,0 +1,28 @@ +#include "StaticDefinedComposedNode.hxx" + +using namespace std; +using namespace YACS::ENGINE; + +StaticDefinedComposedNode::StaticDefinedComposedNode(const std::string& name):ComposedNode(name) +{ +} + +StaticDefinedComposedNode::StaticDefinedComposedNode(const StaticDefinedComposedNode& other, ComposedNode *father):ComposedNode(other,father) +{ +} + +bool StaticDefinedComposedNode::isPlacementPredictableB4Run() const +{ + return true; +} + +bool StaticDefinedComposedNode::isMultiplicitySpecified(unsigned& value) const +{ + value=1; + return true; +} + +void StaticDefinedComposedNode::forceMultiplicity(unsigned value) +{ + //no sense for this class +} diff --git a/src/engine/StaticDefinedComposedNode.hxx b/src/engine/StaticDefinedComposedNode.hxx new file mode 100644 index 000000000..a59551b14 --- /dev/null +++ b/src/engine/StaticDefinedComposedNode.hxx @@ -0,0 +1,27 @@ +#ifndef __STATICDEFINEDCOMPOSEDNODE_HXX__ +#define __STATICDEFINEDCOMPOSEDNODE_HXX__ + +#include "ComposedNode.hxx" + +namespace YACS +{ + namespace ENGINE + { + /*! + * Abstract class, that factorizes all the treatments relative to resource management for ComposedNode that have + * their connectivity fully defined before launching ; which is not always the case for classes inheriting from DynParaLoop. + */ + class StaticDefinedComposedNode : public ComposedNode + { + protected: + StaticDefinedComposedNode(const std::string& name); + StaticDefinedComposedNode(const StaticDefinedComposedNode& other, ComposedNode *father); + public: + bool isPlacementPredictableB4Run() const; + bool isMultiplicitySpecified(unsigned& value) const; + void forceMultiplicity(unsigned value); + }; + } +} + +#endif diff --git a/src/engine/Switch.cxx b/src/engine/Switch.cxx index 4d4ad76f7..af2442f45 100644 --- a/src/engine/Switch.cxx +++ b/src/engine/Switch.cxx @@ -1,29 +1,670 @@ #include "Switch.hxx" +#include "Visitor.hxx" + +#include +#include +#include using namespace YACS::ENGINE; using namespace std; -Switch::Switch(const string& name):ComposedNode(name) +const char Switch::DEFAULT_NODE_NAME[]="default"; +const int Switch::ID_FOR_DEFAULT_NODE=-1979020617; +const char Switch::SELECTOR_INPUTPORT_NAME[]="select"; + +int CollectorSwOutPort::edGetNumberOfOutLinks() const +{ + return 1; +} + +std::set CollectorSwOutPort::edSetInPort() const +{ + set ret; + if(_consumer) + ret.insert(_consumer); + return ret; +} + +bool CollectorSwOutPort::isAlreadyLinkedWith(InPort *with) const +{ + set s; + with->getAllRepresentants(s); + return s.find(_consumer)!=s.end(); +} + +std::string CollectorSwOutPort::getNameOfTypeOfCurrentInstance() const +{ + return _className; +} + +void CollectorSwOutPort::edRemoveAllLinksLinkedWithMe() throw(Exception) +{ + map::iterator pt; + if(_consumer) + for(pt=_potentialProducers.begin();pt!=_potentialProducers.end();pt++) + ((*pt).second)->removeInPort(_consumer,true); +} + +bool CollectorSwOutPort::isDifferentTypeOf(const DataPort *other) const +{ + return (*(_potentialProducers.begin())).second->isDifferentTypeOf(other); +} + +void CollectorSwOutPort::getAllRepresented(std::set& represented) const +{ + map::const_iterator pt; + for(pt=_potentialProducers.begin();pt!=_potentialProducers.end();pt++) + ((*pt).second)->getAllRepresented(represented); +} + +bool CollectorSwOutPort::addInPort(InPort *inPort) throw(Exception) +{ + if(_currentProducer) + {//a specific link is beeing done + bool ret=_currentProducer->addInPort(inPort); + _currentProducer=0; + return ret; + } + else//global links asked + for(map::iterator iter=_potentialProducers.begin();iter!=_potentialProducers.end();iter++) + (*iter).second->addInPort(inPort); +} + +int CollectorSwOutPort::removeInPort(InPort *inPort, bool forward) throw(Exception) +{ + if(_currentProducer) + { + return _currentProducer->removeInPort(inPort,forward); + } + else + throw Exception("CollectorSwOutputPort::edRemoveInputPort : internal error on link removal."); + _currentProducer=0; +} + +/*! + * \note : 'master' specifies the instance of Switch of which 'this' collects all of these direct + * or indirect outports going to the same port 'port' (which is out of scope of 'master'). + */ +CollectorSwOutPort::CollectorSwOutPort(Switch *master, InPort *port):OutPort("",master,port->edGetType()), + DataPort("",master,port->edGetType()), + Port(master), + _consumer(port),_currentProducer(0) +{ + _name="Representant_of_"; _name+=master->getName(); _name+="_for_inport_"; _name+=master->getRootNode()->getInPortName(_consumer); +} + +CollectorSwOutPort::CollectorSwOutPort(const CollectorSwOutPort& other, Switch *master):OutPort("",master,other.edGetType()), + DataPort("",master,other.edGetType()), + Port(master), + _consumer(0),_currentProducer(0) +{ + _name=other._name; + Switch *othSw=(Switch *)other._node; + for(map::const_iterator iter=other._potentialProducers.begin();iter!=other._potentialProducers.end();iter++) + { + string name=othSw->getOutPortName((*iter).second); + _potentialProducers[(*iter).first]=master->getOutPort(name); + } +} + +void CollectorSwOutPort::addPotentialProducerForMaster(OutPort *port) +{ + int i=((Switch *)_node)->getRankOfNode(port->getNode()); + map::iterator pt=_potentialProducers.find(i); + if(pt==_potentialProducers.end()) + { + _potentialProducers[i]=port; + _currentProducer=port; + } + else + { + _currentProducer=(*pt).second; + if(_currentProducer!=port) + { + string what("CollectorSwOutPort::addPotentialProducerForMaster : In switch node "); what+=_node->getName(); + what+=" for input named \'"; what+=_consumer->getName(); what+="\' the output "; what+=_currentProducer->getName(); + what+=" already got out for case of label "; + what+=Switch::getRepresentationOfCase((*pt).first); + throw Exception(what); + } + } + _className=port->getNameOfTypeOfCurrentInstance(); +} + +bool CollectorSwOutPort::removePotentialProducerForMaster() +{ + int i; + map::iterator result; + for(result=_potentialProducers.begin();result!=_potentialProducers.end();result++) + if((*result).second==_currentProducer) + { + i=(*result).first; + break; + } + if(result==_potentialProducers.end()) + { + ostringstream stream; stream << "CollectorSwOutPort::removePotentialProducerForMaster : link from the branch whith id "; + stream << i << " not defined"; + throw Exception(stream.str()); + } + if((*result).second!=_currentProducer) + { + ostringstream stream; stream << "CollectorSwOutPort::removePotentialProducerForMaster : link from the branch whith id "; + stream << i << " defined but the output specified is not compatible"; + throw Exception(stream.str()); + } + _potentialProducers.erase(result); + return _potentialProducers.empty(); +} + +bool CollectorSwOutPort::checkManagementOfPort(OutPort *port) throw(Exception) +{ + for(map::iterator iter=_potentialProducers.begin();iter!=_potentialProducers.end();iter++) + if((*iter).second==port) + { + _currentProducer=port; + return _potentialProducers.size()==1; + } + throw Exception("CollectorSwOutPort::checkManagementOfPort : unexported port"); +} + +void CollectorSwOutPort::checkCompletenessOfCases() const throw(Exception) +{ + if(((Switch *)_node)->getNbOfCases()==_potentialProducers.size()) + return ;//Ok all of cases treats _consumer. + set lackingCases; + for(map< int ,Node * >::const_iterator iter=((Switch *)_node)->_mapOfNode.begin();iter!=((Switch *)_node)->_mapOfNode.end();iter++) + { + if(_potentialProducers.find((*iter).first)==_potentialProducers.end()) + lackingCases.insert((*iter).first); + } + ostringstream streamForExc; + streamForExc << "CollectorSwOutPort::checkCompletenessOfCases : For link to " << _consumer->getName() << " of node " << _consumer->getNode()->getName() + << " the cases of switch node named " << _node->getName() + << " do not define links for following cases ids :"; + for(set::iterator iter=lackingCases.begin();iter!=lackingCases.end();iter++) + streamForExc << Switch::getRepresentationOfCase(*iter) << " "; + throw Exception(streamForExc.str()); +} + +FakeNodeForSwitch::FakeNodeForSwitch(Switch *sw, bool normalFinish, bool internalError):ElementaryNode("thisIsAFakeNode"), + _sw(sw), + _normalFinish(normalFinish), + _internalError(internalError) +{ + _state=YACS::TOACTIVATE; + _father=_sw->getFather(); +} + +FakeNodeForSwitch::FakeNodeForSwitch(const FakeNodeForSwitch& other):ElementaryNode(other),_sw(0), + _normalFinish(false), + _internalError(true) +{ +} + +Node *FakeNodeForSwitch::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new FakeNodeForSwitch(*this); +} + +void FakeNodeForSwitch::exForwardFailed() +{ + _sw->exForwardFailed(); + FakeNodeForSwitch *normallyThis=_sw->_undispatchableNotificationNode; + _sw->_undispatchableNotificationNode=0; + delete normallyThis; +} + +void FakeNodeForSwitch::exForwardFinished() +{ + _sw->exForwardFinished(); + FakeNodeForSwitch *normallyThis=_sw->_undispatchableNotificationNode; + _sw->_undispatchableNotificationNode=0; + delete normallyThis; +} + +void FakeNodeForSwitch::execute() +{ + if(!_normalFinish) + throw Exception("");//only to trigger ABORT on Executor +} + +void FakeNodeForSwitch::aborted() +{ + if(_internalError) + _sw->_state!=YACS::INTERNALERR; + else + _sw->setState(YACS::ERROR); +} + +void FakeNodeForSwitch::finished() +{ + _sw->setState(YACS::DONE); +} + +Switch::Switch(const Switch& other, ComposedNode *father, bool editionOnly):StaticDefinedComposedNode(other,father),_condition(other._condition,this), + _undispatchableNotificationNode(0) +{ + for(map::const_iterator iter=other._mapOfNode.begin();iter!=other._mapOfNode.end();iter++) + _mapOfNode[(*iter).first]=(*iter).second->clone(this,editionOnly); + if(!editionOnly) + for(map::const_iterator iter2=other._outPortsCollector.begin();iter2!=other._outPortsCollector.end();iter2++) + { + CollectorSwOutPort *newCol=new CollectorSwOutPort(*((*iter2).second),this); + _alreadyExistingCollectors.push_back(newCol); + } +} + +Switch::Switch(const std::string& name):StaticDefinedComposedNode(name),_condition(SELECTOR_INPUTPORT_NAME,this,Runtime::_tc_int),_undispatchableNotificationNode(0) { } Switch::~Switch() { + for(map< int , Node * >::iterator iter=_mapOfNode.begin();iter!=_mapOfNode.end();iter++) + delete (*iter).second; + for(map::iterator iter2=_outPortsCollector.begin();iter2!=_outPortsCollector.end();iter2++) + delete (*iter2).second; + for(vector::iterator iter3=_alreadyExistingCollectors.begin();iter3!=_alreadyExistingCollectors.end();iter3++) + delete (*iter3); +} + +Node *Switch::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new Switch(*this,father,editionOnly); +} + +void Switch::exUpdateState() +{ + if(_state == YACS::DISABLED) + return; + if(_inGate.exIsReady()) + { + setState(YACS::TOACTIVATE); + if(_condition.isEmpty()) + _undispatchableNotificationNode=new FakeNodeForSwitch(this,false,true); + else + { + map< int , Node * >::iterator iter=_mapOfNode.find(_condition.getIntValue()); + if(iter==_mapOfNode.end()) + { + iter=_mapOfNode.find(ID_FOR_DEFAULT_NODE); + if(iter==_mapOfNode.end()) + { + bool normalFinish=getAllOutPortsLeavingCurrentScope().empty(); + delete _undispatchableNotificationNode; + _undispatchableNotificationNode=new FakeNodeForSwitch(this,normalFinish); + } + else + ((*iter).second)->exUpdateState(); + } + else + ((*iter).second)->exUpdateState(); + } + } +} + +void Switch::init(bool start) +{ + StaticDefinedComposedNode::init(start); + int i=0; + for(map< int , Node * >::iterator iter=_mapOfNode.begin();iter!=_mapOfNode.end();iter++, i++) + { + if(!(*iter).second) + { + ostringstream stream; + stream << "Switch::init : initialization failed due to unitialized branch of id " << (*iter).first; + throw Exception(stream.str()); + } + ((*iter).second)->init(start); + } +} + +void Switch::getReadyTasks(std::vector& tasks) +{ + /* + * To change the way ComposedNode state is handled, uncomment the following line + * see Bloc::getReadyTasks + */ + if(_state==YACS::TOACTIVATE) setState(YACS::ACTIVATED); + if(_state==YACS::TOACTIVATE || _state==YACS::ACTIVATED) + { + map< int , Node * >::iterator iter=_mapOfNode.find(_condition.getIntValue()); + if(iter!=_mapOfNode.end()) + ((*iter).second)->getReadyTasks(tasks); + else + { + iter=_mapOfNode.find(ID_FOR_DEFAULT_NODE); + if(iter!=_mapOfNode.end()) + (*iter).second->getReadyTasks(tasks);//Default Node is returned + else + if(_undispatchableNotificationNode) + _undispatchableNotificationNode->getReadyTasks(tasks); + else + throw Exception("Switch::getReadyTasks : internal error"); + } + } +} + +void Switch::selectRunnableTasks(std::vector& tasks) +{ +} + +set Switch::edGetDirectDescendants() const +{ + set ret; + for(map< int , Node * >::const_iterator iter=_mapOfNode.begin();iter!=_mapOfNode.end();iter++) + if((*iter).second) + ret.insert((*iter).second); + return ret; +} + +int Switch::getNumberOfInputPorts() const +{ + return StaticDefinedComposedNode::getNumberOfInputPorts()+1; +} + +void Switch::edRemoveChild(Node *node) throw(Exception) +{ + map< int , Node * >::iterator iter=_mapOfNode.begin(); + for(;iter!=_mapOfNode.end();iter++) + if(node==(*iter).second) + { + edReleaseCase((*iter).first); + return; + } + ostringstream what; what << "Switch::edRemoveChild : node with name " << node->getName() << " is not a direct child of Switch node " << _name; + throw Exception(what.str()); +} + +std::list Switch::getSetOfInputPort() const +{ + list ret=StaticDefinedComposedNode::getSetOfInputPort(); + ret.push_back((InputPort *)&_condition); + return ret; +} + +OutPort *Switch::getOutPort(const std::string& name) const throw(Exception) +{ + for(map::const_iterator iter=_outPortsCollector.begin();iter!=_outPortsCollector.end();iter++) + if(name==(*iter).second->getName()) + return (*iter).second; + for(vector::const_iterator iter2=_alreadyExistingCollectors.begin();iter2!=_alreadyExistingCollectors.end();iter2++) + if(name==(*iter2)->getName()) + return *iter2; + return StaticDefinedComposedNode::getOutPort(name); } -void Switch::edSetNumberOfCases(int numberOfCases) +InputPort *Switch::getInputPort(const std::string& name) const throw(Exception) { - _vectorOfNode.resize(numberOfCases); + if(name==SELECTOR_INPUTPORT_NAME) + return (InputPort *)&_condition; + return StaticDefinedComposedNode::getInputPort(name); } -void Switch::edSetNode(int caseId, Node *node) throw(Exception) +void Switch::checkConsistency(ComposedNode *pointOfView) const throw(Exception) { - if(caseId>=_vectorOfNode.size()) - throw Exception("Switch::edSetNode : caseId is too large compared to number of cases"); - _vectorOfNode[caseId]=node; + for(map::const_iterator iter=_outPortsCollector.begin();iter!=_outPortsCollector.end();iter++) + (*iter).second->checkCompletenessOfCases(); +} + +Node *Switch::getChildByShortName(const std::string& name) const throw(Exception) +{ + if(name==DEFAULT_NODE_NAME) + { + map< int , Node * >::const_iterator iter=_mapOfNode.find(ID_FOR_DEFAULT_NODE); + if(iter!=_mapOfNode.end()) + return (Node *)((*iter).second); + else + { + string what("Switch::getChildByShortName : no default node defined for switch of name "); what+=getName(); + throw Exception(what); + } + } + for(map< int , Node * >::const_iterator iter=_mapOfNode.begin();iter!=_mapOfNode.end();iter++) + { + if(name==((*iter).second)->getQualifiedName()) + return (*iter).second; + } + string what("node "); what+= name ; what+=" is not a child of node switch "; what += getName(); + throw Exception(what); +} + +Node *Switch::edSetDefaultNode(Node *node) +{ + return edSetNode(ID_FOR_DEFAULT_NODE,node); +} + +Node *Switch::edReleaseDefaultNode() throw(Exception) +{ + return edReleaseCase(ID_FOR_DEFAULT_NODE); +} + +Node *Switch::edReleaseCase(int caseId) throw(Exception) +{ + map< int , Node * >::iterator iter=_mapOfNode.find(caseId); + if(iter==_mapOfNode.end()) + { + string what("Switch::edReleaseCase : the case # "); what+=getRepresentationOfCase(caseId); what+=" is not set yet."; + throw Exception(what); + } + else + { + Node *ret=(*iter).second; + StaticDefinedComposedNode::edRemoveChild(ret); + _mapOfNode.erase(iter); + return ret; + } +} + +/*! + * \param caseId : the case ID chosen to place 'node' + * \param node : the node for the specified 'caseId' + * \return : If an old node with id equal to 'caseId' exists before, this old node is returned so that to be deallocated. + * 0 is returned if caseId is a new ID. + * \b WARNING : 'node' is held by 'this' after call, whereas returned node is no more held. + */ +Node *Switch::edSetNode(int caseId, Node *node) throw(Exception) +{ + if(!node) + throw Exception("Switch::edSetNode : null node cannot be set as a case in switch node"); + if(node->_father!=0) + throw Exception("Switch::edSetNode : node already held by another father"); + node->_father=this; + map< int , Node * >::iterator iter=_mapOfNode.find(caseId); + if(iter==_mapOfNode.end()) + { + _mapOfNode[caseId]=node; + return 0; + } + else + { + if(node!=(*iter).second) + { + Node *ret=(*iter).second; + (*iter).second=node; + return ret; + } + } +} + +YACS::Event Switch::updateStateOnFinishedEventFrom(Node *node) +{ + setState(YACS::DONE); + return YACS::FINISH;//notify to father node that 'this' has becomed finished. +} + +std::set Switch::getAllInPortsComingFromOutsideOfCurrentScope() const +{ + set ret=StaticDefinedComposedNode::getAllInPortsComingFromOutsideOfCurrentScope(); + set temp2=_condition.edSetOutPort(); + for(set::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++) + if(!isInMyDescendance((*iter3)->getNode())) + { + ret.insert((InPort *)&_condition); + break; + } + return ret; +} + +std::vector< std::pair > Switch::getSetOfLinksComingInCurrentScope() const +{ + vector< std::pair > ret=StaticDefinedComposedNode::getSetOfLinksComingInCurrentScope(); + set temp2=_condition.edSetOutPort(); + for(set::iterator iter3=temp2.begin();iter3!=temp2.end();iter3++) + if(!isInMyDescendance((*iter3)->getNode())) + ret.push_back(pair((InPort *)&_condition,*iter3)); + return ret; } void Switch::checkNoCyclePassingThrough(Node *node) throw(Exception) { throw Exception("Switch::checkNoCyclePassingThrough : uncorrect control flow link relative to switch"); } + +void Switch::checkLinkPossibility(OutPort *start, const std::set& pointsOfViewStart, + InPort *end, const std::set& pointsOfViewEnd) throw(Exception) +{ + throw Exception("Switch::checkLinkPossibility : A link between 2 different cases of a same Switch requested -> Impossible"); +} + +void Switch::buildDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) +{ + map::iterator result=_outPortsCollector.find(finalTarget); + CollectorSwOutPort *newCollector; + if(result!=_outPortsCollector.end()) + newCollector=(*result).second; + else + { + newCollector=new CollectorSwOutPort(this,finalTarget); + newCollector->edSetType((port.first)->edGetType()); + _outPortsCollector[finalTarget]=newCollector; + } + newCollector->addPotentialProducerForMaster(port.first); + port.second=newCollector; + port.first=newCollector; +} + +void Switch::getDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) throw(Exception) +{ + map::iterator iter=_outPortsCollector.find(finalTarget); + if(iter==_outPortsCollector.end()) + { + string what("Switch::getDelegateOf : not exported OuputPort with name "); what+=(port.first)->getName(); what+=" for target inport of name "; + what+=finalTarget->getName(); + throw Exception(what); + } + ((*iter).second)->checkManagementOfPort(port.first); + port.second=(*iter).second; + port.first=(*iter).second; +} + +void Switch::releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::set& pointsOfView) throw(Exception) +{ + set repr; + portDwn->getAllRepresented(repr); + if(repr.size()==1) + { + CollectorSwOutPort *portCasted=dynamic_cast(portUp); + if(portCasted->removePotentialProducerForMaster())//normally always true + { + delete portCasted; + _outPortsCollector.erase(finalTarget); + } + } +} + +int Switch::getNbOfCases() const +{ + return _mapOfNode.size(); +} + +int Switch::getRankOfNode(Node *node) const +{ + Node *directSon=isInMyDescendance(node); + for(map< int , Node * >::const_iterator iter=_mapOfNode.begin();iter!=_mapOfNode.end();iter++) + if((*iter).second==directSon) + return (*iter).first; + throw Exception("Switch::getRankOfNode : node not in switch"); +} + +string Switch::getRepresentationOfCase(int i) +{ + if(i!=ID_FOR_DEFAULT_NODE) + { + ostringstream stream; + stream << i; + return stream.str(); + } + else + return DEFAULT_NODE_NAME; +} + +//! Return the effective state of a node in the context of this switch (its father) +/*! + * \param node: the node which effective state is queried + * \return the effective node state + */ +YACS::StatesForNode Switch::getEffectiveState(Node* node) +{ + YACS::StatesForNode effectiveState=Node::getEffectiveState(); + if(effectiveState==YACS::INITED) + return YACS::INITED; + if(effectiveState==YACS::TOACTIVATE) + return YACS::INITED; + if(effectiveState==YACS::DISABLED) + return YACS::DISABLED; + map< int , Node * >::iterator iter=_mapOfNode.find(_condition.getIntValue()); + if(iter!=_mapOfNode.end() && (*iter).second==node) + return node->getState(); + else + return YACS::INITED; +} + +void Switch::writeDot(std::ostream &os) +{ + os << " subgraph cluster_" << getId() << " {\n" ; + for(map::const_iterator iter=_mapOfNode.begin();iter!=_mapOfNode.end();iter++) + { + Node* n=(*iter).second; + n->writeDot(os); + os << getId() << " -> " << n->getId() << ";\n"; + } + os << "}\n" ; + os << getId() << "[fillcolor=\"" ; + YACS::StatesForNode state=Node::getEffectiveState(); + os << getColorState(state); + os << "\" label=\"" << "Switch:" ; + os << getQualifiedName() <<"\"];\n"; +} + +std::string Switch::getMyQualifiedName(const Node *directSon) const +{ + string id=getCaseId(directSon); + id+=directSon->getName(); + return id; +} + +std::string Switch::getCaseId(const Node *node) const throw(Exception) +{ + const char sep='_'; + map::const_iterator iter; + for (iter = _mapOfNode.begin(); iter != _mapOfNode.end(); iter++) + if (iter->second == node) + { + stringstream a; + if (iter->first == Switch::ID_FOR_DEFAULT_NODE) + a << DEFAULT_NODE_NAME << sep; + else if (iter->first <0) + a << "m" << -iter->first << sep; + else a << "p" << iter->first << sep; + return a.str(); + } + string what("node "); what+= node->getName() ; what+=" is not a child of node "; what += getName(); + throw Exception(what); +} + +void Switch::accept(Visitor *visitor) +{ + visitor->visitSwitch(this); +} diff --git a/src/engine/Switch.hxx b/src/engine/Switch.hxx index 34687bb2e..c1fad1c1a 100644 --- a/src/engine/Switch.hxx +++ b/src/engine/Switch.hxx @@ -1,25 +1,119 @@ #ifndef __SWITCH_HXX__ #define __SWITCH_HXX__ -#include "ComposedNode.hxx" +#include "StaticDefinedComposedNode.hxx" +#include "ElementaryNode.hxx" +#include "AnyInputPort.hxx" +#include "OutPort.hxx" -#include +#include namespace YACS { namespace ENGINE { - class Switch : public ComposedNode + class Switch; + + class CollectorSwOutPort : public OutPort + { + friend class Switch; + private: + int edGetNumberOfOutLinks() const; + std::set edSetInPort() const; + bool isAlreadyLinkedWith(InPort *with) const; + std::string getNameOfTypeOfCurrentInstance() const; + void edRemoveAllLinksLinkedWithMe() throw(Exception); + bool isDifferentTypeOf(const DataPort *other) const; + void getAllRepresented(std::set& represented) const; + bool addInPort(InPort *inPort) throw(Exception); + int removeInPort(InPort *inPort, bool forward) throw(Exception); + private://Specific part + bool removePotentialProducerForMaster(); + void checkCompletenessOfCases() const throw(Exception); + CollectorSwOutPort(Switch *master, InPort *port); + CollectorSwOutPort(const CollectorSwOutPort& other, Switch *master); + void addPotentialProducerForMaster(OutPort *port); + bool checkManagementOfPort(OutPort *port) throw(Exception); + private: + InPort *_consumer; + std::string _className; + OutPort *_currentProducer; + std::map _potentialProducers; + }; + + class FakeNodeForSwitch : public ElementaryNode { + friend class Switch; + private: + Switch *_sw; + bool _normalFinish; + bool _internalError; + private: + FakeNodeForSwitch(Switch *sw, bool normalFinish, bool internalError=false); + FakeNodeForSwitch(const FakeNodeForSwitch& other); + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + void exForwardFailed(); + void exForwardFinished(); + void execute(); + void aborted(); + void finished(); + }; + + class Switch : public StaticDefinedComposedNode + { + friend class FakeNodeForSwitch; + friend class CollectorSwOutPort; + public: + static const char DEFAULT_NODE_NAME[]; + static const char SELECTOR_INPUTPORT_NAME[]; + static const int ID_FOR_DEFAULT_NODE; protected: - std::vector _vectorOfNode;//Nodes ownered + AnyInputPort _condition; + std::map< int , Node * > _mapOfNode;//Nodes ownered + FakeNodeForSwitch *_undispatchableNotificationNode; + std::map _outPortsCollector; + mutable std::vector _alreadyExistingCollectors; public: + Switch(const Switch& other, ComposedNode *father, bool editionOnly); Switch(const std::string& name); ~Switch(); - void edSetNumberOfCases(int numberOfCases); - void edSetNode(int caseId, Node *node) throw(Exception); + void exUpdateState(); + void init(bool start=true); + Node *edSetDefaultNode(Node *node); + Node *edReleaseDefaultNode() throw(Exception); + Node *edReleaseCase(int caseId) throw(Exception); + Node *edSetNode(int caseId, Node *node) throw(Exception); + void getReadyTasks(std::vector& tasks); + void selectRunnableTasks(std::vector& tasks); + std::set edGetDirectDescendants() const; + InputPort *edGetConditionPort() { return &_condition; } + void writeDot(std::ostream &os); + int getNumberOfInputPorts() const; + void edRemoveChild(Node *node) throw(Exception); + std::list getSetOfInputPort() const; + YACS::StatesForNode getEffectiveState(Node* node); + OutPort *getOutPort(const std::string& name) const throw(Exception); + InputPort* getInputPort(const std::string& name) const throw(Exception); + void checkConsistency(ComposedNode *pointOfView=0) const throw(Exception); + Node *getChildByShortName(const std::string& name) const throw(Exception); + std::string getMyQualifiedName(const Node *directSon) const; + std::string getCaseId(const Node *node) const throw(Exception); + virtual void accept(Visitor *visitor); + int getRankOfNode(Node *node) const; protected: + YACS::Event updateStateOnFinishedEventFrom(Node *node); + Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; + std::set getAllInPortsComingFromOutsideOfCurrentScope() const; + std::vector< std::pair > getSetOfLinksComingInCurrentScope() const; + void checkLinkPossibility(OutPort *start, const std::set& pointsOfViewStart, + InPort *end, const std::set& pointsOfViewEnd) throw(Exception); + void buildDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView); + void getDelegateOf(std::pair& port, InPort *finalTarget, const std::set& pointsOfView) throw(Exception); + void releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::set& pointsOfView) throw(Exception); void checkNoCyclePassingThrough(Node *node) throw(Exception); + private: + int getNbOfCases() const; + static std::string getRepresentationOfCase(int i); }; } } diff --git a/src/engine/Task.hxx b/src/engine/Task.hxx index 2f20fe7b0..239d3b0aa 100644 --- a/src/engine/Task.hxx +++ b/src/engine/Task.hxx @@ -1,17 +1,30 @@ #ifndef __TASK_HXX__ #define __TASK_HXX__ +#include "define.hxx" + namespace YACS { namespace ENGINE { + class ComponentInstance; + class Task { public: virtual void begin() = 0; virtual bool isReady() = 0; virtual void execute() = 0; + virtual void load() = 0; + virtual void loaded() = 0; + virtual void initService() = 0; + virtual void connectService() = 0; + virtual void disconnectService() = 0; + virtual bool isDeployable() const = 0; + virtual ComponentInstance *getComponent() = 0; + virtual YACS::StatesForNode getState() const = 0; virtual void finished() = 0; + virtual void aborted() = 0; }; } } diff --git a/src/engine/Test/ComponentInstanceTest.cxx b/src/engine/Test/ComponentInstanceTest.cxx new file mode 100644 index 000000000..a483244b2 --- /dev/null +++ b/src/engine/Test/ComponentInstanceTest.cxx @@ -0,0 +1,97 @@ +#include "ComponentInstanceTest.hxx" +#include "ToyNode.hxx" + +using namespace std; +using namespace YACS::ENGINE; + +ComponentInstanceTest1::ComponentInstanceTest1(const ComponentInstanceTest1& other):ComponentInstance(other),_loaded(false) +{ +} + +ComponentInstanceTest1::ComponentInstanceTest1(const std::string& name):ComponentInstance(name),_loaded(false) +{ +} + +void ComponentInstanceTest1::load() +{ + _loaded=true; +} + +void ComponentInstanceTest1::unload() +{ + _loaded=false; +} + +bool ComponentInstanceTest1::isLoaded() +{ + return _loaded; +} + +std::string ComponentInstanceTest1::getKind() const +{ + return ToyNode1S::KIND; +} + +ServiceNode* ComponentInstanceTest1::createNode(const std::string& name) +{ + ToyNode1S* node=new ToyNode1S(name); + node->setComponent(this); + return node; +} + +ComponentInstance *ComponentInstanceTest1::clone() const +{ + if(isAttachedOnCloning()) + { + incrRef(); + return (ComponentInstance *) this; + } + else + return new ComponentInstanceTest1(*this); +} + +ComponentInstanceTest2::ComponentInstanceTest2(const ComponentInstanceTest2& other):ComponentInstance(other),_loaded(false) +{ +} + +ComponentInstanceTest2::ComponentInstanceTest2(const std::string& name):ComponentInstance(name),_loaded(false) +{ +} + +void ComponentInstanceTest2::load() +{ + _loaded=true; +} + +void ComponentInstanceTest2::unload() +{ + _loaded=false; +} + +bool ComponentInstanceTest2::isLoaded() +{ + return _loaded; +} + +std::string ComponentInstanceTest2::getKind() const +{ + return ToyNode2S::KIND; +} + +ServiceNode* ComponentInstanceTest2::createNode(const std::string& name) +{ + ToyNode2S* node=new ToyNode2S(name); + node->setComponent(this); + return node; +} + +ComponentInstance *ComponentInstanceTest2::clone() const +{ + if(isAttachedOnCloning()) + { + incrRef(); + return (ComponentInstance *) this; + } + else + return new ComponentInstanceTest2(*this); +} diff --git a/src/engine/Test/ComponentInstanceTest.hxx b/src/engine/Test/ComponentInstanceTest.hxx new file mode 100644 index 000000000..88b4e8874 --- /dev/null +++ b/src/engine/Test/ComponentInstanceTest.hxx @@ -0,0 +1,42 @@ +#ifndef __COMPONENTINTANCETEST_HXX__ +#define __COMPONENTINTANCETEST_HXX__ + +#include "ComponentInstance.hxx" + +namespace YACS +{ + namespace ENGINE + { + class ComponentInstanceTest1 : public ComponentInstance + { + public: + ComponentInstanceTest1(const ComponentInstanceTest1& other); + ComponentInstanceTest1(const std::string& name); + void load(); + void unload(); + bool isLoaded(); + std::string getKind() const; + ServiceNode* createNode(const std::string& name); + ComponentInstance *clone() const; + protected: + bool _loaded; + }; + + class ComponentInstanceTest2 : public ComponentInstance + { + public: + ComponentInstanceTest2(const ComponentInstanceTest2& other); + ComponentInstanceTest2(const std::string& name); + void load(); + void unload(); + bool isLoaded(); + std::string getKind() const; + ServiceNode* createNode(const std::string& name); + ComponentInstance *clone() const; + protected: + bool _loaded; + }; + } +} + +#endif diff --git a/src/engine/Test/ContainerTest.cxx b/src/engine/Test/ContainerTest.cxx new file mode 100644 index 000000000..234ff1ddc --- /dev/null +++ b/src/engine/Test/ContainerTest.cxx @@ -0,0 +1,98 @@ +#include "ContainerTest.hxx" +#include "ComponentInstance.hxx" +#include "ToyNode.hxx" +#include + +using namespace std; +using namespace YACS::ENGINE; + +unsigned ContainerTest::_counter = 0; + +const char ContainerTest::SUPPORTED_COMP_KIND[] = "TESTKIND1"; + +unsigned ContainerTest2::_counter = 0; + +const char ContainerTest2::SUPPORTED_COMP_KIND[] = "TESTKIND2"; + +ContainerTest::ContainerTest():_alreadyStarted(false),_myCounter(_counter++) +{ +} + +std::string ContainerTest::getPlacementInfo() const +{ + ostringstream stream; + stream << "Cont#_" << _myCounter; + return stream.str(); +} + +bool ContainerTest::isAlreadyStarted() const +{ + return _alreadyStarted; +} + +void ContainerTest::start() throw(Exception) +{ + if(_alreadyStarted) + throw Exception("ContainerTest already started !!!!"); + _alreadyStarted=true; +} + +Container *ContainerTest::clone() const +{ + if(_isAttachedOnCloning) + { + incrRef(); + return (Container *) this; + } + else + return new ContainerTest; +} + +void ContainerTest::checkCapabilityToDealWith(const ComponentInstance *inst) const throw(Exception) +{ + if(inst->getKind()!=SUPPORTED_COMP_KIND) + throw Exception("ContainerTest not compatible with this type of instance."); +} + +void ContainerTest::initAllContainers() +{ + _counter=0; +} + +ContainerTest2::ContainerTest2():_alreadyStarted(false),_myCounter(_counter++) +{ +} + +bool ContainerTest2::isAlreadyStarted() const +{ + return _alreadyStarted; +} + +void ContainerTest2::start() throw(Exception) +{ + if(_alreadyStarted) + throw Exception("ContainerTest already started !!!!"); + _alreadyStarted=true; +} + +Container *ContainerTest2::clone() const +{ + if(_isAttachedOnCloning) + { + incrRef(); + return (Container *) this; + } + else + return new ContainerTest2; +} + +void ContainerTest2::initAllContainers() +{ + _counter=0; +} + +void ContainerTest2::checkCapabilityToDealWith(const ComponentInstance *inst) const throw(Exception) +{ + if(inst->getKind()!=SUPPORTED_COMP_KIND) + throw Exception("ContainerTest not compatible with this type of instance."); +} diff --git a/src/engine/Test/ContainerTest.hxx b/src/engine/Test/ContainerTest.hxx new file mode 100644 index 000000000..ab0faa3c8 --- /dev/null +++ b/src/engine/Test/ContainerTest.hxx @@ -0,0 +1,51 @@ +#ifndef __CONTAINERTEST_HXX__ +#define __CONTAINERTEST_HXX__ + +#include "Container.hxx" + +namespace YACS +{ + namespace ENGINE + { + class ContainerTest : public Container + { + public: + ContainerTest(); + std::string getPlacementInfo() const; + // implementation of compulsary methods + bool isAlreadyStarted() const; + void start() throw(Exception); + Container *clone() const; + std::string getPlacementId() const { return ""; } + static void initAllContainers(); + protected: + void checkCapabilityToDealWith(const ComponentInstance *inst) const throw(Exception); + protected: + bool _alreadyStarted; + unsigned _myCounter; + static unsigned _counter; + static const char SUPPORTED_COMP_KIND[]; + }; + + class ContainerTest2 : public Container + { + public: + ContainerTest2(); + // implementation of compulsary methods + bool isAlreadyStarted() const; + void start() throw(Exception); + Container *clone() const; + std::string getPlacementId() const { return ""; } + static void initAllContainers(); + protected: + void checkCapabilityToDealWith(const ComponentInstance *inst) const throw(Exception); + protected: + bool _alreadyStarted; + unsigned _myCounter; + static unsigned _counter; + static const char SUPPORTED_COMP_KIND[]; + }; + } +} + +#endif diff --git a/src/engine/Test/IntegrationTestEngine.cxx b/src/engine/Test/IntegrationTestEngine.cxx new file mode 100644 index 000000000..c3b22856e --- /dev/null +++ b/src/engine/Test/IntegrationTestEngine.cxx @@ -0,0 +1,13 @@ + + +#define UNIT_TEST_HEADER " --- TEST src/engine EngineIntegrationTest" + +#include "engineIntegrationTest.hxx" + +using namespace YACS::ENGINE; +using namespace YACS; +using namespace std; + +CPPUNIT_TEST_SUITE_REGISTRATION( EngineIntegrationTest ); + +#include "BasicMainTest.hxx" diff --git a/src/engine/Test/Makefile.am b/src/engine/Test/Makefile.am index 7877fbddd..3e59783d2 100644 --- a/src/engine/Test/Makefile.am +++ b/src/engine/Test/Makefile.am @@ -1,26 +1,56 @@ include $(top_srcdir)/adm/unix/make_begin.am -check_PROGRAMS = TestEngine +check_PROGRAMS = TestEngine IntegrationTestEngine -TestEngine_SOURCES = \ - TestEngine.cxx \ +TestEngine_SOURCES = \ + TestEngine.cxx \ + RuntimeForEngineTest.cxx \ engineTest.cxx TestEngine_LDADD = \ - ../libYACSEngine.la \ + ../libYACSEngine.la \ ../../bases/libYACSBases.la TestEngine_LDFLAGS = $(CPPUNIT_LIBS) -pthread -ldl TestEngine_CXXFLAGS = \ - $(CPPUNIT_INCLUDES) \ - -I$(srcdir)/.. \ - -I$(srcdir)/../../bases \ + $(CPPUNIT_INCLUDES) \ + -I$(srcdir)/.. \ + -I$(srcdir)/../../bases \ -I$(srcdir)/../../bases/Test +lib_LTLIBRARIES = libPluginOptEvTest1.la -TESTS = TestEngine +libPluginOptEvTest1_la_SOURCES = PluginOptEvTest1.cxx + +libPluginOptEvTest1_la_CXXFLAGS = $(THREAD_DEF) \ + -I$(srcdir)/.. \ + -I$(srcdir)/../../bases + +IntegrationTestEngine_SOURCES = \ + ToyNode.cxx \ + ContainerTest.cxx \ + ComponentInstanceTest.cxx \ + IntegrationTestEngine.cxx \ + engineIntegrationTest.cxx \ + RuntimeForEngineIntegrationTest.cxx + +IntegrationTestEngine_LDADD = \ + ../libYACSEngine.la \ + ../../bases/libYACSBases.la + +IntegrationTestEngine_LDFLAGS = $(CPPUNIT_LIBS) -pthread -ldl + +IntegrationTestEngine_CXXFLAGS = \ + $(CPPUNIT_INCLUDES) \ + $(THREAD_DEF) \ + -I$(srcdir)/.. \ + -I$(srcdir)/../../bases \ + -I$(srcdir)/../../bases/Test + + +TESTS = TestEngine IntegrationTestEngine include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/engine/Test/PluginOptEvTest1.cxx b/src/engine/Test/PluginOptEvTest1.cxx new file mode 100644 index 000000000..70094da3b --- /dev/null +++ b/src/engine/Test/PluginOptEvTest1.cxx @@ -0,0 +1,84 @@ +#include "PluginOptEvTest1.hxx" +#include "TypeCode.hxx" +#include "Pool.hxx" + +#include + +using namespace YACS::ENGINE; + +PluginOptEvTest1::PluginOptEvTest1(Pool *pool):OptimizerAlgSync(pool),_tcIn(0),_tcOut(0),_idTest(0) +{ + _tcIn=new TypeCode(Double); + _tcOut=new TypeCode(Int); +} + +PluginOptEvTest1::~PluginOptEvTest1() +{ + _tcIn->decrRef(); + _tcOut->decrRef(); +} + +TypeCode *PluginOptEvTest1::getTCForIn() const +{ + return _tcIn; +} + +TypeCode *PluginOptEvTest1::getTCForOut() const +{ + return _tcOut; +} + +void PluginOptEvTest1::parseFileToInit(const std::string& fileName) +{ +} + +void PluginOptEvTest1::start() +{ + _idTest=0; + Any *val=AtomAny::New(1.2); + _pool->pushInSample(4,val); + val=AtomAny::New(3.4); + _pool->pushInSample(9,val); +} + +void PluginOptEvTest1::takeDecision() +{ + if(_idTest==1) + { + Any *val=AtomAny::New(5.6); + _pool->pushInSample(16,val); + val=AtomAny::New(7.8); + _pool->pushInSample(25,val); + val=AtomAny::New(9. ); + _pool->pushInSample(36,val); + val=AtomAny::New(12.3); + _pool->pushInSample(49,val); + } + else if(_idTest==4) + { + Any *val=AtomAny::New(45.6); + _pool->pushInSample(64,val); + val=AtomAny::New(78.9); + _pool->pushInSample(81,val); + } + else + { + Any *tmp= _pool->getCurrentInSample(); + if(fabs(tmp->getDoubleValue()-45.6)<1.e-12) + _pool->destroyAll(); + } + _idTest++; +} + +void PluginOptEvTest1::initialize(const Any *input) throw (Exception) +{ +} + +void PluginOptEvTest1::finish() +{ +} + +OptimizerAlgBase *PluginOptEvTest1Factory(Pool *pool) +{ + return new PluginOptEvTest1(pool); +} diff --git a/src/engine/Test/PluginOptEvTest1.hxx b/src/engine/Test/PluginOptEvTest1.hxx new file mode 100644 index 000000000..94aa268cb --- /dev/null +++ b/src/engine/Test/PluginOptEvTest1.hxx @@ -0,0 +1,35 @@ +#ifndef __PUGINOPTEVTEST1_HXX__ +#define __PUGINOPTEVTEST1_HXX__ + +#include "OptimizerAlg.hxx" + +extern "C" +{ + YACS::ENGINE::OptimizerAlgBase *PluginOptEvTest1Factory(YACS::ENGINE::Pool *pool); +} + +namespace YACS +{ + namespace ENGINE + { + class PluginOptEvTest1 : public OptimizerAlgSync + { + private: + int _idTest; + TypeCode *_tcIn; + TypeCode *_tcOut; + public: + PluginOptEvTest1(Pool *pool); + virtual ~PluginOptEvTest1(); + TypeCode *getTCForIn() const; + TypeCode *getTCForOut() const; + void parseFileToInit(const std::string& fileName); + void start(); + void takeDecision(); + void initialize(const Any *input) throw(Exception); + void finish(); + }; + } +} + +#endif diff --git a/src/engine/Test/RuntimeForEngineIntegrationTest.cxx b/src/engine/Test/RuntimeForEngineIntegrationTest.cxx new file mode 100644 index 000000000..5f08db5bd --- /dev/null +++ b/src/engine/Test/RuntimeForEngineIntegrationTest.cxx @@ -0,0 +1,72 @@ +#include "RuntimeForEngineIntegrationTest.hxx" +#include "ComponentInstanceTest.hxx" +#include "ToyNode.hxx" +#include + +using namespace std; +using namespace YACS::ENGINE; + +void RuntimeForEngineIntegrationTest::setRuntime() +{ + if (! Runtime::_singleton) + Runtime::_singleton = new RuntimeForEngineIntegrationTest; +} + +ElementaryNode* RuntimeForEngineIntegrationTest::createNode(const string& implementation, const string& name) throw(Exception) +{ + if (implementation == ToyNode::MY_IMPL_NAME) + return new ToyNode(name); + else if(implementation == LimitNode::MY_IMPL_NAME) + return new LimitNode(name); + string what="RuntimeForEngineIntegrationTest does not handle this implementation: " + implementation; + throw Exception(what); +} + +InputPort* RuntimeForEngineIntegrationTest::createInputPort(const string& name, const string& impl, Node * node, TypeCode * type) +{ + if(impl == ToyNode::MY_IMPL_NAME) + { + if(type->kind()!=Double) + throw Exception("Invalid type"); + return new InputToyPort(name, node); + } + else if(impl == LimitNode::MY_IMPL_NAME) + throw Exception("InputPort creation not allowed for LimitNode"); + ostringstream msg; + msg << "Cannot create " << impl << " OutputPort" ; + throw Exception(msg.str()); +} + +OutputPort* RuntimeForEngineIntegrationTest::createOutputPort(const string& name, const string& impl, Node * node, TypeCode * type) +{ + if(impl == ToyNode::MY_IMPL_NAME) + { + if(type->kind()!=Double && type->kind()!=Int) + throw Exception("Invalid type"); + return new OutputToyPort(name, node, type); + } + else if(impl == LimitNode::MY_IMPL_NAME) + throw Exception("OutputPort creation not allowed for LimitNode"); + stringstream msg; + msg << "Cannot create " << impl << " OutputPort" ; + throw Exception(msg.str()); +} + +InputPort* RuntimeForEngineIntegrationTest::adapt(InputPort* source, const string& impl,TypeCode * type) throw (ConversionException) +{ + return new ProxyPort(source); +} + +ComponentInstance* RuntimeForEngineIntegrationTest::createComponentInstance(const std::string& name, const std::string& kind) +{ + if(kind==ToyNode1S::KIND) + return new ComponentInstanceTest1(name); + else if(kind==ToyNode2S::KIND) + return new ComponentInstanceTest2(name); + else + { + string msg("RuntimeForEngineIntegrationTest::createComponentInstance : Unable to crate component with kind \""); + msg+=kind; msg+="\""; + throw Exception(msg); + } +} diff --git a/src/engine/Test/RuntimeForEngineIntegrationTest.hxx b/src/engine/Test/RuntimeForEngineIntegrationTest.hxx new file mode 100644 index 000000000..ebf70d135 --- /dev/null +++ b/src/engine/Test/RuntimeForEngineIntegrationTest.hxx @@ -0,0 +1,23 @@ +#ifndef __RUNTIMEFORENGINEINTEGRATIONTEST_HXX__ +#define __RUNTIMEFORENGINEINTEGRATIONTEST_HXX__ + +#include "Runtime.hxx" + +namespace YACS +{ + namespace ENGINE + { + class RuntimeForEngineIntegrationTest : public Runtime + { + public: + static void setRuntime(); + ElementaryNode* createNode(const std::string& implementation, const std::string& name) throw(Exception); + InputPort* createInputPort(const std::string& name, const std::string& impl, Node * node, TypeCode * type); + OutputPort* createOutputPort(const std::string& name, const std::string& impl, Node * node, TypeCode * type); + InputPort* adapt(InputPort* source, const std::string& impl,TypeCode * type) throw (ConversionException); + ComponentInstance* createComponentInstance(const std::string& name, const std::string& kind=""); + }; + } +} + +#endif diff --git a/src/engine/Test/RuntimeForEngineTest.cxx b/src/engine/Test/RuntimeForEngineTest.cxx new file mode 100644 index 000000000..9f9fd3daf --- /dev/null +++ b/src/engine/Test/RuntimeForEngineTest.cxx @@ -0,0 +1,108 @@ +#include "RuntimeForEngineTest.hxx" +#include +#include + +using namespace YACS::ENGINE; +using namespace std; + +TestElemNode::TestElemNode(const TestElemNode& other, ComposedNode *father):ElementaryNode(other,father) +{ +} + +Node *TestElemNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new TestElemNode(*this,father); +} + +TestElemInputPort::TestElemInputPort(const std::string& name, Node *node, TypeCode* type):InputPort(name,node,type),DataPort(name,node,type),Port(node) +{ +} + +TestElemInputPort::TestElemInputPort(const TestElemInputPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder) +{ +} + +void TestElemInputPort::put(const void *data) throw(ConversionException) +{ + cerr << _name << endl; + stringstream msg; + msg << "Not implemented (" << __FILE__ << ":" << __LINE__ << ")"; + throw Exception(msg.str()); +} + +InputPort *TestElemInputPort::clone(Node *newHelder) const +{ + return new TestElemInputPort(*this,newHelder); +} + +void *TestElemInputPort::get() const throw(Exception) +{ + stringstream msg; + msg << "Not implemented (" << __FILE__ << ":" << __LINE__ << ")"; + throw Exception(msg.str()); +} + +void TestElemInputPort::exRestoreInit() +{ + if(!_initValue) + return; + if(_value) + _value->decrRef(); + _value=_initValue; + _value->incrRef(); +} + +void TestElemInputPort::exSaveInit() +{ + if(_initValue) + _initValue->decrRef(); + _initValue=_value; + _initValue->incrRef(); +} + +TestElemOutputPort::TestElemOutputPort(const std::string& name, Node *node, TypeCode* type):OutputPort(name,node,type),DataPort(name,node,type),Port(node) +{ +} + +TestElemOutputPort::TestElemOutputPort(const TestElemOutputPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder) +{ +} + +OutputPort *TestElemOutputPort::clone(Node *newHelder) const +{ + return new TestElemOutputPort(*this,newHelder); +} + +void TestElemOutputPort::put(const void *data) throw(ConversionException) +{ + cerr << _name << endl; + stringstream msg; + msg << "Not implemented (" << __FILE__ << ":" << __LINE__ << ")"; + throw Exception(msg.str()); +} + +void RuntimeForEngineTest::setRuntime() +{ + if (! Runtime::_singleton) + Runtime::_singleton = new RuntimeForEngineTest; +} + +ElementaryNode* RuntimeForEngineTest::createNode(const string& implementation, const string& name) throw(Exception) +{ + return new TestElemNode(name); +} + +InputPort* RuntimeForEngineTest::createInputPort(const string& name, const string& impl, Node * node, TypeCode * type) +{ + return new TestElemInputPort(name, node, type); +} + +OutputPort* RuntimeForEngineTest::createOutputPort(const string& name, const string& impl, Node * node, TypeCode * type) +{ + return new TestElemOutputPort(name, node, type); +} + +InputPort* RuntimeForEngineTest::adapt(InputPort* source, const string& impl,TypeCode * type) throw (ConversionException) +{ + return new ProxyPort(source); +} diff --git a/src/engine/Test/RuntimeForEngineTest.hxx b/src/engine/Test/RuntimeForEngineTest.hxx new file mode 100644 index 000000000..48ed7a1c8 --- /dev/null +++ b/src/engine/Test/RuntimeForEngineTest.hxx @@ -0,0 +1,58 @@ +#ifndef __RUNTIMEFORENGINETEST_HXX__ +#define __RUNTIMEFORENGINETEST_HXX__ + +#include "Runtime.hxx" +#include "InputPort.hxx" +#include "OutputPort.hxx" +#include "ElementaryNode.hxx" + +namespace YACS +{ + namespace ENGINE + { + class TestElemNode: public ElementaryNode + { + public: + TestElemNode(const std::string& s): ElementaryNode(s) { } + TestElemNode(const TestElemNode& other, ComposedNode *father); + void execute() { } + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + }; + + class TestElemInputPort : public InputPort + { + public: + TestElemInputPort(const std::string& name, Node *node, TypeCode* type); + TestElemInputPort(const TestElemInputPort& other, Node *newHelder); + void put(const void *data) throw(ConversionException); + InputPort *clone(Node *newHelder) const; + void *get() const throw(Exception); + void exRestoreInit(); + void exSaveInit(); + protected: + Any *_value; + }; + + class TestElemOutputPort : public OutputPort + { + public: + TestElemOutputPort(const std::string& name, Node *node, TypeCode* type); + TestElemOutputPort(const TestElemOutputPort& other, Node *newHelder); + void put(const void *data) throw(ConversionException); + OutputPort *clone(Node *newHelder) const; + }; + + class RuntimeForEngineTest : public Runtime + { + public: + static void setRuntime(); + ElementaryNode* createNode(const std::string& implementation, const std::string& name) throw(Exception); + InputPort* createInputPort(const std::string& name, const std::string& impl, Node * node, TypeCode * type); + OutputPort* createOutputPort(const std::string& name, const std::string& impl, Node * node, TypeCode * type); + InputPort* adapt(InputPort* source, const std::string& impl, TypeCode * type) throw (ConversionException); + }; + } +} + +#endif diff --git a/src/engine/Test/TestEngine.cxx b/src/engine/Test/TestEngine.cxx index 447f014c5..6a9b282a1 100644 --- a/src/engine/Test/TestEngine.cxx +++ b/src/engine/Test/TestEngine.cxx @@ -1,4 +1,6 @@ +#define UNIT_TEST_HEADER " --- TEST src/engine EngineTest" + #include "engineTest.hxx" using namespace YACS; diff --git a/src/engine/Test/ToyNode.cxx b/src/engine/Test/ToyNode.cxx new file mode 100644 index 000000000..c45350fa0 --- /dev/null +++ b/src/engine/Test/ToyNode.cxx @@ -0,0 +1,719 @@ +#include "ToyNode.hxx" +#include + +using namespace YACS::ENGINE; +using namespace std; + +char ToyNode::MY_IMPL_NAME[]="TOY"; + +const char ToyNode1S::KIND[]="TESTKIND1"; + +const char ToyNode2S::KIND[]="TESTKIND2"; + +char LimitNode::MY_IMPL_NAME[]="LIMIT"; + +char ToyNode::NAME_FOR_NB[]="NbOfEntries"; + +char SeqToyNode::NAME_NBOFELTS_INSEQ_INPRT[]="NbOfEltsInSeq"; + +char SeqToyNode::NAME_SEQ_OUTPRT[]="MySeq"; + +char Seq2ToyNode::NAME_SEQ_INPRT1[]="SeqIn1"; + +char Seq2ToyNode::NAME_SEQ_INPRT2[]="SeqIn2"; + +char Seq2ToyNode::NAME_SEQ_OUTPRT[]="SeqOut"; + +char Seq3ToyNode::NAME_SEQ_INPRT1[]="SeqIn1"; + +char Seq3ToyNode::NAME_SEQ_INPRT2[]="SeqIn2"; + +char Seq3ToyNode::NAME_SEQ_OUTPRT[]="SeqOut"; + +char LimitNode::NAME_FOR_SWPORT[]="SwitchPort"; + +char LimitNode::NAME_FOR_SWPORT2[]="SwitchPort2"; + +InputToyPort::InputToyPort(const InputToyPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder), + _data(0),_initData(0) +{ + if(other._data) + _data=other._data->clone(); + if(other._initData) + _initData=other._initData->clone(); +} + +InputToyPort::InputToyPort(const string& name, Node *node):InputPort(name, node, Runtime::_tc_double),DataPort(name, node, Runtime::_tc_double),Port(node),_data(0),_initData(0) +{ +} + +void InputToyPort::put(const void *data) throw(ConversionException) +{ + put((Any *)data); +} + +bool InputToyPort::edIsManuallyInitialized() const +{ + return _initData!=0; +} + +void *InputToyPort::get() const throw(Exception) +{ + return (void *)_data; +} + +void InputToyPort::edRemoveManInit() +{ + if(_initData) + _initData->decrRef(); + _initData=0; + InputPort::edRemoveManInit(); +} + +InputPort *InputToyPort::clone(Node *newHelder) const +{ + return new InputToyPort(*this,newHelder); +} + +void InputToyPort::put(Any *data) +{ + if(_data) + _data->decrRef(); + _data=data; + _data->incrRef(); +} + +void InputToyPort::exSaveInit() + { + if(_initData) _initData->decrRef(); + _initData=_data; + _initData->incrRef(); + } + +void InputToyPort::exRestoreInit() + { + if(!_initData)return; + if(_data) _data->decrRef(); + _data=_initData; + _data->incrRef(); + } + +InputToyPort::~InputToyPort() +{ + if(_data) + _data->decrRef(); + if(_initData) + _initData->decrRef(); +} + +OutputToyPort::OutputToyPort(const string& name, Node *node, TypeCode *type):OutputPort(name, node, type),DataPort(name, node, type),Port(node),_data(0) +{ +} + +OutputToyPort::OutputToyPort(const OutputToyPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder),_data(0) +{ + if(other._data) + _data=other._data->clone(); +} + +void OutputToyPort::put(const void *data) throw(ConversionException) +{ + put((Any *)data); + OutputPort::put(data); +} + +OutputPort *OutputToyPort::clone(Node *newHelder) const +{ + return new OutputToyPort(*this,newHelder); +} + +void OutputToyPort::put(Any *data) +{ + if(_data) + _data->decrRef(); + _data=data; + _data->incrRef(); +} + +OutputToyPort::~OutputToyPort() +{ + if(_data) + _data->decrRef(); +} + +void OutputToyPort::exInit() +{ + if(_data) + { + _data->decrRef(); + _data=0; + } +} + +ToyNode::ToyNode(const ToyNode& other, ComposedNode *father):ElementaryNode(other,father),_nbOfInputsPort(other._nbOfInputsPort,this) +{ +} + +ToyNode::ToyNode(const string& name):ElementaryNode(name),_nbOfInputsPort(NAME_FOR_NB,this,Runtime::_tc_int) +{ + _implementation=MY_IMPL_NAME; +} + +void ToyNode::execute() +{ + int i=0; + double d=0.; + for(list::iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++) + { + i++; + InputToyPort *p=(InputToyPort *) (*iter); + d+=p->getAny()->getDoubleValue(); + } + int size=_setOfOutputPort.size(); + if(size) + d/=(double)(size); + Any *tmp=AtomAny::New((int)_setOfInputPort.size()); + _nbOfInputsPort.put((const void *)tmp); + tmp->decrRef(); + for(list::iterator iter2=_setOfOutputPort.begin();iter2!=_setOfOutputPort.end();iter2++) + { + Any *tmp=AtomAny::New(d); + (*iter2)->put(tmp); + tmp->decrRef(); + } +} + +std::list ToyNode::getSetOfOutputPort() const +{ + list ret=ElementaryNode::getSetOfOutputPort(); + ret.push_back((OutputPort *)&_nbOfInputsPort); + return ret; +} + +int ToyNode::getNumberOfOutputPorts() const +{ + return ElementaryNode::getNumberOfInputPorts()+1; +} + +OutputPort *ToyNode::getOutputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_FOR_NB) + return (OutputPort *)&_nbOfInputsPort; + else + return ElementaryNode::getOutputPort(name); +} + +Node *ToyNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new ToyNode(*this,father); +} + +ToyNode1S::ToyNode1S(const std::string& name):ServiceNode(name) +{ +} + +ToyNode1S::ToyNode1S(const ToyNode1S& other, ComposedNode *father):ServiceNode(other,father) +{ +} + +void ToyNode1S::execute() +{ + //nothing only to test deployment calculation not for running. +} + +std::string ToyNode1S::getKind() const +{ + return KIND; +} + +ServiceNode *ToyNode1S::createNode(const std::string& name) +{ + ToyNode1S* node=new ToyNode1S(name); + node->setComponent(_component); + return node; +} + +Node *ToyNode1S::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new ToyNode1S(*this,father); +} + +ToyNode2S::ToyNode2S(const std::string& name):ServiceNode(name) +{ +} + +ToyNode2S::ToyNode2S(const ToyNode2S& other, ComposedNode *father):ServiceNode(other,father) +{ +} + +void ToyNode2S::execute() +{ + //nothing only to test deployment calculation not for running. +} + +std::string ToyNode2S::getKind() const +{ + return KIND; +} + +ServiceNode *ToyNode2S::createNode(const std::string& name) +{ + ToyNode2S* node=new ToyNode2S(name); + node->setComponent(_component); + return node; +} + +Node *ToyNode2S::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new ToyNode2S(*this,father); +} + +void SeqToyNode::execute() +{ + int val=_inIntValue.getIntValue(); + SequenceAny *tmp=SequenceAny::New(Runtime::_tc_double,val); + double d=(double) val; + for(int i=0;isetEltAtRank(i,tmp2); + tmp2->decrRef(); + d+=1.; + } + _seqOut.put((const void *)tmp); + tmp->decrRef(); +} + +SeqToyNode::SeqToyNode(const SeqToyNode& other, ComposedNode *father):ElementaryNode(other,father), + _seqOut(other._seqOut,this), + _inIntValue(other._inIntValue,this) +{ +} + +SeqToyNode::SeqToyNode(const std::string& name):ElementaryNode(name),_seqOut(NAME_SEQ_OUTPRT,this,Runtime::_tc_double), + _inIntValue(NAME_NBOFELTS_INSEQ_INPRT,this,Runtime::_tc_int) +{ + _implementation=ToyNode::MY_IMPL_NAME; + TypeCodeSeq *tc=new TypeCodeSeq("","",Runtime::_tc_double); + _seqOut.edSetType(tc); + tc->decrRef(); +} + +int SeqToyNode::getNumberOfInputPorts() const +{ + return ElementaryNode::getNumberOfInputPorts()+1; +} + +std::list SeqToyNode::getSetOfInputPort() const +{ + list ret=ElementaryNode::getSetOfInputPort(); + ret.push_back((InputPort *)&_inIntValue); + return ret; +} + +InputPort *SeqToyNode::getInputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_NBOFELTS_INSEQ_INPRT) + return (InputPort *)&_inIntValue; + else + return ElementaryNode::getInputPort(name); +} + +int SeqToyNode::getNumberOfOutputPorts() const +{ + return ElementaryNode::getNumberOfOutputPorts()+1; +} + +std::list SeqToyNode::getSetOfOutputPort() const +{ + list ret=ElementaryNode::getSetOfOutputPort(); + ret.push_back((OutputPort *)&_seqOut); + return ret; +} + +OutputPort *SeqToyNode::getOutputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_SEQ_OUTPRT) + return (OutputPort *)&_seqOut; + else + return ElementaryNode::getOutputPort(name); +} + +Node *SeqToyNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new SeqToyNode(*this,father); +} + +void Seq2ToyNode::execute() +{ + SequenceAny *vals1=(SequenceAny *)_inValue1.getValue(); + SequenceAny *vals2=(SequenceAny *)_inValue2.getValue(); + int val=vals1->size(); + SequenceAny *tmp=SequenceAny::New(Runtime::_tc_int,val); + for(int i=0;igetDoubleValue()+(*vals2)[i]->getDoubleValue())); + tmp->setEltAtRank(i,tmp2); + tmp2->decrRef(); + } + _seqOut.put((const void *)tmp); + tmp->decrRef(); +} + +Seq2ToyNode::Seq2ToyNode(const Seq2ToyNode& other, ComposedNode *father):ElementaryNode(other,father), + _seqOut(other._seqOut,this), + _inValue1(other._inValue1,this), + _inValue2(other._inValue1,this) +{ +} + +Seq2ToyNode::Seq2ToyNode(const std::string& name):ElementaryNode(name),_seqOut(NAME_SEQ_OUTPRT,this,Runtime::_tc_double), + _inValue1(NAME_SEQ_INPRT1,this,Runtime::_tc_int), + _inValue2(NAME_SEQ_INPRT2,this,Runtime::_tc_int) +{ + _implementation=ToyNode::MY_IMPL_NAME; + TypeCodeSeq *tc=new TypeCodeSeq("","",Runtime::_tc_double); + _inValue1.edSetType(tc); + _inValue2.edSetType(tc); + tc->decrRef(); + tc=new TypeCodeSeq("","",Runtime::_tc_int); + _seqOut.edSetType(tc); + tc->decrRef(); +} + +int Seq2ToyNode::getNumberOfInputPorts() const +{ + return ElementaryNode::getNumberOfOutputPorts()+2; +} + +std::list Seq2ToyNode::getSetOfInputPort() const +{ + list ret=ElementaryNode::getSetOfInputPort(); + ret.push_back((InputPort *)&_inValue1); + ret.push_back((InputPort *)&_inValue2); + return ret; +} + +InputPort *Seq2ToyNode::getInputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_SEQ_INPRT1) + return (InputPort *)&_inValue1; + else if(name==NAME_SEQ_INPRT2) + return (InputPort *)&_inValue2; + else + return ElementaryNode::getInputPort(name); +} + +int Seq2ToyNode::getNumberOfOutputPorts() const +{ + return ElementaryNode::getNumberOfOutputPorts()+1; +} + +std::list Seq2ToyNode::getSetOfOutputPort() const +{ + list ret=ElementaryNode::getSetOfOutputPort(); + ret.push_back((OutputPort *)&_seqOut); + return ret; +} + +OutputPort *Seq2ToyNode::getOutputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_SEQ_OUTPRT) + return (OutputPort *)&_seqOut; + else + return ElementaryNode::getOutputPort(name); +} + +Node *Seq2ToyNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new Seq2ToyNode(*this,father); +} + +void Seq3ToyNode::execute() +{ + SequenceAny *vals1=(SequenceAny *)_inValue1.getValue(); + SequenceAny *vals2=(SequenceAny *)_inValue2.getValue(); + int val=vals1->size(); + TypeCodeSeq *tc1=new TypeCodeSeq("","",Runtime::_tc_int); + SequenceAny *tmp=SequenceAny::New(tc1,val); + tc1->decrRef(); + for(int i=0;isize(); + SequenceAny *tmp2=SequenceAny::New(Runtime::_tc_int,val2); + for(int j=0;jgetDoubleValue()+(*vals2)[i][j]->getDoubleValue())); + tmp2->setEltAtRank(j,tmp3); + tmp3->decrRef(); + } + tmp->setEltAtRank(i,tmp2); + tmp2->decrRef(); + } + _seqOut.put((const void *)tmp); + tmp->decrRef(); +} + +Seq3ToyNode::Seq3ToyNode(const Seq3ToyNode& other, ComposedNode *father):ElementaryNode(other,father), + _seqOut(other._seqOut,this), + _inValue1(other._inValue1,this), + _inValue2(other._inValue1,this) +{ +} + +Seq3ToyNode::Seq3ToyNode(const std::string& name):ElementaryNode(name),_seqOut(NAME_SEQ_OUTPRT,this,Runtime::_tc_double), + _inValue1(NAME_SEQ_INPRT1,this,Runtime::_tc_int), + _inValue2(NAME_SEQ_INPRT2,this,Runtime::_tc_int) +{ + _implementation=ToyNode::MY_IMPL_NAME; + TypeCodeSeq *tc1=new TypeCodeSeq("","",Runtime::_tc_double); + TypeCodeSeq *tc2=new TypeCodeSeq("","",tc1); + tc1->decrRef(); + _inValue1.edSetType(tc2); + _inValue2.edSetType(tc2); + tc2->decrRef(); + tc1=new TypeCodeSeq("","",Runtime::_tc_int); + tc2=new TypeCodeSeq("","",tc1); + tc1->decrRef(); + _seqOut.edSetType(tc2); + tc2->decrRef(); +} + +int Seq3ToyNode::getNumberOfInputPorts() const +{ + return ElementaryNode::getNumberOfOutputPorts()+2; +} + +std::list Seq3ToyNode::getSetOfInputPort() const +{ + list ret=ElementaryNode::getSetOfInputPort(); + ret.push_back((InputPort *)&_inValue1); + ret.push_back((InputPort *)&_inValue2); + return ret; +} + +InputPort *Seq3ToyNode::getInputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_SEQ_INPRT1) + return (InputPort *)&_inValue1; + else if(name==NAME_SEQ_INPRT2) + return (InputPort *)&_inValue2; + else + return ElementaryNode::getInputPort(name); +} + +int Seq3ToyNode::getNumberOfOutputPorts() const +{ + return ElementaryNode::getNumberOfOutputPorts()+1; +} + +std::list Seq3ToyNode::getSetOfOutputPort() const +{ + list ret=ElementaryNode::getSetOfOutputPort(); + ret.push_back((OutputPort *)&_seqOut); + return ret; +} + +OutputPort *Seq3ToyNode::getOutputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_SEQ_OUTPRT) + return (OutputPort *)&_seqOut; + else + return ElementaryNode::getOutputPort(name); +} + +Node *Seq3ToyNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new Seq3ToyNode(*this,father); +} + +InputLimitPort::InputLimitPort(const InputLimitPort& other, Node *newHelder):InputPort(other,newHelder), + DataPort(other,newHelder),Port(other,newHelder), + _data(0),_initData(0) +{ + if(other._data) + _data=other._data->clone(); + if(other._initData) + _initData=other._initData->clone(); +} + +InputLimitPort::InputLimitPort(const string& name, Node *node) + :InputPort(name, node, Runtime::_tc_double), + DataPort(name, node, Runtime::_tc_double), + Port(node),_data(0),_initData(0) +{ +} + +void InputLimitPort::put(const void *data) throw(ConversionException) +{ + put((Any *)data); +} + +InputPort *InputLimitPort::clone(Node *newHelder) const +{ + return new InputLimitPort(*this,newHelder); +} + +bool InputLimitPort::edIsManuallyInitialized() const +{ + return _initData!=0; +} + +void *InputLimitPort::get() const throw(Exception) +{ + if(!_data) + { + string what="InputLimitPort::get : no value currently in input whith name \""; what+=_name; what+="\""; + throw Exception(what); + } + return (void *)_data; +} + +void InputLimitPort::edRemoveManInit() +{ + if(_initData) + _initData->decrRef(); + _initData=0; + InputPort::edRemoveManInit(); +} + +void InputLimitPort::put(Any *data) +{ + if(_data) + _data->decrRef(); + _data=data; + _data->incrRef(); +} + +void InputLimitPort::exSaveInit() +{ + if(_initData) _initData->decrRef(); + _initData=_data; + _initData->incrRef(); +} + +void InputLimitPort::exRestoreInit() +{ + if(!_initData)return; + if(_data) _data->decrRef(); + _data=_initData; + _data->incrRef(); +} + +InputLimitPort::~InputLimitPort() +{ + if(_data) + _data->decrRef(); + if(_initData) + _initData->decrRef(); +} + +OutputLimitPort::OutputLimitPort(const OutputLimitPort& other, Node *newHelder):OutputPort(other,newHelder), + DataPort(other,newHelder),Port(other,newHelder),_data(0) +{ + if(other._data) + _data=other._data->clone(); +} + +OutputLimitPort::OutputLimitPort(const string& name, Node *node, TypeCode *type):OutputPort(name, node, type),DataPort(name, node, type),Port(node),_data(0) +{ +} + +void OutputLimitPort::put(const void *data) throw(ConversionException) +{ + put((Any *)data); + OutputPort::put(data); +} + +OutputPort *OutputLimitPort::clone(Node *newHelder) const +{ + return new OutputLimitPort(*this,newHelder); +} + +void OutputLimitPort::put(Any *data) +{ + if(_data) + _data->decrRef(); + _data=data; + _data->incrRef(); +} + +OutputLimitPort::~OutputLimitPort() +{ + if(_data) + _data->decrRef(); +} + +void LimitNode::init(bool start) +{ + if(start) + _current=0.; + Node::init(start); +} + +void LimitNode::execute() +{ + _current+=_entry.getAny()->getDoubleValue(); + Any *tmp=AtomAny::New(_current); + _counterPort.put((const void *)tmp); + tmp->decrRef(); + bool verdict=(_current<_limit); + tmp=AtomAny::New(verdict); + _switchPort.put((const void *)tmp); + tmp->decrRef(); +} + +Node *LimitNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new LimitNode(*this,father); +} + +std::list LimitNode::getSetOfInputPort() const +{ + list ret=ElementaryNode::getSetOfInputPort(); + ret.push_back((InputPort *)&_entry); + return ret; +} + +std::list LimitNode::getSetOfOutputPort() const +{ + list ret=ElementaryNode::getSetOfOutputPort(); + ret.push_back((OutputPort *)&_switchPort); + ret.push_back((OutputPort *)&_counterPort); + return ret; +} + +InputPort *LimitNode::getInputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_FOR_SWPORT) + return (InputPort *)&_entry; + else + return ElementaryNode::getInputPort(name); +} + +OutputPort *LimitNode::getOutputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_FOR_SWPORT) + return (OutputPort *)&_switchPort; + else if(name==NAME_FOR_SWPORT2) + return (OutputPort *)&_counterPort; + else + return ElementaryNode::getOutputPort(name); +} + +LimitNode::LimitNode(const LimitNode& other, ComposedNode *father):ElementaryNode(other,father), + _limit(other._limit),_current(other._limit), + _entry(other._entry,this), + _switchPort(other._switchPort,this), + _counterPort(other._counterPort,this) +{ +} + +LimitNode::LimitNode(const string& name):ElementaryNode(name),_limit(0.),_current(0.), + _entry(NAME_FOR_SWPORT,this), + _switchPort(NAME_FOR_SWPORT,this, Runtime::_tc_bool), + _counterPort(NAME_FOR_SWPORT2,this, Runtime::_tc_double) +{ +} diff --git a/src/engine/Test/ToyNode.hxx b/src/engine/Test/ToyNode.hxx new file mode 100644 index 000000000..3692f08e4 --- /dev/null +++ b/src/engine/Test/ToyNode.hxx @@ -0,0 +1,245 @@ +#ifndef __TOYNODE_HXX__ +#define __TOYNODE_HXX__ + +#include "ServiceNode.hxx" +#include "AnyInputPort.hxx" +#include "OutputPort.hxx" +#include "InputPort.hxx" +#include "Any.hxx" + +namespace YACS +{ + namespace ENGINE + { + class InputToyPort : public InputPort + { + public: + InputToyPort(const InputToyPort& other, Node *newHelder); + InputToyPort(const std::string& name, Node *node); + void put(const void *data) throw(ConversionException); + InputPort *clone(Node *newHelder) const; + bool edIsManuallyInitialized() const; + void *get() const throw(Exception); + void edRemoveManInit(); + void put(Any *data); + ~InputToyPort(); + Any *getAny() { return _data; } + void exSaveInit(); + void exRestoreInit(); + protected: + Any *_data; + Any *_initData; + }; + + class OutputToyPort : public OutputPort + { + public: + OutputToyPort(const std::string& name, Node *node, TypeCode *type); + OutputToyPort(const OutputToyPort& other, Node *newHelder); + void put(const void *data) throw(ConversionException); + OutputPort *clone(Node *newHelder) const; + void put(Any *data); + ~OutputToyPort(); + void exInit(); + Any *get() { return _data; } + protected: + Any *_data; + }; + + class ToyNode : public ElementaryNode + { + private: + OutputToyPort _nbOfInputsPort; + public: + void execute(); + ToyNode(const ToyNode& other, ComposedNode *father); + ToyNode(const std::string& name); + OutputPort *edGetNbOfInputsOutputPort() { return &_nbOfInputsPort; } + std::list getSetOfOutputPort() const; + int getNumberOfOutputPorts()const; + OutputPort *getOutputPort(const std::string& name) const throw(Exception); + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + public: + static char NAME_FOR_NB[]; + static char MY_IMPL_NAME[]; + }; + + class ToyNode1S : public ServiceNode + { + public: + ToyNode1S(const std::string& name); + ToyNode1S(const ToyNode1S& other, ComposedNode *father); + void execute(); + std::string getKind() const; + ServiceNode *createNode(const std::string& name); + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + public: + static const char KIND[]; + }; + + class ToyNode2S : public ServiceNode + { + public: + ToyNode2S(const std::string& name); + ToyNode2S(const ToyNode2S& other, ComposedNode *father); + void execute(); + std::string getKind() const; + ServiceNode *createNode(const std::string& name); + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + public: + static const char KIND[]; + }; + + class SeqToyNode : public ElementaryNode + { + private: + OutputToyPort _seqOut; + AnyInputPort _inIntValue; + public: + void execute(); + SeqToyNode(const SeqToyNode& other, ComposedNode *father); + SeqToyNode(const std::string& name); + OutputPort *edGetSeqOut() const { return (OutputPort *)&_seqOut; } + InputPort *edGetInIntValue() const { return (InputPort *)&_inIntValue; } + int getNumberOfInputPorts() const; + std::list getSetOfInputPort() const; + InputPort *getInputPort(const std::string& name) const throw(Exception); + int getNumberOfOutputPorts() const; + std::list getSetOfOutputPort() const; + OutputPort *getOutputPort(const std::string& name) const throw(Exception); + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + public: + static char NAME_NBOFELTS_INSEQ_INPRT[]; + static char NAME_SEQ_OUTPRT[]; + }; + + class Seq2ToyNode : public ElementaryNode + { + private: + OutputToyPort _seqOut; + AnyInputPort _inValue1; + AnyInputPort _inValue2; + public: + void execute(); + Seq2ToyNode(const Seq2ToyNode& other, ComposedNode *father); + Seq2ToyNode(const std::string& name); + OutputToyPort *edGetSeqOut() const { return (OutputToyPort *)&_seqOut; } + InputPort *edGetInValue1() const { return (InputPort *)&_inValue1; } + InputPort *edGetInValue2() const { return (InputPort *)&_inValue2; } + int getNumberOfInputPorts() const; + std::list getSetOfInputPort() const; + InputPort *getInputPort(const std::string& name) const throw(Exception); + int getNumberOfOutputPorts() const; + std::list getSetOfOutputPort() const; + OutputPort *getOutputPort(const std::string& name) const throw(Exception); + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + public: + static char NAME_SEQ_INPRT1[]; + static char NAME_SEQ_INPRT2[]; + static char NAME_SEQ_OUTPRT[]; + }; + + class Seq3ToyNode : public ElementaryNode + { + private: + OutputToyPort _seqOut; + AnyInputPort _inValue1; + AnyInputPort _inValue2; + public: + void execute(); + Seq3ToyNode(const Seq3ToyNode& other, ComposedNode *father); + Seq3ToyNode(const std::string& name); + OutputToyPort *edGetSeqOut() const { return (OutputToyPort *)&_seqOut; } + InputPort *edGetInValue1() const { return (InputPort *)&_inValue1; } + InputPort *edGetInValue2() const { return (InputPort *)&_inValue2; } + int getNumberOfInputPorts() const; + std::list getSetOfInputPort() const; + InputPort *getInputPort(const std::string& name) const throw(Exception); + int getNumberOfOutputPorts() const; + std::list getSetOfOutputPort() const; + OutputPort *getOutputPort(const std::string& name) const throw(Exception); + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + public: + static char NAME_SEQ_INPRT1[]; + static char NAME_SEQ_INPRT2[]; + static char NAME_SEQ_OUTPRT[]; + }; + + class LimitNode; + + class InputLimitPort : public InputPort + { + friend class LimitNode; + public: + void put(const void *data) throw(ConversionException); + InputPort *clone(Node *newHelder) const; + bool edIsManuallyInitialized() const; + void *get() const throw(Exception); + void edRemoveManInit(); + void put(Any *data); + ~InputLimitPort(); + Any *getAny() { return _data; } + void exSaveInit(); + void exRestoreInit(); + private: + InputLimitPort(const InputLimitPort& other, Node *newHelder); + InputLimitPort(const std::string& name, Node *node); + protected: + Any *_data; + Any *_initData; + }; + + class OutputLimitPort : public OutputPort + { + friend class LimitNode; + public: + void put(const void *data) throw(ConversionException); + OutputPort *clone(Node *newHelder) const; + void put(Any *data); + ~OutputLimitPort(); + Any *get() { return _data; } + private: + OutputLimitPort(const OutputLimitPort& other, Node *newHelder); + OutputLimitPort(const std::string& name, Node *node, TypeCode *type); + protected: + Any *_data; + }; + + class LimitNode : public ElementaryNode + { + private: + double _limit; + double _current; + InputLimitPort _entry; + OutputLimitPort _switchPort; + OutputLimitPort _counterPort; + public: + void init(bool start=true); + void execute(); + void setLimit(double limit) { _limit=limit; } + InputPort *getEntry() { return &_entry; } + OutputPort *getSwitchPort() { return &_switchPort; } + OutputPort *getCounterPort() { return &_counterPort; } + std::list getSetOfInputPort() const; + std::list getSetOfOutputPort() const; + InputPort *getInputPort(const std::string& name) const throw(Exception); + OutputPort *getOutputPort(const std::string& name) const throw(Exception); + LimitNode(const LimitNode& other, ComposedNode *father); + LimitNode(const std::string& name); + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + public: + static char MY_IMPL_NAME[]; + static char NAME_FOR_SWPORT[]; + static char NAME_FOR_SWPORT2[]; + }; + } +} + +#endif diff --git a/src/engine/Test/engineIntegrationTest.cxx b/src/engine/Test/engineIntegrationTest.cxx new file mode 100644 index 000000000..92cc1a16b --- /dev/null +++ b/src/engine/Test/engineIntegrationTest.cxx @@ -0,0 +1,2905 @@ +#include "engineIntegrationTest.hxx" +#include "RuntimeForEngineIntegrationTest.hxx" +#include "ComponentInstanceTest.hxx" +#include "OutputDataStreamPort.hxx" +#include "InputDataStreamPort.hxx" +#include "ContainerTest.hxx" +#include "OptimizerLoop.hxx" +#include "ForEachLoop.hxx" +#include "WhileLoop.hxx" +#include "TypeCode.hxx" +#include "Executor.hxx" +#include "LinkInfo.hxx" +#include "ForLoop.hxx" +#include "ToyNode.hxx" +#include "Switch.hxx" +#include "Bloc.hxx" +#include "Proc.hxx" + +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; + +#define DBL_PRECISION_COMPARE 1.e-12 + +using namespace YACS::ENGINE; + +void EngineIntegrationTest::setUp() +{ + RuntimeForEngineIntegrationTest::setRuntime(); +} + +void EngineIntegrationTest::tearDown() +{ +} + +//Simplest test to test basic mechanisms like Data, initialisation of ports. +void EngineIntegrationTest::testBloc1() +{ + ToyNode *n1=new ToyNode("T1"); + InputPort *i8=n1->edAddInputPort("o",Runtime::_tc_double); + InputPort *i9=n1->edAddInputPort("p",Runtime::_tc_double); + Bloc *graph=new Bloc("toto"); + graph->edAddChild(n1); + OutputPort *o1=n1->edAddOutputPort("b",Runtime::_tc_double); + i9->edInit(5.67); + i8->edInit(2.78); + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)o1)->get()->getDoubleValue(),8.45,DBL_PRECISION_COMPARE ); + OutputPort *o2=n1->edAddOutputPort("c",Runtime::_tc_double); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)o1)->get()->getDoubleValue(),4.225,DBL_PRECISION_COMPARE ); + Executor exe2; + Bloc *clonedGraph=(Bloc *)graph->clone(0); + delete graph; + exe2.RunW(clonedGraph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)clonedGraph->getOutputPort("T1.b"))->get()->getDoubleValue(),4.225,DBL_PRECISION_COMPARE ); + delete clonedGraph; +} + +//Only one level(hierarchy) simple graph. Tests DF and CF links. +void EngineIntegrationTest::testBloc2() +{ + ToyNode *n1=new ToyNode("T1"); + ToyNode *n2=new ToyNode("T2"); + ToyNode *n3=new ToyNode("T3"); + 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",Runtime::_tc_double); InputPort *i1_b=n1->edAddInputPort("b",Runtime::_tc_double); OutputPort *o1_j=n1->edAddOutputPort("j",Runtime::_tc_double); OutputPort *o1_k=n1->edAddOutputPort("k",Runtime::_tc_double); + InputPort *i2_c=n2->edAddInputPort("c",Runtime::_tc_double); InputPort *i2_d=n2->edAddInputPort("d",Runtime::_tc_double); OutputPort *o2_f=n2->edAddOutputPort("f",Runtime::_tc_double); + InputPort *i3_e=n3->edAddInputPort("e",Runtime::_tc_double); OutputPort *o3_g=n3->edAddOutputPort("g",Runtime::_tc_double); OutputPort *o3_h=n3->edAddOutputPort("h",Runtime::_tc_double); + InputPort *i4_l=n4->edAddInputPort("l",Runtime::_tc_double); InputPort *i4_m=n4->edAddInputPort("m",Runtime::_tc_double); OutputPort *o4_i=n4->edAddOutputPort("i",Runtime::_tc_double); + //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(); + i1_a->edInit(1.2); + i1_b->edInit(3.4); + i2_d->edInit(7.); + //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( ((OutputToyPort*)o4_i)->get()->getDoubleValue(),10.45,DBL_PRECISION_COMPARE ); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)o4_i)->get()->getDoubleValue(),10.45,DBL_PRECISION_COMPARE ); + Executor exe2; + Bloc *clonedGraph=(Bloc *)graph->clone(0); + exe2.RunW(clonedGraph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)clonedGraph->getOutputPort("T4.i"))->get()->getDoubleValue(),10.45,DBL_PRECISION_COMPARE ); + delete clonedGraph; + 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 EngineIntegrationTest::testBloc3() +{ + 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"); 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); + CPPUNIT_ASSERT( toto->edAddCFLink(n2,titi) ); + CPPUNIT_ASSERT( !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",Runtime::_tc_double); OutputPort *o2_a=n2->edAddOutputPort("a",Runtime::_tc_double); OutputPort *o2_b=n2->edAddOutputPort("b",Runtime::_tc_double); + InputPort *i3_a=n3->edAddInputPort("a",Runtime::_tc_double); OutputPort *o3_a=n3->edAddOutputPort("a",Runtime::_tc_double); OutputPort *o3_b=n3->edAddOutputPort("b",Runtime::_tc_double); + InputPort *i4_a=n4->edAddInputPort("a",Runtime::_tc_double); InputPort *i4_b=n4->edAddInputPort("b",Runtime::_tc_double); OutputPort *o4_a=n4->edAddOutputPort("a",Runtime::_tc_double); OutputPort *o4_b=n4->edAddOutputPort("b",Runtime::_tc_double); + InputPort *i5_a=n5->edAddInputPort("a",Runtime::_tc_double); InputPort *i5_b=n5->edAddInputPort("b",Runtime::_tc_double); OutputPort *o5_a=n5->edAddOutputPort("a",Runtime::_tc_double); + InputPort *i6_a=n6->edAddInputPort("a",Runtime::_tc_double); InputPort *i6_b=n6->edAddInputPort("b",Runtime::_tc_double); OutputPort *o6_a=n6->edAddOutputPort("a",Runtime::_tc_double); + InputPort *i7_a=n7->edAddInputPort("a",Runtime::_tc_double); OutputPort *o7_a=n7->edAddOutputPort("a",Runtime::_tc_double); + InputPort *i8_a=n8->edAddInputPort("a",Runtime::_tc_double); InputPort *i8_b=n8->edAddInputPort("b",Runtime::_tc_double); OutputPort *o8_a=n8->edAddOutputPort("a",Runtime::_tc_double); + // + 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); + // + i2_a->edInit(1.2); + i6_b->edInit(7.); + i4_a->edInit(7.); + i7_a->edInit(3.); + CPPUNIT_ASSERT_EQUAL( 1, toto->getNumberOfCFLinks() ); CPPUNIT_ASSERT_EQUAL( 3, titi->getNumberOfCFLinks() ); + CPPUNIT_ASSERT_EQUAL( 1, tata->getNumberOfCFLinks() ); + Executor exe; + exe.RunW(toto); + CPPUNIT_ASSERT_EQUAL(toto->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(titi->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(tata->getState(),YACS::DONE); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)o6_a)->get()->getDoubleValue(),7.3,DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)o4_a)->get()->getDoubleValue(),3.8,DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)o8_a)->get()->getDoubleValue(),10.3,DBL_PRECISION_COMPARE ); + exe.RunW(toto); + CPPUNIT_ASSERT_EQUAL(toto->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(titi->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(tata->getState(),YACS::DONE); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)o6_a)->get()->getDoubleValue(),7.3,DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)o4_a)->get()->getDoubleValue(),3.8,DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)o8_a)->get()->getDoubleValue(),10.3,DBL_PRECISION_COMPARE ); + Bloc *clonedGraph=(Bloc *)toto->clone(0); + Bloc *titiCloned=(Bloc *)titi->clone(0);//to check internal links only cpy + CPPUNIT_ASSERT_EQUAL(4,(int)titiCloned->getSetOfInternalLinks().size()); + CPPUNIT_ASSERT_EQUAL(7,(int)clonedGraph->getSetOfInternalLinks().size()); + delete titiCloned; + titi->edRemoveChild(n7); + delete n7; + CPPUNIT_ASSERT_EQUAL( toto->getNumberOfCFLinks(),1 ); CPPUNIT_ASSERT_EQUAL( titi->getNumberOfCFLinks(),2 ); + CPPUNIT_ASSERT_EQUAL( tata->getNumberOfCFLinks(),1 ); + titi->edRemoveChild(tata); + delete tata; + CPPUNIT_ASSERT_EQUAL( 1, toto->getNumberOfCFLinks() ); CPPUNIT_ASSERT_EQUAL( 0, titi->getNumberOfCFLinks() ); + delete toto; + Executor exe2; + exe2.RunW(clonedGraph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)clonedGraph->getOutputPort("titi.tata.T6.a"))->get()->getDoubleValue(),7.3,DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)clonedGraph->getOutputPort("titi.tata.T4.a"))->get()->getDoubleValue(),3.8,DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)clonedGraph->getOutputPort("titi.T8.a"))->get()->getDoubleValue(),10.3,DBL_PRECISION_COMPARE ); + delete clonedGraph; +} + +void EngineIntegrationTest::testForLoop1() +{ + TypeCode *tc_double = Runtime::_tc_double; + TypeCode *tc_int = Runtime::_tc_int; + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",tc_double); + i11->edInit(3.14); + InputPort *i12=n1->edAddInputPort("i12",tc_double); + i12->edInit(2.78); + InputPort *i13=n1->edAddInputPort("i13",tc_double); + i13->edInit(7.177); + OutputPort *o1=n1->edAddOutputPort("o1",tc_double); + OutputPort *o2=n1->edGetNbOfInputsOutputPort(); + Bloc *graph=new Bloc("Graph"); + graph->edAddChild(n1); + Bloc *titi=new Bloc("titi"); + ForLoop *loop=new ForLoop("toto"); + ToyNode *n2=new ToyNode("T2"); + titi->edAddChild(n2); + InputPort *i21=n2->edAddInputPort("i1",tc_double); + InputPort *i22=n2->edAddInputPort("i2",tc_double); + i22->edInit(2.1); + OutputPort *o21=n2->edAddOutputPort("o1",tc_double); + loop->edSetNode(titi); + graph->edAddChild(loop); + InputPort *iNbTimes=loop->edGetNbOfTimesInputPort(); + graph->edAddLink(o2,iNbTimes); + graph->edAddLink(o1,i21); + graph->edAddCFLink(n1,loop); + graph->edAddLink(o21,i21); + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)n2->getOutputPort("o1"))->get()->getDoubleValue(),19.397, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)n2->getOutputPort("o1"))->get()->getDoubleValue(),19.397, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + Bloc *clonedGraph=(Bloc *)graph->clone(0); + delete graph; + Executor exe2; + exe2.RunW(clonedGraph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)clonedGraph->getOutputPort("toto.titi.T2.o1"))->get()->getDoubleValue(),19.397, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(((Loop *)clonedGraph->getChildByName("toto"))->getNbOfTurns(),3); + CPPUNIT_ASSERT_EQUAL(clonedGraph->getChildByName("toto")->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(clonedGraph->getState(),YACS::DONE); + delete clonedGraph; +} + +void EngineIntegrationTest::testForLoop2() +{ + TypeCode *tc_double = Runtime::_tc_double; + TypeCode *tc_int = Runtime::_tc_int; + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",tc_double); + i11->edInit(3.14); + InputPort *i12=n1->edAddInputPort("i12",tc_double); + i12->edInit(2.78); + InputPort *i13=n1->edAddInputPort("i13",tc_double); + i13->edInit(7.177); + OutputPort *o1=n1->edAddOutputPort("o1",tc_double); + OutputPort *o2=n1->edGetNbOfInputsOutputPort(); + Bloc *graph=new Bloc("Graph"); + graph->edAddChild(n1); + ForLoop *loop=new ForLoop("toto"); + ToyNode *n2=new ToyNode("T2"); + InputPort *i21=n2->edAddInputPort("i1",tc_double); + InputPort *i22=n2->edAddInputPort("i2",tc_double); + i22->edInit(2.1); + OutputPort *o21=n2->edAddOutputPort("o1",tc_double); + loop->edSetNode(n2); + graph->edAddChild(loop); + InputPort *iNbTimes=loop->edGetNbOfTimesInputPort(); + graph->edAddLink(o2,iNbTimes); + graph->edAddLink(o1,i21); + graph->edAddCFLink(n1,loop); + graph->edAddLink(o21,i21); + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)n2->getOutputPort("o1"))->get()->getDoubleValue(),19.397, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)n2->getOutputPort("o1"))->get()->getDoubleValue(),19.397, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + delete graph; +} + +//Test on loop when 0 turn of forloop is done +void EngineIntegrationTest::testForLoop3() +{ + TypeCode *tc_double = Runtime::_tc_double; + TypeCode *tc_int = Runtime::_tc_int; + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",tc_double); + i11->edInit(3.14); + InputPort *i12=n1->edAddInputPort("i12",tc_double); + i12->edInit(2.78); + OutputPort *o11=n1->edAddOutputPort("o1",tc_double); + OutputPort *o12=n1->edGetNbOfInputsOutputPort(); + ToyNode *n2=new ToyNode("T2"); + InputPort *i21=n2->edAddInputPort("i1",tc_double); + InputPort *i22=n2->edAddInputPort("i2",tc_double); + i22->edInit(2.1); + OutputPort *o21=n2->edAddOutputPort("o1",tc_double); + ToyNode *n3=new ToyNode("T3"); + InputPort *i31=n3->edAddInputPort("i1",tc_double); + OutputPort *o31=n3->edAddOutputPort("o1",tc_double); + ForLoop *loop=new ForLoop("toto"); + loop->edSetNode(n2); + Bloc *graph=new Bloc("Graph"); + graph->edAddChild(loop); + graph->edAddChild(n1); + graph->edAddChild(n3); + graph->edAddCFLink(n1,loop); + graph->edAddCFLink(loop,n3); + graph->edAddLink(o11,i21); + graph->edAddLink(o12,loop->edGetNbOfTimesInputPort()); + graph->edAddLink(o21,i21); + graph->edAddLink(o21,i31); + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),10.12, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),2); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),10.12, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),2); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + //Let's go to test 0 cycle whithout any back dependancies : normal behaviour + n1->edRemovePort(i11); + n1->edRemovePort(i12); + graph->edRemoveLink(o21,i31); + graph->edAddLink(o11,i31); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + Bloc *clonedGraph=(Bloc *)graph->clone(0); + Executor exe2; + exe2.RunW(clonedGraph); + CPPUNIT_ASSERT_EQUAL(((Loop *)clonedGraph->getChildByName("toto"))->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(((Loop *)clonedGraph->getChildByName("toto"))->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(clonedGraph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(clonedGraph->getChildByName("T1")->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(clonedGraph->getChildByName("T3")->getState(),YACS::DONE); + delete clonedGraph; + // + graph->edRemoveLink(o11,i31); + graph->edAddLink(o21,i31);//this link obliges that loops run at least 1 time : which is not the case + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::ERROR); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::FAILED); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::FAILED); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::ERROR); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::FAILED); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::FAILED); + clonedGraph=(Bloc *)graph->clone(0); + exe2.RunW(clonedGraph); + CPPUNIT_ASSERT_EQUAL(((Loop *)clonedGraph->getChildByName("toto"))->getState(),YACS::ERROR); + CPPUNIT_ASSERT_EQUAL(((Loop *)clonedGraph->getChildByName("toto"))->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(clonedGraph->getState(),YACS::FAILED); + CPPUNIT_ASSERT_EQUAL(clonedGraph->getChildByName("T1")->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(clonedGraph->getChildByName("T3")->getState(),YACS::FAILED); + delete clonedGraph; + + //retrieves back state and retest + graph->edRemoveLink(o21,i31); + graph->edAddLink(o11,i31); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + //Retrieves initial graph and test again + graph->edRemoveLink(o11,i31); + graph->edAddLink(o21,i31); + i11=n1->edAddInputPort("i11",tc_double); + i11->edInit(3.14); + i12=n1->edAddInputPort("i12",tc_double); + i12->edInit(2.78); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),10.12, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),2); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),10.12, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),2); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + delete graph; +} + +void EngineIntegrationTest::testForLoop4() +{ + Bloc *graph=new Bloc("Graph"); + ToyNode *n1=new ToyNode("T1"); graph->edAddChild(n1); + ForLoop *loop=new ForLoop("loop"); graph->edAddChild(loop); graph->edAddCFLink(n1,loop); + ToyNode *n2=new ToyNode("T2"); loop->edSetNode(n2); + n1->edAddInputPort("i11",Runtime::_tc_double)->edInit(3.); + n1->edAddInputPort("i12",Runtime::_tc_double)->edInit(4.); + n1->edAddInputPort("i13",Runtime::_tc_double)->edInit(5.); + OutputPort *o11=n1->edAddOutputPort("o11",Runtime::_tc_double); + InputPort *i21=n2->edAddInputPort("i21",Runtime::_tc_double); + n2->edAddInputPort("i22",Runtime::_tc_double)->edInit(2.); + OutputPort *o21=n2->edAddOutputPort("o21",Runtime::_tc_double); + graph->edAddLink(o11,i21); + graph->edAddLink(o21,i21); + graph->edAddLink(n1->edGetNbOfInputsOutputPort(),loop->edGetNbOfTimesInputPort()); + Bloc *graph2=(Bloc *)graph->clone(0); + loop->edGetNbOfTimesInputPort()->edInit(0); + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("loop.T2.o21"))->get()->getDoubleValue(),18., DBL_PRECISION_COMPARE); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("loop.T2.o21"))->get()->getDoubleValue(),18., DBL_PRECISION_COMPARE); + Bloc *blocInt=new Bloc("blocInt"); + graph->edRemoveChild(loop); + blocInt->edAddChild(loop); + graph->edAddChild(blocInt); + graph->edAddCFLink(n1,blocInt); + graph->edAddLink(o11,i21); + graph->edAddLink(n1->edGetNbOfInputsOutputPort(),loop->edGetNbOfTimesInputPort()); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(3,loop->getNbOfTurns()); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("blocInt.loop.T2.o21"))->get()->getDoubleValue(),18., DBL_PRECISION_COMPARE); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(3,loop->getNbOfTurns()); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("blocInt.loop.T2.o21"))->get()->getDoubleValue(),18., DBL_PRECISION_COMPARE); + graph->edRemoveLink(n1->edGetNbOfInputsOutputPort(),loop->edGetNbOfTimesInputPort()); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(0,loop->getNbOfTurns()); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(0,loop->getNbOfTurns()); + + exe.RunW(graph2); + ForLoop *loop2=(ForLoop *)graph2->getChildByName("loop"); + CPPUNIT_ASSERT_EQUAL(loop2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(loop2->getNbOfTurns(),3); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph2->getOutputPort("loop.T2.o21"))->get()->getDoubleValue(),18., DBL_PRECISION_COMPARE); + exe.RunW(graph2); + CPPUNIT_ASSERT_EQUAL(loop2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(loop2->getNbOfTurns(),3); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph2->getOutputPort("loop.T2.o21"))->get()->getDoubleValue(),18., DBL_PRECISION_COMPARE); + Bloc *blocInt2=new Bloc("blocInt"); + n1=(ToyNode *)graph2->getChildByName("T1"); + graph2->edRemoveChild(loop2); + blocInt2->edAddChild(loop2); + graph2->edAddChild(blocInt2); + graph2->edAddCFLink(n1,blocInt2); + o11=graph2->getOutputPort("T1.o11"); + i21=graph2->getInputPort("blocInt.loop.T2.i21"); + graph2->edAddLink(o11,i21); + graph2->edAddLink(n1->edGetNbOfInputsOutputPort(),loop2->edGetNbOfTimesInputPort()); + exe.RunW(graph2); + CPPUNIT_ASSERT_EQUAL(loop2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(3,loop2->getNbOfTurns()); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph2->getOutputPort("blocInt.loop.T2.o21"))->get()->getDoubleValue(),18., DBL_PRECISION_COMPARE); + exe.RunW(graph2); + CPPUNIT_ASSERT_EQUAL(loop2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(3,loop2->getNbOfTurns()); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph2->getOutputPort("blocInt.loop.T2.o21"))->get()->getDoubleValue(),18., DBL_PRECISION_COMPARE); + delete graph2; + delete graph; +} + +//multi loop inclusion +void EngineIntegrationTest::testForLoop5() +{ + Bloc *graph=new Bloc("Graph"); + ToyNode *n1=new ToyNode("T1"); graph->edAddChild(n1); + Bloc *b1=new Bloc("b1"); graph->edAddChild(b1); graph->edAddCFLink(n1,b1); + ForLoop *loop2=new ForLoop("loop2"); b1->edAddChild(loop2); + Bloc *b3=new Bloc("b3"); loop2->edSetNode(b3); + ForLoop *loop4=new ForLoop("loop4"); b3->edAddChild(loop4); + Bloc *b5=new Bloc("b5"); loop4->edSetNode(b5); + ToyNode *n2=new ToyNode("T2"); b5->edAddChild(n2); + n1->edAddInputPort("i11",Runtime::_tc_double)->edInit(3.); + n1->edAddInputPort("i12",Runtime::_tc_double)->edInit(4.); + n1->edAddInputPort("i13",Runtime::_tc_double)->edInit(5.); + OutputPort *o11=n1->edAddOutputPort("o11",Runtime::_tc_double); + graph->edAddLink(n1->edGetNbOfInputsOutputPort(),loop2->edGetNbOfTimesInputPort()); + loop4->edGetNbOfTimesInputPort()->edInit(2); + n2->edAddInputPort("i22",Runtime::_tc_double)->edInit(7.); + InputPort *i21=n2->edAddInputPort("i21",Runtime::_tc_double); + OutputPort *o21=n2->edAddOutputPort("o21",Runtime::_tc_double); + graph->edAddLink(o21,i21); + graph->edAddLink(o11,i21); + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)loop2->getOutputPort("b3.loop4.b5.T2.o21"))->get()->getDoubleValue(),54., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,loop2->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(2,loop4->getNbOfTurns()); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)loop2->getOutputPort("b3.loop4.b5.T2.o21"))->get()->getDoubleValue(),54., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,loop2->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(2,loop4->getNbOfTurns()); + delete graph; +} + +void EngineIntegrationTest::testWhileLoop1() +{ + TypeCode *tc_double = Runtime::_tc_double; + TypeCode *tc_int = Runtime::_tc_int; + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",tc_double); + i11->edInit(3.14); + InputPort *i12=n1->edAddInputPort("i12",tc_double); + i12->edInit(2.78); + InputPort *i13=n1->edAddInputPort("i13",tc_double); + i13->edInit(7.177); + OutputPort *o1=n1->edAddOutputPort("o1",tc_double); + LimitNode *l1=new LimitNode("L1"); + OutputPort *ol1s=l1->getSwitchPort(); + l1->setLimit(25.); + Bloc *graph=new Bloc("Graph"); + // + Bloc *inLoop=new Bloc("inLoop"); + ToyNode *n2=new ToyNode("T2"); + InputPort *i21=n2->edAddInputPort("i1",tc_double); + InputPort *i22=n2->edAddInputPort("i2",tc_double); + OutputPort *o21=n2->edAddOutputPort("o1",tc_double); + i22->edInit(22.1006); + LimitNode *l2=new LimitNode("L2"); + OutputPort *ol2s=l2->getSwitchPort(); + l2->setLimit(100.); + inLoop->edAddChild(n2); + inLoop->edAddChild(l2); + WhileLoop *whileLoop=new WhileLoop("MyWhile"); + whileLoop->edSetNode(inLoop); + inLoop->edAddCFLink(n2,l2); + inLoop->edAddLink(o21,l2->getEntry()); + inLoop->edAddLink(l2->getCounterPort(),i21); + // + graph->edAddChild(n1); + graph->edAddChild(l1); + graph->edAddChild(whileLoop); + graph->edAddCFLink(n1,l1); + graph->edAddCFLink(l1,whileLoop); + graph->edAddCFLink(n1,whileLoop); + graph->edAddLink(l1->getSwitchPort(),whileLoop->edGetConditionPort()); + graph->edAddLink(l2->getSwitchPort(),whileLoop->edGetConditionPort()); + graph->edAddLink(o1,i21); + graph->edAddLink(o1,l1->getEntry()); + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputLimitPort*)l2->getCounterPort())->get()->getDoubleValue(),207.0922, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(whileLoop->getNbOfTurns(),3); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputLimitPort*)l2->getCounterPort())->get()->getDoubleValue(),207.0922, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(whileLoop->getNbOfTurns(),3); + delete graph; +} + +void EngineIntegrationTest::testSwitch() +{ + RuntimeForEngineIntegrationTest::setRuntime(); + Runtime *myRuntime = getRuntime(); + TypeCode *tc_double = Runtime::_tc_double; + TypeCode *tc_int = Runtime::_tc_int; + Bloc *graph=new Bloc("Graph"); + + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",tc_double); + i11->edInit(17.); + OutputPort *o1=n1->edAddOutputPort("o1",tc_double); + graph->edAddChild(n1); + + Switch *mySwitch=new Switch("mySwitch"); + graph->edAddChild(mySwitch); + graph->edAddCFLink(n1,mySwitch); + + ToyNode *n2=new ToyNode("T2"); + InputPort *i21=n2->edAddInputPort("i21",tc_double); + InputPort *i22=n2->edAddInputPort("i22",tc_double); + OutputPort *o21=n2->edAddOutputPort("o21",tc_double); + i22->edInit(1.); + mySwitch->edSetNode(0,n2); + graph->edAddLink(o1,i21); + graph->edAddLink(n1->edGetNbOfInputsOutputPort(),mySwitch->edGetConditionPort()); + ToyNode *n3=new ToyNode("T3"); + InputPort *i31=n3->edAddInputPort("i31",tc_double); + InputPort *i32=n3->edAddInputPort("i32",tc_double); + OutputPort *o31=n3->edAddOutputPort("o31",tc_double); + i32->edInit(2.); + mySwitch->edSetNode(1,n3); + graph->edAddLink(o1,i31); + try + { + graph->edAddLink(o31,i21); + CPPUNIT_ASSERT(0); + } + catch(Exception& e) + { + CPPUNIT_ASSERT(string(e.what())=="Switch::checkLinkPossibility : A link between 2 different cases of a same Switch requested -> Impossible"); + } + ToyNode *n4=new ToyNode("T4"); + InputPort *i41=n4->edAddInputPort("i41",tc_double); + InputPort *i42=n4->edAddInputPort("i42",tc_double); + OutputPort *o41=n4->edAddOutputPort("o41",tc_double); + i42->edInit(3.); + mySwitch->edSetNode(2,n4); + graph->edAddLink(o1,i41); + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)o31)->get()->getDoubleValue(),19., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(((OutputToyPort*)o21)->get(),(Any *)0); + CPPUNIT_ASSERT_EQUAL(((OutputToyPort*)o41)->get(),(Any *)0); + CPPUNIT_ASSERT_EQUAL(mySwitch->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + InputPort *i12=n1->edAddInputPort("i12",tc_double); + i12->edInit(17.); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)o41)->get()->getDoubleValue(),37., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(((OutputToyPort*)o21)->get(),(Any *)0); + CPPUNIT_ASSERT_EQUAL(((OutputToyPort*)o31)->get(),(Any *)0); + CPPUNIT_ASSERT_EQUAL(mySwitch->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + delete graph; +} + +void EngineIntegrationTest::testSwitch2() +{ + TypeCode *tc_double = Runtime::_tc_double; + TypeCode *tc_int = Runtime::_tc_int; + Bloc *graph=new Bloc("Graph"); + + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",tc_double); + i11->edInit(17.); + OutputPort *o1=n1->edAddOutputPort("o1",tc_double); + graph->edAddChild(n1); + + Switch *mySwitch=new Switch("mySwitch"); + graph->edAddChild(mySwitch); + graph->edAddCFLink(n1,mySwitch); + + ToyNode *n2=new ToyNode("T2"); + InputPort *i21=n2->edAddInputPort("i21",tc_double); + InputPort *i22=n2->edAddInputPort("i22",tc_double); + OutputPort *o21=n2->edAddOutputPort("o21",tc_double); + i22->edInit(1.); + mySwitch->edSetNode(0,n2); + graph->edAddLink(o1,i21); + graph->edAddLink(n1->edGetNbOfInputsOutputPort(),mySwitch->edGetConditionPort()); + ToyNode *n3=new ToyNode("T3"); + InputPort *i31=n3->edAddInputPort("i31",tc_double); + InputPort *i32=n3->edAddInputPort("i32",tc_double); + OutputPort *o31=n3->edAddOutputPort("o31",tc_double); + i32->edInit(2.); + mySwitch->edSetNode(1,n3); + graph->edAddLink(o1,i31); + ToyNode *n4=new ToyNode("T4"); + InputPort *i41=n4->edAddInputPort("i41",tc_double); + InputPort *i42=n4->edAddInputPort("i42",tc_double); + OutputPort *o41=n4->edAddOutputPort("o41",tc_double); + i42->edInit(3.); + mySwitch->edSetNode(2,n4); + graph->edAddLink(o1,i41); + LimitNode *l1=new LimitNode("L1"); + l1->getEntry()->edInit(13.); + l1->setLimit(100.); + graph->edAddChild(l1); + // + Bloc *inLoop=new Bloc("inLoop"); + ToyNode *nn2=new ToyNode("TT2"); + inLoop->edAddChild(nn2); + InputPort *ii21=nn2->edAddInputPort("ii1",tc_double); + ii21->edInit(7.); + InputPort *ii22=nn2->edAddInputPort("ii2",tc_double); + OutputPort *oo21=nn2->edAddOutputPort("oo1",tc_double); + LimitNode *l2=new LimitNode("L2"); + OutputPort *ool2s=l2->getSwitchPort(); + l2->setLimit(100.); + inLoop->edAddChild(nn2); + inLoop->edAddChild(l2); + WhileLoop *whileLoop=new WhileLoop("MyWhile"); + whileLoop->edSetNode(inLoop); + graph->edAddChild(whileLoop); + graph->edAddCFLink(l1,whileLoop); + graph->edAddLink(o21,ii22); + graph->edAddLink(o31,ii22); + graph->edAddLink(o41,ii22); + inLoop->edAddCFLink(nn2,l2); + graph->edAddCFLink(mySwitch,whileLoop); + inLoop->edAddLink(oo21,l2->getEntry()); + inLoop->edAddLink(l2->getCounterPort(),ii21); + graph->edAddLink(l1->getSwitchPort(),whileLoop->edGetConditionPort()); + graph->edAddLink(l2->getSwitchPort(),whileLoop->edGetConditionPort()); + mySwitch->checkConsistency(); + graph->edRemoveLink(o31,ii22); + try + { + mySwitch->checkConsistency(); + CPPUNIT_ASSERT(0); + } + catch(Exception& e) + { + CPPUNIT_ASSERT(std::string(e.what())=="CollectorSwOutPort::checkCompletenessOfCases : For link to ii2 of node TT2 the cases of switch node named mySwitch do not define links for following cases ids :1 "); + } + graph->edRemoveLink(o41,ii22); + try + { + mySwitch->checkConsistency(); + CPPUNIT_ASSERT(0); + } + catch(Exception& e) + { + CPPUNIT_ASSERT(std::string(e.what())=="CollectorSwOutPort::checkCompletenessOfCases : For link to ii2 of node TT2 the cases of switch node named mySwitch do not define links for following cases ids :1 2 "); + } + graph->edAddLink(o31,ii22); + graph->edAddLink(o41,ii22); + mySwitch->checkConsistency(); + Executor exe; + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)l2->getCounterPort())->get()->getDoubleValue(),161., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,whileLoop->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(whileLoop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)l2->getCounterPort())->get()->getDoubleValue(),161., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,whileLoop->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(whileLoop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + //default + ToyNode *n5=new ToyNode("T5"); + InputPort *i51=n5->edAddInputPort("i51",tc_double); + InputPort *i52=n5->edAddInputPort("i52",tc_double); + OutputPort *o51=n5->edAddOutputPort("o51",tc_double); + i52->edInit(4.); + mySwitch->edSetDefaultNode(n5); + graph->edAddLink(o1,i51); + try + { + mySwitch->checkConsistency(); + CPPUNIT_ASSERT(0); + } + catch(Exception& e) + { + CPPUNIT_ASSERT(std::string(e.what())=="CollectorSwOutPort::checkCompletenessOfCases : For link to ii2 of node TT2 the cases of switch node named mySwitch do not define links for following cases ids :default "); + } + graph->edAddLink(o51,ii22); + mySwitch->checkConsistency(); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)l2->getCounterPort())->get()->getDoubleValue(),161., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,whileLoop->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(whileLoop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)l2->getCounterPort())->get()->getDoubleValue(),161., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,whileLoop->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(whileLoop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + try + { + mySwitch->edReleaseCase(4); + CPPUNIT_ASSERT(0); + } + catch(Exception& e) + { + CPPUNIT_ASSERT(std::string(e.what())=="Switch::edReleaseCase : the case # 4 is not set yet."); + } + mySwitch->edReleaseCase(1); + mySwitch->checkConsistency(); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)l2->getCounterPort())->get()->getDoubleValue(),175., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,whileLoop->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(whileLoop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)l2->getCounterPort())->get()->getDoubleValue(),175., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,whileLoop->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(whileLoop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + //now test when unexpected value is recieved and no default node specifies + mySwitch->edReleaseDefaultNode(); + mySwitch->checkConsistency(); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(whileLoop->getState(),YACS::FAILED); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::FAILED); + CPPUNIT_ASSERT_EQUAL(mySwitch->getState(),YACS::ERROR); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(whileLoop->getState(),YACS::FAILED); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::FAILED); + CPPUNIT_ASSERT_EQUAL(mySwitch->getState(),YACS::ERROR); + //retrieving back state + mySwitch->edSetDefaultNode(n5); + graph->edAddLink(o1,i51); + try + { + mySwitch->checkConsistency(); + CPPUNIT_ASSERT(0); + } + catch(Exception& e) + { + CPPUNIT_ASSERT(std::string(e.what())=="CollectorSwOutPort::checkCompletenessOfCases : For link to ii2 of node TT2 the cases of switch node named mySwitch do not define links for following cases ids :default "); + } + graph->edAddLink(o51,ii22); + mySwitch->checkConsistency(); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)l2->getCounterPort())->get()->getDoubleValue(),175., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,whileLoop->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(whileLoop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)l2->getCounterPort())->get()->getDoubleValue(),175., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,whileLoop->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(whileLoop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + //and finally retrieving initial state + mySwitch->edSetNode(1,n3); + graph->edAddLink(o1,i31); + graph->edAddLink(o31,ii22); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)l2->getCounterPort())->get()->getDoubleValue(),161., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,whileLoop->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(whileLoop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)l2->getCounterPort())->get()->getDoubleValue(),161., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,whileLoop->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(whileLoop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + Bloc *clonedGraph=(Bloc *)graph->clone(0); + delete graph; + Executor exe2; + exe2.RunW(clonedGraph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(((OutputToyPort*)clonedGraph->getOutPort("MyWhile.inLoop.L2.SwitchPort2"))->get()->getDoubleValue(),161., DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(3,((WhileLoop *)clonedGraph->getChildByName("MyWhile"))->getNbOfTurns()); + CPPUNIT_ASSERT_EQUAL(((WhileLoop *)clonedGraph->getChildByName("MyWhile"))->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(clonedGraph->getState(),YACS::DONE); + delete clonedGraph; +} + +/** + * multi switch inclusion - link update + */ +void EngineIntegrationTest::testSwitch3() +{ + Bloc *graph=new Bloc("Graph"); + Switch *mySwitch1=new Switch("mySwitch1"); + graph->edAddChild(mySwitch1); + Switch *mySwitch2=new Switch("mySwitch2"); + mySwitch1->edSetNode(2,mySwitch2); + ToyNode *n1=new ToyNode("T1"); Bloc *blocForT1=new Bloc("blocForT1"); blocForT1->edAddChild(n1); + ToyNode *n2=new ToyNode("T2"); Bloc *blocForT2=new Bloc("blocForT2"); blocForT2->edAddChild(n2); mySwitch1->edSetNode(3,blocForT2);graph->edAddChild(blocForT1); n2->edAddInputPort("i22",Runtime::_tc_double)->edInit(2.); + ToyNode *n3=new ToyNode("T3"); mySwitch2->edSetNode(2,n3); n3->edAddInputPort("i32",Runtime::_tc_double)->edInit(3.); + ToyNode *n4=new ToyNode("T4"); Bloc *blocForT4=new Bloc("blocForT4"); blocForT4->edAddChild(n4); mySwitch2->edSetNode(5,blocForT4); n4->edAddInputPort("i42",Runtime::_tc_double)->edInit(4.); + ToyNode *n5=new ToyNode("T5"); mySwitch2->edSetNode(8,n5); n5->edAddInputPort("i52",Runtime::_tc_double)->edInit(5.); + ToyNode *n6=new ToyNode("T6"); graph->edAddChild(n6); + graph->edAddCFLink(blocForT1,mySwitch1); + graph->edAddCFLink(mySwitch1,n6); + mySwitch2->getInputPort("select")->edInit(5); + mySwitch1->getInputPort("select")->edInit(2); + InputPort *i11=n1->edAddInputPort("i11",Runtime::_tc_double); OutputPort *o11=n1->edAddOutputPort("o11",Runtime::_tc_double); + InputPort *i21=n2->edAddInputPort("i21",Runtime::_tc_double); OutputPort *o21=n2->edAddOutputPort("o21",Runtime::_tc_double); + InputPort *i31=n3->edAddInputPort("i31",Runtime::_tc_double); OutputPort *o31=n3->edAddOutputPort("o31",Runtime::_tc_double); + InputPort *i41=n4->edAddInputPort("i41",Runtime::_tc_double); OutputPort *o41=n4->edAddOutputPort("o41",Runtime::_tc_double); + InputPort *i51=n5->edAddInputPort("i51",Runtime::_tc_double); OutputPort *o51=n5->edAddOutputPort("o51",Runtime::_tc_double); + InputPort *i61=n6->edAddInputPort("i61",Runtime::_tc_double); OutputPort *o61=n6->edAddOutputPort("o61",Runtime::_tc_double); + i11->edInit(17.); + graph->edAddLink(o11,i21); graph->edAddLink(o11,i31); graph->edAddLink(o11,i41); graph->edAddLink(o11,i51); + graph->edAddLink(o21,i61); + graph->edAddLink(o31,i61); + graph->edAddLink(o41,i61); + graph->edAddLink(o51,i61); + mySwitch1->checkConsistency(); + mySwitch2->checkConsistency(); + CPPUNIT_ASSERT_EQUAL(1,n6->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(1,i61->edGetNumberOfLinks());// <-- important + CPPUNIT_ASSERT_EQUAL(4,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i31->edGetNumberOfLinks()); + graph->edRemoveLink(o21,i61); + CPPUNIT_ASSERT_EQUAL(1,i61->edGetNumberOfLinks());// <-- important + CPPUNIT_ASSERT_EQUAL(0,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i31->edGetNumberOfLinks()); + graph->edAddLink(o21,i61); + graph->edRemoveLink(o31,i61); + graph->edRemoveLink(o41,i61); + graph->edRemoveLink(o51,i61); + CPPUNIT_ASSERT_EQUAL(1,i61->edGetNumberOfLinks());// <-- important + graph->edRemoveLink(o21,i61); + CPPUNIT_ASSERT_EQUAL(0,i61->edGetNumberOfLinks());// <-- important + graph->edAddLink(o21,i61); + CPPUNIT_ASSERT_EQUAL(1,i61->edGetNumberOfLinks()); + graph->edAddLink(o41,i61); + CPPUNIT_ASSERT_EQUAL(1,i61->edGetNumberOfLinks()); + try + { + mySwitch2->checkConsistency(); + CPPUNIT_ASSERT(0); + } + catch(Exception& e) + { + CPPUNIT_ASSERT(std::string(e.what())=="CollectorSwOutPort::checkCompletenessOfCases : For link to i61 of node T6 the cases of switch node named mySwitch2 do not define links for following cases ids :2 8 "); + } + graph->edAddLink(o31,i61); + graph->edAddLink(o51,i61); + mySwitch2->checkConsistency(); + CPPUNIT_ASSERT_EQUAL(1,i61->edGetNumberOfLinks()); + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T6.o61"))->get()->getDoubleValue(),21., DBL_PRECISION_COMPARE); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T6.o61"))->get()->getDoubleValue(),21., DBL_PRECISION_COMPARE); + mySwitch1->getInputPort("select")->edInit(3); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T6.o61"))->get()->getDoubleValue(),19., DBL_PRECISION_COMPARE); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T6.o61"))->get()->getDoubleValue(),19., DBL_PRECISION_COMPARE); + delete graph; +} + +void EngineIntegrationTest::testWhileLoop2()//Test of 0 turn of loop +{ + //first test without any link to condition port on start of loop that is to say WhileLoop is considered has while and NOT dowhile. + TypeCode *tc_double = Runtime::_tc_double; + TypeCode *tc_int = Runtime::_tc_int; + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",tc_double); + i11->edInit(3.14); + InputPort *i12=n1->edAddInputPort("i12",tc_double); + i12->edInit(2.78); + OutputPort *o11=n1->edAddOutputPort("o1",tc_double); + ToyNode *n2=new ToyNode("T2"); + InputPort *i21=n2->edAddInputPort("i1",tc_double); + InputPort *i22=n2->edAddInputPort("i2",tc_double); + i22->edInit(22.1); + OutputPort *o21=n2->edAddOutputPort("o1",tc_double); + ToyNode *n3=new ToyNode("T3"); + InputPort *i31=n3->edAddInputPort("i1",tc_double); + OutputPort *o31=n3->edAddOutputPort("o1",tc_double); + LimitNode *l2=new LimitNode("L2"); + OutputPort *ol2s=l2->getSwitchPort(); + l2->setLimit(100.); + Bloc *titi=new Bloc("titi"); + titi->edAddChild(n2); + titi->edAddChild(l2); + WhileLoop *loop=new WhileLoop("toto"); + loop->edSetNode(titi); + Bloc *graph=new Bloc("Graph"); + graph->edAddChild(loop); + graph->edAddChild(n1); + graph->edAddChild(n3); + graph->edAddCFLink(n1,loop); + graph->edAddCFLink(loop,n3); + titi->edAddCFLink(n2,l2); + graph->edAddLink(o11,i21); + graph->edAddLink(o21,l2->getEntry()); + graph->edAddLink(ol2s,loop->edGetConditionPort()); + graph->edAddLink(o21,i21); + graph->edAddLink(o21,i31); + Executor exe; + DEBTRACE("Run graph"); + exe.RunW(graph); + DEBTRACE("After Run graph"); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),72.22, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(), 72.22, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + //Link on conditionPort of while same behaviour as ahead + LimitNode *l1=new LimitNode("L1"); + graph->edAddChild(l1); + OutputPort *ol1s=l1->getSwitchPort(); + l1->setLimit(100.); + l1->getEntry()->edInit(12.); + graph->edAddCFLink(l1,loop); + graph->edAddLink(ol1s,loop->edGetConditionPort()); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),72.22, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),72.22, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + //Now no turn in while loop... + l1->getEntry()->edInit(120.); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::ERROR); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::FAILED); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(l1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::FAILED); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::ERROR); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::FAILED); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(l1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::FAILED); + //like before + l1->getEntry()->edInit(12.); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),72.22, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),72.22, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n2->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + //now 0 turn of loop but no back dependancies + l1->getEntry()->edInit(125.); + graph->edRemoveLink(o21,i31); + graph->edAddLink(o11,i31);//this + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),5.92, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),5.92, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + // + graph->edRemoveChild(l1); + delete l1; + graph->getInputPort("toto.condition")->edInit(false); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),5.92, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),5.92, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + // + graph->getInputPort("toto.condition")->edInit(true); + DEBTRACE("Run graph"); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)graph->getOutputPort("T3.o1"))->get()->getDoubleValue(),5.92, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)l2->getCounterPort())->get()->getDoubleValue(),150.36, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),3); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(graph->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n1->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n3->getState(),YACS::DONE); + delete graph; +} + +void EngineIntegrationTest::testEdInitOnLoops() +{ + ForLoop *loop=new ForLoop("totoloop"); + Bloc *titi=new Bloc("titi"); + ToyNode *n2=new ToyNode("T2"); + titi->edAddChild(n2); + loop->edSetNode(titi); + InputPort *i21=n2->edAddInputPort("i1",Runtime::_tc_double); + InputPort *i22=n2->edAddInputPort("i2",Runtime::_tc_double); + i21->edInit(2.1); + i22->edInit(4.3); + OutputPort *o21=n2->edAddOutputPort("o1",Runtime::_tc_double); + titi->edAddLink(o21,i21); + loop->edGetNbOfTimesInputPort()->edInit(4); + Executor exe; + exe.RunW(loop); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)loop->getOutputPort("titi.T2.o1"))->get()->getDoubleValue(),19.3, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),4); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n2->getState(),YACS::DONE); + exe.RunW(loop); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)loop->getOutputPort("titi.T2.o1"))->get()->getDoubleValue(),19.3, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),4); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n2->getState(),YACS::DONE); + loop->edGetNbOfTimesInputPort()->edInit(5); + exe.RunW(loop); + CPPUNIT_ASSERT_DOUBLES_EQUAL( ((OutputToyPort*)loop->getOutputPort("titi.T2.o1"))->get()->getDoubleValue(),23.6, DBL_PRECISION_COMPARE); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),5); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + CPPUNIT_ASSERT_EQUAL(n2->getState(),YACS::DONE); + loop->edGetNbOfTimesInputPort()->edInit(0); + exe.RunW(loop); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + exe.RunW(loop); + CPPUNIT_ASSERT_EQUAL(loop->getNbOfTurns(),0); + CPPUNIT_ASSERT_EQUAL(loop->getState(),YACS::DONE); + delete loop; +} + +/** + * This test peers at link deletion forwarding for switch + */ +void EngineIntegrationTest::testLinkUpdate1() +{ + Bloc *graph=new Bloc("Graph"); + + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",Runtime::_tc_double); + i11->edInit(17.); + OutputPort *o1=n1->edAddOutputPort("o1",Runtime::_tc_double); + graph->edAddChild(n1); + + Switch *mySwitch=new Switch("mySwitch"); + graph->edAddChild(mySwitch); + graph->edAddCFLink(n1,mySwitch); + + ToyNode *n2=new ToyNode("T2"); + InputPort *i21=n2->edAddInputPort("i21",Runtime::_tc_double); + InputPort *i22=n2->edAddInputPort("i22",Runtime::_tc_double); + OutputPort *o21=n2->edAddOutputPort("o21",Runtime::_tc_double); + OutputPort *o22=n2->edAddOutputPort("o22",Runtime::_tc_double); + i22->edInit(1.); + mySwitch->edSetNode(0,n2); + graph->edAddLink(o1,i21); + graph->edAddLink(n1->edGetNbOfInputsOutputPort(),mySwitch->edGetConditionPort()); + ToyNode *n3=new ToyNode("T3"); + Bloc *Bn3=new Bloc("Bn3"); + Bn3->edAddChild(n3); + InputPort *i31=n3->edAddInputPort("i31",Runtime::_tc_double); + InputPort *i32=n3->edAddInputPort("i32",Runtime::_tc_double); + OutputPort *o31=n3->edAddOutputPort("o31",Runtime::_tc_double); + OutputPort *o32=n3->edAddOutputPort("o32",Runtime::_tc_double); + i32->edInit(2.); + mySwitch->edSetNode(1,Bn3); + graph->edAddLink(o1,i31); + // + ToyNode *n4=new ToyNode("T4"); + InputPort *i41=n4->edAddInputPort("i41",Runtime::_tc_double); + InputPort *i42=n4->edAddInputPort("i42",Runtime::_tc_double); + OutputPort *o41=n4->edAddOutputPort("o41",Runtime::_tc_double); + i42->edInit(3.14); + graph->edAddChild(n4); + graph->edAddCFLink(mySwitch,n4); + graph->edAddLink(o21,i41); + graph->edAddLink(o31,i41); + mySwitch->checkConsistency(); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks());// <-- important + graph->edRemoveLink(o21,i41); + CPPUNIT_ASSERT_EQUAL(0,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks());// <-- important + graph->edRemoveLink(o31,i41);//normally implies collector inputport deletion + CPPUNIT_ASSERT_EQUAL(0,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i41->edGetNumberOfLinks());// <-- important + //Test on forward update for deletion + graph->edAddLink(o21,i41); + graph->edAddLink(o31,i41); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + n2->edRemovePort(o21); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + n3->edRemovePort(o31); + CPPUNIT_ASSERT_EQUAL(0,i41->edGetNumberOfLinks());// <-- important + o21=n2->edAddOutputPort("o21",Runtime::_tc_double); + o31=n3->edAddOutputPort("o31",Runtime::_tc_double); + // + graph->edAddLink(o21,i41); + graph->edAddLink(o31,i41); + mySwitch->checkConsistency(); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + ToyNode *n5=new ToyNode("T5"); + InputPort *i51=n5->edAddInputPort("i51",Runtime::_tc_double); + InputPort *i52=n5->edAddInputPort("i52",Runtime::_tc_double); + OutputPort *o51=n5->edAddOutputPort("o51",Runtime::_tc_double); + OutputPort *o52=n5->edAddOutputPort("o52",Runtime::_tc_double); + i52->edInit(7.); + mySwitch->edSetNode(17,n5); + graph->edAddLink(o1,i51); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,o51->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + graph->edAddLink(o51,i41); + mySwitch->checkConsistency(); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o51->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + graph->edRemoveLink(o31,i41); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o51->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + graph->edAddLink(o31,i41); + mySwitch->checkConsistency(); + graph->edAddLink(o22,i42); + graph->edAddLink(o32,i42); + graph->edAddLink(o52,i42); + mySwitch->checkConsistency(); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o51->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + ToyNode *n6=new ToyNode("T6"); + InputPort *i61=n6->edAddInputPort("i61",Runtime::_tc_double); + InputPort *i62=n6->edAddInputPort("i62",Runtime::_tc_double); + OutputPort *o61=n6->edAddOutputPort("o61",Runtime::_tc_double); + graph->edAddChild(n6); + graph->edAddCFLink(mySwitch,n6); + CPPUNIT_ASSERT_EQUAL(1,n6->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(0,i62->edGetNumberOfLinks()); + graph->edAddLink(o22,i62); + CPPUNIT_ASSERT_EQUAL(1,i62->edGetNumberOfLinks()); + graph->edAddLink(o32,i62); + graph->edAddLink(o52,i62); + CPPUNIT_ASSERT_EQUAL(2,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i62->edGetNumberOfLinks()); + graph->edRemoveChild(n6);//normally implies collector inputport deletion + mySwitch->checkConsistency(); + CPPUNIT_ASSERT_EQUAL(1,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i62->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,n6->getInGate()->getNumberOfBackLinks()); + graph->edAddChild(n6); + graph->edAddCFLink(mySwitch,n6); + CPPUNIT_ASSERT_EQUAL(1,n6->getInGate()->getNumberOfBackLinks()); + graph->edAddLink(o22,i62); + CPPUNIT_ASSERT_EQUAL(1,i62->edGetNumberOfLinks()); + graph->edAddLink(o32,i62); + graph->edAddLink(o52,i62); + CPPUNIT_ASSERT_EQUAL(2,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i62->edGetNumberOfLinks()); + n6->edRemovePort(i61); + CPPUNIT_ASSERT_EQUAL(1,n6->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(2,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i62->edGetNumberOfLinks()); + n6->edRemovePort(i62);//normally implies collector inputport deletion + CPPUNIT_ASSERT_EQUAL(1,n6->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(1,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + graph->edRemoveLink(o32,i42); + CPPUNIT_ASSERT_EQUAL(1,n6->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(1,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + n4->edRemovePort(i42);//normally implies collector inputport deletion + CPPUNIT_ASSERT_EQUAL(0,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,o32->edGetNumberOfOutLinks()); + //few forward link updates + CPPUNIT_ASSERT_EQUAL(1,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i31->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i51->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(3,o1->edGetNumberOfOutLinks()); + n1->edRemovePort(o1); + CPPUNIT_ASSERT_EQUAL(0,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i31->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i51->edGetNumberOfLinks()); + delete graph; +} + +/** + * Idem testLinkUpdate1 but for DS. + */ +void EngineIntegrationTest::testLinkUpdate1DS() +{ + Bloc *graph=new Bloc("Graph"); + + ToyNode *n1=new ToyNode("T1"); + InputDataStreamPort *i11=n1->edAddInputDataStreamPort("i11",Runtime::_tc_double); + OutputDataStreamPort *o1=n1->edAddOutputDataStreamPort("o1",Runtime::_tc_double); + graph->edAddChild(n1); + + Switch *mySwitch=new Switch("mySwitch"); + graph->edAddChild(mySwitch); + graph->edAddCFLink(n1,mySwitch); + + ToyNode *n2=new ToyNode("T2"); + InputDataStreamPort *i21=n2->edAddInputDataStreamPort("i21",Runtime::_tc_double); + InputDataStreamPort *i22=n2->edAddInputDataStreamPort("i22",Runtime::_tc_double); + OutputDataStreamPort *o21=n2->edAddOutputDataStreamPort("o21",Runtime::_tc_double); + OutputDataStreamPort *o22=n2->edAddOutputDataStreamPort("o22",Runtime::_tc_double); + mySwitch->edSetNode(0,n2); + graph->edAddLink(o1,i21); + graph->edAddLink(n1->edGetNbOfInputsOutputPort(),mySwitch->edGetConditionPort()); + ToyNode *n3=new ToyNode("T3"); + Bloc *Bn3=new Bloc("Bn3"); + Bn3->edAddChild(n3); + InputDataStreamPort *i31=n3->edAddInputDataStreamPort("i31",Runtime::_tc_double); + InputDataStreamPort *i32=n3->edAddInputDataStreamPort("i32",Runtime::_tc_double); + OutputDataStreamPort *o31=n3->edAddOutputDataStreamPort("o31",Runtime::_tc_double); + OutputDataStreamPort *o32=n3->edAddOutputDataStreamPort("o32",Runtime::_tc_double); + mySwitch->edSetNode(1,Bn3); + graph->edAddLink(o1,i31); + // + ToyNode *n4=new ToyNode("T4"); + InputDataStreamPort *i41=n4->edAddInputDataStreamPort("i41",Runtime::_tc_double); + InputDataStreamPort *i42=n4->edAddInputDataStreamPort("i42",Runtime::_tc_double); + OutputDataStreamPort *o41=n4->edAddOutputDataStreamPort("o41",Runtime::_tc_double); + graph->edAddChild(n4); + graph->edAddCFLink(mySwitch,n4); + graph->edAddLink(o21,i41); + graph->edAddLink(o31,i41); + mySwitch->checkConsistency(); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks());// <-- important + graph->edRemoveLink(o21,i41); + CPPUNIT_ASSERT_EQUAL(0,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks());// <-- important + graph->edRemoveLink(o31,i41);//normally implies collector inputport deletion + CPPUNIT_ASSERT_EQUAL(0,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i41->edGetNumberOfLinks());// <-- important + //Test on forward update for deletion + graph->edAddLink(o21,i41); + graph->edAddLink(o31,i41); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + n2->edRemovePort(o21); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + n3->edRemovePort(o31); + CPPUNIT_ASSERT_EQUAL(0,i41->edGetNumberOfLinks());// <-- important + o21=n2->edAddOutputDataStreamPort("o21",Runtime::_tc_double); + o31=n3->edAddOutputDataStreamPort("o31",Runtime::_tc_double); + // + graph->edAddLink(o21,i41); + graph->edAddLink(o31,i41); + mySwitch->checkConsistency(); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + ToyNode *n5=new ToyNode("T5"); + InputDataStreamPort *i51=n5->edAddInputDataStreamPort("i51",Runtime::_tc_double); + InputDataStreamPort *i52=n5->edAddInputDataStreamPort("i52",Runtime::_tc_double); + OutputDataStreamPort *o51=n5->edAddOutputDataStreamPort("o51",Runtime::_tc_double); + OutputDataStreamPort *o52=n5->edAddOutputDataStreamPort("o52",Runtime::_tc_double); + mySwitch->edSetNode(17,n5); + graph->edAddLink(o1,i51); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,o51->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + graph->edAddLink(o51,i41); + mySwitch->checkConsistency(); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o51->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + graph->edRemoveLink(o31,i41); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o51->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + graph->edAddLink(o31,i41); + mySwitch->checkConsistency(); + graph->edAddLink(o22,i42); + graph->edAddLink(o32,i42); + graph->edAddLink(o52,i42); + mySwitch->checkConsistency(); + CPPUNIT_ASSERT_EQUAL(1,o21->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o31->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o51->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i41->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + ToyNode *n6=new ToyNode("T6"); + InputDataStreamPort *i61=n6->edAddInputDataStreamPort("i61",Runtime::_tc_double); + InputDataStreamPort *i62=n6->edAddInputDataStreamPort("i62",Runtime::_tc_double); + OutputDataStreamPort *o61=n6->edAddOutputDataStreamPort("o61",Runtime::_tc_double); + graph->edAddChild(n6); + graph->edAddCFLink(mySwitch,n6); + CPPUNIT_ASSERT_EQUAL(1,n6->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(0,i62->edGetNumberOfLinks()); + graph->edAddLink(o22,i62); + CPPUNIT_ASSERT_EQUAL(1,i62->edGetNumberOfLinks()); + graph->edAddLink(o32,i62); + graph->edAddLink(o52,i62); + CPPUNIT_ASSERT_EQUAL(2,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i62->edGetNumberOfLinks()); + graph->edRemoveChild(n6);//normally implies collector inputport deletion + mySwitch->checkConsistency(); + CPPUNIT_ASSERT_EQUAL(1,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i62->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,n6->getInGate()->getNumberOfBackLinks()); + graph->edAddChild(n6); + graph->edAddCFLink(mySwitch,n6); + CPPUNIT_ASSERT_EQUAL(1,n6->getInGate()->getNumberOfBackLinks()); + graph->edAddLink(o22,i62); + CPPUNIT_ASSERT_EQUAL(1,i62->edGetNumberOfLinks()); + graph->edAddLink(o32,i62); + graph->edAddLink(o52,i62); + CPPUNIT_ASSERT_EQUAL(2,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i62->edGetNumberOfLinks()); + n6->edRemovePort(i61); + CPPUNIT_ASSERT_EQUAL(1,n6->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(2,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i62->edGetNumberOfLinks()); + n6->edRemovePort(i62);//normally implies collector inputport deletion + CPPUNIT_ASSERT_EQUAL(1,n6->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(1,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + graph->edRemoveLink(o32,i42); + CPPUNIT_ASSERT_EQUAL(1,n6->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(1,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,o32->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o52->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i42->edGetNumberOfLinks()); + n4->edRemovePort(i42);//normally implies collector inputport deletion + CPPUNIT_ASSERT_EQUAL(0,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,o32->edGetNumberOfOutLinks()); + //few forward link updates + CPPUNIT_ASSERT_EQUAL(1,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i31->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i51->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(3,o1->edGetNumberOfOutLinks()); + n1->edRemovePort(o1); + CPPUNIT_ASSERT_EQUAL(0,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i31->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i51->edGetNumberOfLinks()); + delete graph; +} + +// Less complex than testLinkUpdate1 only for Blocs update +void EngineIntegrationTest::testLinkUpdate2() +{ + Bloc *graph=new Bloc("Graph"); + + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",Runtime::_tc_double); + InputPort *i12=n1->edAddInputPort("i12",Runtime::_tc_double); + InputPort *i13=n1->edAddInputPort("i13",Runtime::_tc_double); + InputPort *i14=n1->edAddInputPort("i14",Runtime::_tc_double); + OutputPort *o11=n1->edAddOutputPort("o11",Runtime::_tc_double); + OutputPort *o12=n1->edAddOutputPort("o12",Runtime::_tc_double); + OutputPort *o13=n1->edAddOutputPort("o13",Runtime::_tc_double); + graph->edAddChild(n1); + // + Bloc *toto=new Bloc("toto"); + graph->edAddChild(toto); + graph->edAddCFLink(n1,toto); + ToyNode *n2=new ToyNode("T2"); + toto->edAddChild(n2); + InputPort *i21=n2->edAddInputPort("i21",Runtime::_tc_double); + InputPort *i22=n2->edAddInputPort("i22",Runtime::_tc_double); + InputPort *i23=n2->edAddInputPort("i23",Runtime::_tc_double); + OutputPort *o21=n2->edAddOutputPort("o21",Runtime::_tc_double); + OutputPort *o22=n2->edAddOutputPort("o22",Runtime::_tc_double); + OutputPort *o23=n2->edAddOutputPort("o23",Runtime::_tc_double); + ToyNode *n3=new ToyNode("T3"); + toto->edAddChild(n3); + InputPort *i31=n3->edAddInputPort("i31",Runtime::_tc_double); + InputPort *i32=n3->edAddInputPort("i32",Runtime::_tc_double); + InputPort *i33=n3->edAddInputPort("i33",Runtime::_tc_double); + InputPort *i34=n3->edAddInputPort("i34",Runtime::_tc_double); + OutputPort *o31=n3->edAddOutputPort("o31",Runtime::_tc_double); + OutputPort *o32=n3->edAddOutputPort("o32",Runtime::_tc_double); + OutputPort *o33=n3->edAddOutputPort("o33",Runtime::_tc_double); + Bloc *totoSub=new Bloc("totoSub"); + toto->edAddChild(totoSub); + toto->edAddCFLink(n2,totoSub); + toto->edAddCFLink(totoSub,n3); + ToyNode *n4=new ToyNode("T4"); + totoSub->edAddChild(n4); + InputPort *i41=n4->edAddInputPort("i41",Runtime::_tc_double); + InputPort *i42=n4->edAddInputPort("i42",Runtime::_tc_double); + InputPort *i43=n4->edAddInputPort("i43",Runtime::_tc_double); + OutputPort *o41=n4->edAddOutputPort("o41",Runtime::_tc_double); + OutputPort *o44=n4->edAddOutputPort("o44",Runtime::_tc_double); + OutputPort *o43=n4->edAddOutputPort("o43",Runtime::_tc_double); + ToyNode *n5=new ToyNode("T5"); + totoSub->edAddChild(n5); + totoSub->edAddCFLink(n4,n5); + InputPort *i51=n5->edAddInputPort("i51",Runtime::_tc_double); + InputPort *i52=n5->edAddInputPort("i52",Runtime::_tc_double); + InputPort *i53=n5->edAddInputPort("i53",Runtime::_tc_double); + InputPort *i54=n5->edAddInputPort("i54",Runtime::_tc_double); + OutputPort *o51=n5->edAddOutputPort("o51",Runtime::_tc_double); + OutputPort *o52=n5->edAddOutputPort("o52",Runtime::_tc_double); + OutputPort *o53=n5->edAddOutputPort("o53",Runtime::_tc_double); + ToyNode *n6=new ToyNode("T6"); + totoSub->edAddChild(n6); + totoSub->edAddCFLink(n4,n6); + InputPort *i61=n6->edAddInputPort("i61",Runtime::_tc_double); + InputPort *i62=n6->edAddInputPort("i62",Runtime::_tc_double); + InputPort *i63=n6->edAddInputPort("i63",Runtime::_tc_double); + OutputPort *o61=n6->edAddOutputPort("o61",Runtime::_tc_double); + OutputPort *o62=n6->edAddOutputPort("o62",Runtime::_tc_double); + ToyNode *n7=new ToyNode("T7"); + totoSub->edAddChild(n7); + totoSub->edAddCFLink(n6,n7); + totoSub->edAddCFLink(n5,n7); + InputPort *i71=n7->edAddInputPort("i71",Runtime::_tc_double); + InputPort *i72=n7->edAddInputPort("i72",Runtime::_tc_double); + InputPort *i73=n7->edAddInputPort("i73",Runtime::_tc_double); + OutputPort *o71=n7->edAddOutputPort("o71",Runtime::_tc_double); + OutputPort *o72=n7->edAddOutputPort("o72",Runtime::_tc_double); + // + Bloc *titi=new Bloc("titi"); + ToyNode *n8=new ToyNode("T8"); + graph->edAddChild(titi); + titi->edAddChild(n8); + InputPort *i81=n8->edAddInputPort("i81",Runtime::_tc_double); + InputPort *i82=n8->edAddInputPort("i82",Runtime::_tc_double); + InputPort *i83=n8->edAddInputPort("i83",Runtime::_tc_double); + OutputPort *o81=n8->edAddOutputPort("o81",Runtime::_tc_double); + OutputPort *o82=n8->edAddOutputPort("o82",Runtime::_tc_double); + OutputDataStreamPort *o83=n8->edAddOutputDataStreamPort("o83",Runtime::_tc_double); + graph->edAddCFLink(toto,titi); + ToyNode *n9=new ToyNode("T9"); + graph->edAddChild(n9); + graph->edAddCFLink(toto,n9); + InputPort *i91=n9->edAddInputPort("i91",Runtime::_tc_double); + InputPort *i92=n9->edAddInputPort("i92",Runtime::_tc_double); + InputPort *i93=n9->edAddInputPort("i93",Runtime::_tc_double); + OutputPort *o91=n9->edAddOutputPort("o91",Runtime::_tc_double); + OutputPort *o92=n9->edAddOutputPort("o92",Runtime::_tc_double); + // Let's test links updates ... + graph->edAddLink(o61,i81); + graph->edAddLink(o61,i72); + graph->edAddLink(o61,i92); + graph->edAddLink(o61,i33); + graph->edAddLink(o12,i21); graph->edAddLink(o12,i31); graph->edAddLink(o12,i71); graph->edAddLink(o12,i82); graph->edAddLink(o12,i91); + CPPUNIT_ASSERT_EQUAL(5,o12->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i31->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i71->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i82->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i91->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i32->edGetNumberOfLinks()); + //Test on link throw + try + { + graph->edAddLink(o83,i51); + CPPUNIT_ASSERT(0); + } + catch(Exception& e) + { + CPPUNIT_ASSERT(string(e.what())=="ComposedNode::checkLinkPossibility : Request for cross protocol link impossible."); + } + // + CPPUNIT_ASSERT_EQUAL(4,o61->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i81->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i72->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i92->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i33->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i32->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(2,(int)toto->getSetOfLinksLeavingCurrentScope().size()); + CPPUNIT_ASSERT_EQUAL(3,(int)totoSub->getSetOfLinksLeavingCurrentScope().size()); + CPPUNIT_ASSERT_EQUAL(1,n3->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(1,titi->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(0,n8->getInGate()->getNumberOfBackLinks()); + graph->edRemoveChild(toto); + CPPUNIT_ASSERT_EQUAL(2,o12->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i31->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i71->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i82->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i91->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i32->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,n3->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(0,titi->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(0,n8->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(2,o61->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i81->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i72->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i92->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i33->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i32->edGetNumberOfLinks()); + toto->edRemoveChild(totoSub); + CPPUNIT_ASSERT_EQUAL(0,n3->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(0,titi->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(0,n8->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(1,o61->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i81->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i72->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i92->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i33->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i32->edGetNumberOfLinks()); + delete toto; + delete totoSub; + // + delete graph; +} + +/** + *idem testLinkUpdate2 but with DS + */ +void EngineIntegrationTest::testLinkUpdate2DS() +{ + Bloc *graph=new Bloc("Graph"); + + ToyNode *n1=new ToyNode("T1"); + InputDataStreamPort *i11=n1->edAddInputDataStreamPort("i11",Runtime::_tc_double); + InputDataStreamPort *i12=n1->edAddInputDataStreamPort("i12",Runtime::_tc_double); + InputDataStreamPort *i13=n1->edAddInputDataStreamPort("i13",Runtime::_tc_double); + InputDataStreamPort *i14=n1->edAddInputDataStreamPort("i14",Runtime::_tc_double); + OutputDataStreamPort *o11=n1->edAddOutputDataStreamPort("o11",Runtime::_tc_double); + OutputDataStreamPort *o12=n1->edAddOutputDataStreamPort("o12",Runtime::_tc_double); + OutputDataStreamPort *o13=n1->edAddOutputDataStreamPort("o13",Runtime::_tc_double); + graph->edAddChild(n1); + // + Bloc *toto=new Bloc("toto"); + graph->edAddChild(toto); + graph->edAddCFLink(n1,toto); + ToyNode *n2=new ToyNode("T2"); + toto->edAddChild(n2); + InputDataStreamPort *i21=n2->edAddInputDataStreamPort("i21",Runtime::_tc_double); + InputDataStreamPort *i22=n2->edAddInputDataStreamPort("i22",Runtime::_tc_double); + InputDataStreamPort *i23=n2->edAddInputDataStreamPort("i23",Runtime::_tc_double); + OutputDataStreamPort *o21=n2->edAddOutputDataStreamPort("o21",Runtime::_tc_double); + OutputDataStreamPort *o22=n2->edAddOutputDataStreamPort("o22",Runtime::_tc_double); + OutputDataStreamPort *o23=n2->edAddOutputDataStreamPort("o23",Runtime::_tc_double); + ToyNode *n3=new ToyNode("T3"); + toto->edAddChild(n3); + InputDataStreamPort *i31=n3->edAddInputDataStreamPort("i31",Runtime::_tc_double); + InputDataStreamPort *i32=n3->edAddInputDataStreamPort("i32",Runtime::_tc_double); + InputDataStreamPort *i33=n3->edAddInputDataStreamPort("i33",Runtime::_tc_double); + InputDataStreamPort *i34=n3->edAddInputDataStreamPort("i34",Runtime::_tc_double); + OutputDataStreamPort *o31=n3->edAddOutputDataStreamPort("o31",Runtime::_tc_double); + OutputDataStreamPort *o32=n3->edAddOutputDataStreamPort("o32",Runtime::_tc_double); + OutputDataStreamPort *o33=n3->edAddOutputDataStreamPort("o33",Runtime::_tc_double); + Bloc *totoSub=new Bloc("totoSub"); + toto->edAddChild(totoSub); + toto->edAddCFLink(n2,totoSub); + toto->edAddCFLink(totoSub,n3); + ToyNode *n4=new ToyNode("T4"); + totoSub->edAddChild(n4); + InputDataStreamPort *i41=n4->edAddInputDataStreamPort("i41",Runtime::_tc_double); + InputDataStreamPort *i42=n4->edAddInputDataStreamPort("i42",Runtime::_tc_double); + InputDataStreamPort *i43=n4->edAddInputDataStreamPort("i43",Runtime::_tc_double); + OutputDataStreamPort *o41=n4->edAddOutputDataStreamPort("o41",Runtime::_tc_double); + OutputDataStreamPort *o44=n4->edAddOutputDataStreamPort("o44",Runtime::_tc_double); + OutputDataStreamPort *o43=n4->edAddOutputDataStreamPort("o43",Runtime::_tc_double); + ToyNode *n5=new ToyNode("T5"); + totoSub->edAddChild(n5); + totoSub->edAddCFLink(n4,n5); + InputDataStreamPort *i51=n5->edAddInputDataStreamPort("i51",Runtime::_tc_double); + InputDataStreamPort *i52=n5->edAddInputDataStreamPort("i52",Runtime::_tc_double); + InputDataStreamPort *i53=n5->edAddInputDataStreamPort("i53",Runtime::_tc_double); + InputDataStreamPort *i54=n5->edAddInputDataStreamPort("i54",Runtime::_tc_double); + OutputDataStreamPort *o51=n5->edAddOutputDataStreamPort("o51",Runtime::_tc_double); + OutputDataStreamPort *o52=n5->edAddOutputDataStreamPort("o52",Runtime::_tc_double); + OutputDataStreamPort *o53=n5->edAddOutputDataStreamPort("o53",Runtime::_tc_double); + ToyNode *n6=new ToyNode("T6"); + totoSub->edAddChild(n6); + totoSub->edAddCFLink(n4,n6); + InputDataStreamPort *i61=n6->edAddInputDataStreamPort("i61",Runtime::_tc_double); + InputDataStreamPort *i62=n6->edAddInputDataStreamPort("i62",Runtime::_tc_double); + InputDataStreamPort *i63=n6->edAddInputDataStreamPort("i63",Runtime::_tc_double); + OutputDataStreamPort *o61=n6->edAddOutputDataStreamPort("o61",Runtime::_tc_double); + OutputDataStreamPort *o62=n6->edAddOutputDataStreamPort("o62",Runtime::_tc_double); + ToyNode *n7=new ToyNode("T7"); + totoSub->edAddChild(n7); + totoSub->edAddCFLink(n6,n7); + totoSub->edAddCFLink(n5,n7); + InputDataStreamPort *i71=n7->edAddInputDataStreamPort("i71",Runtime::_tc_double); + InputDataStreamPort *i72=n7->edAddInputDataStreamPort("i72",Runtime::_tc_double); + InputDataStreamPort *i73=n7->edAddInputDataStreamPort("i73",Runtime::_tc_double); + OutputDataStreamPort *o71=n7->edAddOutputDataStreamPort("o71",Runtime::_tc_double); + OutputDataStreamPort *o72=n7->edAddOutputDataStreamPort("o72",Runtime::_tc_double); + // + Bloc *titi=new Bloc("titi"); + ToyNode *n8=new ToyNode("T8"); + graph->edAddChild(titi); + titi->edAddChild(n8); + InputDataStreamPort *i81=n8->edAddInputDataStreamPort("i81",Runtime::_tc_double); + InputDataStreamPort *i82=n8->edAddInputDataStreamPort("i82",Runtime::_tc_double); + InputDataStreamPort *i83=n8->edAddInputDataStreamPort("i83",Runtime::_tc_double); + OutputDataStreamPort *o81=n8->edAddOutputDataStreamPort("o81",Runtime::_tc_double); + OutputDataStreamPort *o82=n8->edAddOutputDataStreamPort("o82",Runtime::_tc_double); + graph->edAddCFLink(toto,titi); + ToyNode *n9=new ToyNode("T9"); + graph->edAddChild(n9); + graph->edAddCFLink(toto,n9); + InputDataStreamPort *i91=n9->edAddInputDataStreamPort("i91",Runtime::_tc_double); + InputDataStreamPort *i92=n9->edAddInputDataStreamPort("i92",Runtime::_tc_double); + InputDataStreamPort *i93=n9->edAddInputDataStreamPort("i93",Runtime::_tc_double); + OutputDataStreamPort *o91=n9->edAddOutputDataStreamPort("o91",Runtime::_tc_double); + OutputDataStreamPort *o92=n9->edAddOutputDataStreamPort("o92",Runtime::_tc_double); + // Let's test links updates ... + graph->edAddLink(o61,i81); + graph->edAddLink(o61,i72); + graph->edAddLink(o61,i92); + graph->edAddLink(o61,i33); + graph->edAddLink(o12,i21); graph->edAddLink(o12,i31); graph->edAddLink(o12,i71); graph->edAddLink(o12,i82); graph->edAddLink(o12,i91); + CPPUNIT_ASSERT_EQUAL(5,o12->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i31->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i71->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i82->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i91->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i32->edGetNumberOfLinks()); + // + CPPUNIT_ASSERT_EQUAL(4,o61->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i81->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i72->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i92->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i33->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i32->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(2,(int)toto->getSetOfLinksLeavingCurrentScope().size()); + CPPUNIT_ASSERT_EQUAL(3,(int)totoSub->getSetOfLinksLeavingCurrentScope().size()); + CPPUNIT_ASSERT_EQUAL(1,n3->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(1,titi->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(0,n8->getInGate()->getNumberOfBackLinks()); + graph->edRemoveChild(toto); + CPPUNIT_ASSERT_EQUAL(2,o12->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i31->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i71->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i82->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i91->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i32->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,n3->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(0,titi->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(0,n8->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(2,o61->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i81->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i72->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i92->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i33->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i32->edGetNumberOfLinks()); + toto->edRemoveChild(totoSub); + CPPUNIT_ASSERT_EQUAL(0,n3->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(0,titi->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(0,n8->getInGate()->getNumberOfBackLinks()); + CPPUNIT_ASSERT_EQUAL(1,o61->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i81->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i72->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i92->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i33->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i32->edGetNumberOfLinks()); + delete toto; + delete totoSub; + // + delete graph; +} + +/*! + * test of links between 2 loops to simulate coupling. + */ +void EngineIntegrationTest::testInterLoopDFLink() +{ + Bloc *graph=new Bloc("Graph"); + ForLoop *loop1=new ForLoop("loop1"); graph->edAddChild(loop1); + ForLoop *loop2=new ForLoop("loop2"); graph->edAddChild(loop2); + Bloc *b4N1=new Bloc("b4N1"); loop1->edSetNode(b4N1); ToyNode *n1=new ToyNode("T1"); b4N1->edAddChild(n1); + ToyNode *n2=new ToyNode("T2"); loop2->edSetNode(n2); + InputPort *i11=n1->edAddInputPort("i11",Runtime::_tc_double); + InputPort *i21=n2->edAddInputPort("i21",Runtime::_tc_double); + OutputPort *o11=n1->edAddOutputPort("o11",Runtime::_tc_double); + OutputPort *o21=n2->edAddOutputPort("o21",Runtime::_tc_double); + CPPUNIT_ASSERT( graph->edAddLink(o11,i21) ); + CPPUNIT_ASSERT_EQUAL(1,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT( !graph->edAddLink(o11,i21) ); + CPPUNIT_ASSERT_EQUAL(1,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,o11->edGetNumberOfOutLinks()); + set setI1=o11->edSetInPort(); + CPPUNIT_ASSERT(*(setI1.begin()) == i21); + set setO1=i21->edSetOutPort(); + CPPUNIT_ASSERT(*(setO1.begin()) == o11); + graph->edRemoveLink(o11,i21); + CPPUNIT_ASSERT_EQUAL(0,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT( graph->edAddLink(o11,i21) ); + CPPUNIT_ASSERT( !graph->edAddLink(o11,i21) ); + CPPUNIT_ASSERT_EQUAL(1,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,o11->edGetNumberOfOutLinks()); + InputDataStreamPort *i22=n2->edAddInputDataStreamPort("i22",Runtime::_tc_double); + CPPUNIT_ASSERT( graph->edAddLink(o11,i22) );//DF-DS link + CPPUNIT_ASSERT_EQUAL(1,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(2,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i22->edGetNumberOfLinks()); + graph->edRemoveLink(o11,i21); + CPPUNIT_ASSERT_EQUAL(0,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i22->edGetNumberOfLinks()); + graph->edRemoveLink(o11,i22); + CPPUNIT_ASSERT_EQUAL(0,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i22->edGetNumberOfLinks()); + CPPUNIT_ASSERT( graph->edAddLink(o11,i21) ); + CPPUNIT_ASSERT_EQUAL(1,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,o11->edGetNumberOfOutLinks()); + setI1=o11->edSetInPort(); + CPPUNIT_ASSERT(*(setI1.begin()) == i21); + setO1=i21->edSetOutPort(); + CPPUNIT_ASSERT(*(setO1.begin()) == o11); + CPPUNIT_ASSERT( graph->edAddLink(o11,i22) ); + CPPUNIT_ASSERT_EQUAL(1,i21->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(2,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i22->edGetNumberOfLinks()); + ElementaryNode *n=(ElementaryNode *)loop2->edRemoveNode(); + CPPUNIT_ASSERT_EQUAL(0,o11->edGetNumberOfOutLinks()); + // + loop2->edSetNode(n); + CPPUNIT_ASSERT(n==n2); + OutputDataStreamPort *o22=n->edAddOutputDataStreamPort("o22",Runtime::_tc_double); + CPPUNIT_ASSERT( graph->edAddLink(o22,i11) );//DS-DF Link + CPPUNIT_ASSERT_EQUAL(0,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i11->edGetNumberOfLinks()); + graph->edRemoveLink(o22,i11); + CPPUNIT_ASSERT_EQUAL(0,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i11->edGetNumberOfLinks()); + CPPUNIT_ASSERT( graph->edAddLink(o22,i11) ); + CPPUNIT_ASSERT_EQUAL(0,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i11->edGetNumberOfLinks()); + InputDataStreamPort *i13=n1->edAddInputDataStreamPort("i13",Runtime::_tc_double); + CPPUNIT_ASSERT( graph->edAddLink(o22,i13) );//interloop DS-DS Link + CPPUNIT_ASSERT_EQUAL(0,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(2,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i11->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(1,i13->edGetNumberOfLinks()); + graph->edRemoveLink(o22,i13); + CPPUNIT_ASSERT_EQUAL(0,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i11->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i13->edGetNumberOfLinks()); + graph->edRemoveLink(o22,i11); + CPPUNIT_ASSERT_EQUAL(0,o11->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,o22->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i11->edGetNumberOfLinks()); + CPPUNIT_ASSERT_EQUAL(0,i13->edGetNumberOfLinks()); + delete graph; +} + +/*! + * test of links between 2 loops to simulate coupling. + */ +void EngineIntegrationTest::deathTestForLinks() +{ + Bloc *graph=new Bloc("Graph"); + Bloc *b1=new Bloc("b1"); Bloc *b2=new Bloc("b2"); graph->edAddChild(b1); graph->edAddChild(b2); + ForLoop *loop1=new ForLoop("loop1"); b1->edAddChild(loop1); + ForLoop *loop2=new ForLoop("loop2"); b2->edAddChild(loop2); + Bloc *b11=new Bloc("b11"); loop1->edSetNode(b11); + Bloc *b21=new Bloc("b21"); loop2->edSetNode(b21); + ToyNode *n22=new ToyNode("T22"); b21->edAddChild(n22); + Switch *sw12=new Switch("sw12"); b11->edAddChild(sw12); + Bloc *b13=new Bloc("b13"); sw12->edSetNode(7,b13); + Switch *sw14=new Switch("sw14"); b13->edAddChild(sw14); + Bloc *b15=new Bloc("b15"); sw14->edSetNode(9,b15); + ToyNode *n16=new ToyNode("T16"); b15->edAddChild(n16); + //Let's link + OutputPort *o16_1=n16->edAddOutputPort("o16_1",Runtime::_tc_double); + InputPort *i22_1=n22->edAddInputPort("i22_1",Runtime::_tc_double); + CPPUNIT_ASSERT( graph->edAddLink(o16_1,i22_1) ); + CPPUNIT_ASSERT_EQUAL(1,o16_1->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i22_1->edGetNumberOfLinks()); + graph->edRemoveLink(o16_1,i22_1); + CPPUNIT_ASSERT_EQUAL(0,o16_1->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i22_1->edGetNumberOfLinks()); + CPPUNIT_ASSERT( graph->edAddLink(o16_1,i22_1) ); + CPPUNIT_ASSERT( !graph->edAddLink(o16_1,i22_1) ); + CPPUNIT_ASSERT_EQUAL(1,o16_1->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i22_1->edGetNumberOfLinks()); + set setI1=o16_1->edSetInPort(); + CPPUNIT_ASSERT(*(setI1.begin()) == i22_1); + vector vec=o16_1->calculateHistoryOfLinkWith(i22_1); + string path; + for(vector::iterator iter=vec.begin();iter!=vec.end();iter++) + { path+=(*iter)->getNameOfTypeOfCurrentInstance(); path+=" * "; } + CPPUNIT_ASSERT ( path == "OutputPort * OutputPort * OutputPort * OutputDataStreamPort * InputDataStreamPort * InputPort * "); + graph->edRemoveLink(o16_1,i22_1); + CPPUNIT_ASSERT_EQUAL(0,o16_1->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i22_1->edGetNumberOfLinks()); + CPPUNIT_ASSERT( graph->edAddLink(o16_1,i22_1) ); + CPPUNIT_ASSERT( !graph->edAddLink(o16_1,i22_1) ); + CPPUNIT_ASSERT_EQUAL(1,o16_1->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(1,i22_1->edGetNumberOfLinks()); + path=""; + vec=o16_1->calculateHistoryOfLinkWith(i22_1); + for(vector::iterator iter=vec.begin();iter!=vec.end();iter++) + { path+=(*iter)->getNameOfTypeOfCurrentInstance(); path+=" * "; } + CPPUNIT_ASSERT ( path == "OutputPort * OutputPort * OutputPort * OutputDataStreamPort * InputDataStreamPort * InputPort * "); + graph->edRemoveLink(o16_1,i22_1); + CPPUNIT_ASSERT_EQUAL(0,o16_1->edGetNumberOfOutLinks()); + CPPUNIT_ASSERT_EQUAL(0,i22_1->edGetNumberOfLinks()); + delete graph; +} + +void EngineIntegrationTest::testForEachLoop1() +{ + Bloc *graph=new Bloc("graph"); + ForEachLoop *forEach=new ForEachLoop("myFE",Runtime::_tc_double); + graph->edAddChild(forEach); + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",Runtime::_tc_double); i11->edInit(1.3); + InputPort *i12=n1->edAddInputPort("i12",Runtime::_tc_double); i12->edInit(3.4); + InputPort *i13=n1->edAddInputPort("i13",Runtime::_tc_double); i13->edInit(5.6); + OutputPort *o11=n1->edAddOutputPort("o11",Runtime::_tc_double); + graph->edAddChild(n1); + graph->edAddCFLink(n1,forEach); + SeqToyNode *n2=new SeqToyNode("T2"); + graph->edAddChild(n2); + graph->edAddCFLink(n2,forEach); + graph->edAddLink(n1->edGetNbOfInputsOutputPort(),forEach->edGetNbOfBranchesPort()); + graph->edAddLink(n2->edGetSeqOut(),forEach->edGetSeqOfSamplesPort()); + n2->edGetInIntValue()->edInit(5); + ToyNode *n3=new ToyNode("T3"); + InputPort *i31=n3->edAddInputPort("i31",Runtime::_tc_double); i31->edInit(2.); + InputPort *i32=n3->edAddInputPort("i32",Runtime::_tc_double); + OutputPort *o31=n3->edAddOutputPort("o31",Runtime::_tc_double); + forEach->edSetNode(n3); + Seq2ToyNode *n4=new Seq2ToyNode("sequencer"); + graph->edAddChild(n4); + graph->edAddCFLink(forEach,n4); + graph->edAddLink(forEach->edGetSamplePort(),i32); + graph->edAddLink(o31,n4->edGetInValue1()); + graph->edAddLink(n2->edGetSeqOut(),n4->edGetInValue2()); + int tab[]={12,14,16,18,20}; + vector tabv(tab,tab+5); + SequenceAnyPtr tmp=SequenceAny::New(tabv);//expected sequence + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(3,(int)forEach->getNumberOfBranchesCreatedDyn()); + Any *val=n4->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp ); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(3,(int)forEach->getNumberOfBranchesCreatedDyn()); + n1->edRemovePort(i13); + exe.RunW(graph); + val=n4->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp ); + CPPUNIT_ASSERT_EQUAL(2,(int)forEach->getNumberOfBranchesCreatedDyn()); + exe.RunW(graph); + val=n4->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp ); + CPPUNIT_ASSERT_EQUAL(2,(int)forEach->getNumberOfBranchesCreatedDyn()); + Bloc *graph2=(Bloc *)graph->clone(0); + delete graph; + exe.RunW(graph2); + CPPUNIT_ASSERT_EQUAL(2,(int)((ForEachLoop *)graph2->getChildByName("myFE"))->getNumberOfBranchesCreatedDyn()); + exe.RunW(graph2); + CPPUNIT_ASSERT_EQUAL(2,(int)((ForEachLoop *)graph2->getChildByName("myFE"))->getNumberOfBranchesCreatedDyn()); + n4=(Seq2ToyNode *)graph2->getChildByName("sequencer"); + val=n4->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp ); + delete graph2; +} + +void EngineIntegrationTest::testForEachLoop2() +{ + Bloc *graph=new Bloc("graph"); + ForEachLoop *forEach=new ForEachLoop("myFE",Runtime::_tc_double); + graph->edAddChild(forEach); + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",Runtime::_tc_double); i11->edInit(1.3); + InputPort *i12=n1->edAddInputPort("i12",Runtime::_tc_double); i12->edInit(3.4); + InputPort *i13=n1->edAddInputPort("i13",Runtime::_tc_double); i13->edInit(5.6); + OutputPort *o11=n1->edAddOutputPort("o11",Runtime::_tc_double); + graph->edAddChild(n1); + graph->edAddCFLink(n1,forEach); + SeqToyNode *n2=new SeqToyNode("T2"); + graph->edAddChild(n2); + graph->edAddCFLink(n2,forEach); + graph->edAddLink(n1->edGetNbOfInputsOutputPort(),forEach->edGetNbOfBranchesPort()); + graph->edAddLink(n2->edGetSeqOut(),forEach->edGetSeqOfSamplesPort()); + n2->edGetInIntValue()->edInit(5); + Bloc *blocToShakeBaby=new Bloc("blocToShakeBaby"); + ToyNode *n3=new ToyNode("T3"); + blocToShakeBaby->edAddChild(n3); + InputPort *i31=n3->edAddInputPort("i31",Runtime::_tc_double); i31->edInit(2.); + InputPort *i32=n3->edAddInputPort("i32",Runtime::_tc_double); + OutputPort *o31=n3->edAddOutputPort("o31",Runtime::_tc_double); + forEach->edSetNode(blocToShakeBaby); + Seq2ToyNode *n4=new Seq2ToyNode("sequencer"); + graph->edAddChild(n4); + graph->edAddCFLink(forEach,n4); + graph->edAddLink(forEach->edGetSamplePort(),i32); + graph->edAddLink(o31,n4->edGetInValue1()); + graph->edAddLink(n2->edGetSeqOut(),n4->edGetInValue2()); + CPPUNIT_ASSERT(dynamic_cast(graph->getOutputPort("myFE.blocToShakeBaby.T3.o31"))); + int tab[]={12,14,16,18,20}; + vector tabv(tab,tab+5); + SequenceAnyPtr tmp=SequenceAny::New(tabv);//expected sequence + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(3,(int)forEach->getNumberOfBranchesCreatedDyn()); + Any *val=n4->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp ); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(3,(int)forEach->getNumberOfBranchesCreatedDyn()); + n1->edRemovePort(i13); + exe.RunW(graph); + val=n4->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp ); + CPPUNIT_ASSERT_EQUAL(2,(int)forEach->getNumberOfBranchesCreatedDyn()); + exe.RunW(graph); + val=n4->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp ); + CPPUNIT_ASSERT_EQUAL(2,(int)forEach->getNumberOfBranchesCreatedDyn()); + Bloc *graph2=(Bloc *)graph->clone(0); + delete graph; + exe.RunW(graph2); + CPPUNIT_ASSERT_EQUAL(2,(int)((ForEachLoop *)graph2->getChildByName("myFE"))->getNumberOfBranchesCreatedDyn()); + exe.RunW(graph2); + CPPUNIT_ASSERT_EQUAL(2,(int)((ForEachLoop *)graph2->getChildByName("myFE"))->getNumberOfBranchesCreatedDyn()); + n4=(Seq2ToyNode *)graph2->getChildByName("sequencer"); + val=n4->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp ); + delete graph2; +} + +//Multi inclusion of ForEach +void EngineIntegrationTest::testForEachLoop3() +{ + Bloc *graph=new Bloc("graph"); + ForEachLoop *forEach1=new ForEachLoop("myFE1",Runtime::_tc_double); + TypeCodeSeq *tc1=new TypeCodeSeq("","",Runtime::_tc_double); + ForEachLoop *forEach2=new ForEachLoop("myFE2",tc1); + SequenceAnyPtr tmpI=SequenceAny::New(tc1,3);//value as input + tc1->decrRef(); + tc1=new TypeCodeSeq("","",Runtime::_tc_int); + SequenceAnyPtr tmpO=SequenceAny::New(tc1,3);//value expected + tc1->decrRef(); + graph->edAddChild(forEach2); + forEach2->edSetNode(forEach1); + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",Runtime::_tc_double); i11->edInit(9.); + InputPort *i12=n1->edAddInputPort("i12",Runtime::_tc_double); + OutputPort *o11=n1->edAddOutputPort("o11",Runtime::_tc_double); + OutputPort *o12=n1->edAddOutputPort("o12",Runtime::_tc_double); + OutputPort *o13=n1->edAddOutputPort("o13",Runtime::_tc_double); + forEach1->edSetNode(n1); + graph->edAddLink(forEach2->edGetSamplePort(),forEach1->edGetSeqOfSamplesPort()); + graph->edAddLink(forEach1->edGetSamplePort(),i12); + Seq3ToyNode *n2=new Seq3ToyNode("T2"); + graph->edAddChild(n2); + graph->edAddLink(o11,n2->edGetInValue1()); + graph->edAddLink(o13,n2->edGetInValue2()); + graph->edAddCFLink(forEach2,n2); + forEach1->edGetNbOfBranchesPort()->edInit(5); + forEach2->edGetNbOfBranchesPort()->edInit(10); + //Preparing input matrix + double tab1[]={3.,6.,9.,12.,15.}; + double tab2[]={18.,21.,24.,27.,30.}; + double tab3[]={33.,36.,39.,42.,42.}; + vector tabv1(tab1,tab1+5); + vector tabv2(tab2,tab2+5); + vector tabv3(tab3,tab3+5); + SequenceAnyPtr tmp=SequenceAny::New(tabv1); + tmpI->setEltAtRank(0,tmp); + tmp=SequenceAny::New(tabv2); + tmpI->setEltAtRank(1,tmp); + tmp=SequenceAny::New(tabv3); + tmpI->setEltAtRank(2,tmp); + forEach2->edGetSeqOfSamplesPort()->edInit((Any *)tmpI); + //preparing expected matrix + int tab1I[]={8,10,12,14,16}; + int tab2I[]={18,20,22,24,26}; + int tab3I[]={28,30,32,34,34}; + vector tabvI1(tab1I,tab1I+5); + vector tabvI2(tab2I,tab2I+5); + vector tabvI3(tab3I,tab3I+5); + tmp=SequenceAny::New(tabvI1); + tmpO->setEltAtRank(0,tmp); + tmp=SequenceAny::New(tabvI2); + tmpO->setEltAtRank(1,tmp); + tmp=SequenceAny::New(tabvI3); + tmpO->setEltAtRank(2,tmp); + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(3,(int)forEach2->getNumberOfBranchesCreatedDyn()); + Any *val=n2->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmpO ); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(3,(int)forEach2->getNumberOfBranchesCreatedDyn()); + val=n2->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmpO ); + ForEachLoop *clone=(ForEachLoop *)forEach2->clone(0); + try + { + clone->getNumberOfBranchesCreatedDyn(); + CPPUNIT_ASSERT(false); + } + catch(Exception& e) + { + CPPUNIT_ASSERT( string(e.what())=="ForEachLoop::getNumberOfBranches : No branches created dynamically ! - ForEachLoop needs to run or to be runned to call getNumberOfBranches"); + } + Bloc *graphCloned=(Bloc *)graph->clone(0); + delete graph; + exe.RunW(clone); + CPPUNIT_ASSERT_EQUAL(3,(int)clone->getNumberOfBranchesCreatedDyn()); + exe.RunW(clone); + CPPUNIT_ASSERT_EQUAL(3,(int)clone->getNumberOfBranchesCreatedDyn()); + exe.RunW(graphCloned); + CPPUNIT_ASSERT_EQUAL(3,(int)((ForEachLoop *)graphCloned->getChildByName("myFE2"))->getNumberOfBranchesCreatedDyn()); + val=((Seq3ToyNode *) graphCloned->getChildByName("T2"))->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmpO ); + exe.RunW(graphCloned); + CPPUNIT_ASSERT_EQUAL(3,(int)((ForEachLoop *)graphCloned->getChildByName("myFE2"))->getNumberOfBranchesCreatedDyn()); + val=((Seq3ToyNode *) graphCloned->getChildByName("T2"))->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmpO ); + delete graphCloned; + delete clone; +} + +void EngineIntegrationTest::testForEachLoop4() +{ + Bloc *graph=new Bloc("graph"); + ForEachLoop *forEach1=new ForEachLoop("myFE1",Runtime::_tc_int); + Switch *sw=new Switch("Sw1"); + forEach1->edSetNode(sw); + graph->edAddChild(forEach1); + SeqToyNode *n0=new SeqToyNode("T0"); + graph->edAddChild(n0); + n0->edGetInIntValue()->edInit(5); + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",Runtime::_tc_double); i11->edInit(9.); + InputPort *i12=n1->edAddInputPort("i12",Runtime::_tc_double); i12->edInit(8.); + OutputPort *o11=n1->edAddOutputPort("o11",Runtime::_tc_double); + graph->edAddChild(n1); + Seq2ToyNode *n2=new Seq2ToyNode("T2"); + graph->edAddChild(n2); + graph->edAddCFLink(n0,forEach1); + graph->edAddCFLink(n1,forEach1); + graph->edAddCFLink(forEach1,n2); + ToyNode *n3=new ToyNode("T3"); + InputPort *i31=n3->edAddInputPort("i31",Runtime::_tc_double); + InputPort *i32=n3->edAddInputPort("i32",Runtime::_tc_double); i32->edInit(5.); + OutputPort *o31=n3->edAddOutputPort("o31",Runtime::_tc_double); + sw->edSetNode(2,n3); + ToyNode *n4=new ToyNode("T4"); + InputPort *i41=n4->edAddInputPort("i41",Runtime::_tc_double); i41->edInit(5.); + InputPort *i42=n4->edAddInputPort("i42",Runtime::_tc_double); + InputPort *i43=n4->edAddInputPort("i43",Runtime::_tc_double); i43->edInit(7.); + OutputPort *o41=n4->edAddOutputPort("o41",Runtime::_tc_double); + OutputPort *o42=n4->edAddOutputPort("o42",Runtime::_tc_double); + sw->edSetDefaultNode(n4); + graph->edAddLink(o11,i31); + graph->edAddLink(forEach1->edGetSamplePort(),sw->edGetConditionPort()); + graph->edAddLink(o31,n2->edGetInValue1()); + graph->edRemoveLink(o31,n2->edGetInValue1()); + graph->edAddLink(o31,n2->edGetInValue1()); + graph->edAddLink(o31,n2->edGetInValue2());// + graph->edAddLink(o11,i42); + graph->edAddLink(o41,n2->edGetInValue2()); + graph->edRemoveLink(o41,n2->edGetInValue2()); + graph->edAddLink(o41,n2->edGetInValue2()); + graph->edAddLink(o42,n2->edGetInValue1()); + int tabI[]={1,2,2,45,2,5,6,2}; + vector tabvI(tabI,tabI+8); + SequenceAnyPtr tmp=SequenceAny::New(tabvI); + forEach1->edGetSeqOfSamplesPort()->edInit((Any *)tmp); + //graph->edAddLink(n0->edGetSeqOut(),forEach1->edGetSeqOfSamplesPort()); + graph->edAddLink(n0->edGetSeqOut(),n2->edGetInValue2()); + Executor exe; + try + { + exe.RunW(graph); + CPPUNIT_ASSERT(false); + } + catch(Exception& e) + { + CPPUNIT_ASSERT(string(e.what())=="InputPort::checkBasicConsistency : Port nbBranches of node with name myFE1 neither initialized nor linked back"); + } + forEach1->edGetNbOfBranchesPort()->edInit(7); + //expected vals + int tabI2[]={29,44,44,29,44,29,29,44}; + vector tabvI2(tabI2,tabI2+8); + SequenceAnyPtr tmp2=SequenceAny::New(tabvI2); + exe.RunW(graph); + Any *val=n2->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp2 ); + CPPUNIT_ASSERT_EQUAL(7,(int)forEach1->getNumberOfBranchesCreatedDyn()); + exe.RunW(graph); + val=n2->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp2 ); + CPPUNIT_ASSERT_EQUAL(7,(int)forEach1->getNumberOfBranchesCreatedDyn()); + Bloc *graphCloned=(Bloc *)graph->clone(0); + delete graph; + exe.RunW(graphCloned); + val=((Seq2ToyNode *)graphCloned->getChildByName("T2"))->edGetSeqOut()->get(); + delete graphCloned; +} + +/*! + Test to check possibility to linked several times SamplePort OutputPort of a ForEachLoop node. + */ +void EngineIntegrationTest::testForEachLoop5() +{ + Bloc *graph=new Bloc("graph"); + ForEachLoop *forEach=new ForEachLoop("myFE",Runtime::_tc_double); + graph->edAddChild(forEach); + ToyNode *n1=new ToyNode("T1"); + InputPort *i11=n1->edAddInputPort("i11",Runtime::_tc_double); i11->edInit(1.3); + InputPort *i12=n1->edAddInputPort("i12",Runtime::_tc_double); i12->edInit(3.4); + InputPort *i13=n1->edAddInputPort("i13",Runtime::_tc_double); i13->edInit(5.6); + OutputPort *o11=n1->edAddOutputPort("o11",Runtime::_tc_double); + graph->edAddChild(n1); + graph->edAddCFLink(n1,forEach); + SeqToyNode *n2=new SeqToyNode("T2"); + graph->edAddChild(n2); + graph->edAddCFLink(n2,forEach); + graph->edAddLink(n1->edGetNbOfInputsOutputPort(),forEach->edGetNbOfBranchesPort()); + graph->edAddLink(n2->edGetSeqOut(),forEach->edGetSeqOfSamplesPort()); + n2->edGetInIntValue()->edInit(5); + ToyNode *n3=new ToyNode("T3"); + InputPort *i31=n3->edAddInputPort("i31",Runtime::_tc_double); + InputPort *i32=n3->edAddInputPort("i32",Runtime::_tc_double); + OutputPort *o31=n3->edAddOutputPort("o31",Runtime::_tc_double); + forEach->edSetNode(n3); + Seq2ToyNode *n4=new Seq2ToyNode("sequencer"); + graph->edAddChild(n4); + graph->edAddCFLink(forEach,n4); + graph->edAddLink(forEach->edGetSamplePort(),i31); + graph->edAddLink(forEach->edGetSamplePort(),i32); + graph->edAddLink(o31,n4->edGetInValue1()); + graph->edAddLink(n2->edGetSeqOut(),n4->edGetInValue2()); + int tab[]={15,18,21,24,27}; + vector tabv(tab,tab+5); + SequenceAnyPtr tmp=SequenceAny::New(tabv);//expected sequence + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(3,(int)forEach->getNumberOfBranchesCreatedDyn()); + Any *val=n4->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp ); + exe.RunW(graph); + CPPUNIT_ASSERT_EQUAL(3,(int)forEach->getNumberOfBranchesCreatedDyn()); + n1->edRemovePort(i13); + exe.RunW(graph); + val=n4->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp ); + CPPUNIT_ASSERT_EQUAL(2,(int)forEach->getNumberOfBranchesCreatedDyn()); + exe.RunW(graph); + val=n4->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp ); + CPPUNIT_ASSERT_EQUAL(2,(int)forEach->getNumberOfBranchesCreatedDyn()); + Bloc *graph2=(Bloc *)graph->clone(0); + delete graph; + exe.RunW(graph2); + CPPUNIT_ASSERT_EQUAL(2,(int)((ForEachLoop *)graph2->getChildByName("myFE"))->getNumberOfBranchesCreatedDyn()); + exe.RunW(graph2); + CPPUNIT_ASSERT_EQUAL(2,(int)((ForEachLoop *)graph2->getChildByName("myFE"))->getNumberOfBranchesCreatedDyn()); + n4=(Seq2ToyNode *)graph2->getChildByName("sequencer"); + val=n4->edGetSeqOut()->get(); + CPPUNIT_ASSERT( *val==*tmp ); + delete graph2; +} + +/*! + * Here a test for OptimizerLoop with an evenemential (or synchronous) algorithm + */ +void EngineIntegrationTest::testForOptimizerLoop1() +{ + Bloc *graph=new Bloc("Global"); + OptimizerLoop *opt=new OptimizerLoop("myOptWthAlgSync",".libs/libPluginOptEvTest1","PluginOptEvTest1Factory",true); + graph->edAddChild(opt); + ToyNode *n1=new ToyNode("T1"); + ToyNode *n2=new ToyNode("T2"); + graph->edAddChild(n2); + graph->edAddCFLink(opt,n2); + opt->edSetNode(n1); + InputPort *i1=n1->edAddInputPort("i1",Runtime::_tc_double); + OutputPort *o1=n1->edAddOutputPort("o1",Runtime::_tc_double); + graph->edAddLink(opt->edGetSamplePort(),i1); + InputPort *i2=n2->edAddInputPort("i2",Runtime::_tc_double); + OutputPort *o2_1=n2->edAddOutputPort("o1",Runtime::_tc_double); + graph->edAddLink(o1,i2); + graph->edAddLink(n1->edGetNbOfInputsOutputPort(),opt->edGetPortForOutPool()); + opt->edGetNbOfBranchesPort()->edInit(2); + opt->edGetPortForInitFile()->edInit("toto"); + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(45.6,((OutputToyPort*)o2_1)->get()->getDoubleValue(),DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT(8==(int)opt->getNumberOfEltsConsumed() or 7==(int)opt->getNumberOfEltsConsumed()); + CPPUNIT_ASSERT_EQUAL(2,(int)((DynParaLoop *)(opt))->getNumberOfBranchesCreatedDyn()); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(45.6,((OutputToyPort*)o2_1)->get()->getDoubleValue(),DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT(8==(int)opt->getNumberOfEltsConsumed() or 7==(int)opt->getNumberOfEltsConsumed()); + CPPUNIT_ASSERT_EQUAL(2,(int)((DynParaLoop *)(opt))->getNumberOfBranchesCreatedDyn()); + Bloc *clone=(Bloc *)graph->clone(0); + delete graph; + exe.RunW(clone); + CPPUNIT_ASSERT_DOUBLES_EQUAL(45.6,((OutputToyPort*)(clone->getOutPort("T2.o1")))->get()->getDoubleValue(),DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT(8==(int)((OptimizerLoop *)(clone->getChildByName("myOptWthAlgSync")))->getNumberOfEltsConsumed() or 7==(int)((OptimizerLoop *)(clone->getChildByName("myOptWthAlgSync")))->getNumberOfEltsConsumed()); + CPPUNIT_ASSERT_EQUAL(2,(int)((OptimizerLoop *)(clone->getChildByName("myOptWthAlgSync")))->getNumberOfBranchesCreatedDyn()); + exe.RunW(clone); + CPPUNIT_ASSERT_DOUBLES_EQUAL(45.6,((OutputToyPort*)(clone->getOutPort("T2.o1")))->get()->getDoubleValue(),DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT(8==(int)((OptimizerLoop *)(clone->getChildByName("myOptWthAlgSync")))->getNumberOfEltsConsumed() or 7==(int)((OptimizerLoop *)(clone->getChildByName("myOptWthAlgSync")))->getNumberOfEltsConsumed()); + CPPUNIT_ASSERT_EQUAL(2,(int)((OptimizerLoop *)(clone->getChildByName("myOptWthAlgSync")))->getNumberOfBranchesCreatedDyn()); + delete clone; +} + + +/*! + * Idem testForOptimizerLoop1 but with intermediate bloc inside OptermizerLoop. + */ +void EngineIntegrationTest::testForOptimizerLoop2() +{ + Bloc *graph=new Bloc("Global"); + OptimizerLoop *opt=new OptimizerLoop("myOptWthAlgSync",".libs/libPluginOptEvTest1","PluginOptEvTest1Factory",true); + graph->edAddChild(opt); + ToyNode *n1=new ToyNode("T1"); + ToyNode *n2=new ToyNode("T2"); + Bloc *bloc=new Bloc("Bloc"); + graph->edAddChild(n2); + graph->edAddCFLink(opt,n2); + opt->edSetNode(bloc); + bloc->edAddChild(n1); + InputPort *i1=n1->edAddInputPort("i1",Runtime::_tc_double); + OutputPort *o1=n1->edAddOutputPort("o1",Runtime::_tc_double); + graph->edAddLink(opt->edGetSamplePort(),i1); + InputPort *i2=n2->edAddInputPort("i2",Runtime::_tc_double); + OutputPort *o2_1=n2->edAddOutputPort("o1",Runtime::_tc_double); + graph->edAddLink(o1,i2); + graph->edAddLink(n1->edGetNbOfInputsOutputPort(),opt->edGetPortForOutPool()); + opt->edGetNbOfBranchesPort()->edInit(2); + opt->edGetPortForInitFile()->edInit("toto"); + Executor exe; + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(45.6,((OutputToyPort*)o2_1)->get()->getDoubleValue(),DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT(8==(int)opt->getNumberOfEltsConsumed() or 7==(int)opt->getNumberOfEltsConsumed()); + CPPUNIT_ASSERT_EQUAL(2,(int)((DynParaLoop *)(opt))->getNumberOfBranchesCreatedDyn()); + exe.RunW(graph); + CPPUNIT_ASSERT_DOUBLES_EQUAL(45.6,((OutputToyPort*)o2_1)->get()->getDoubleValue(),DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT(8==(int)opt->getNumberOfEltsConsumed() or 7==(int)opt->getNumberOfEltsConsumed()); + CPPUNIT_ASSERT_EQUAL(2,(int)((DynParaLoop *)(opt))->getNumberOfBranchesCreatedDyn()); + Bloc *clone=(Bloc *)graph->clone(0); + delete graph; + exe.RunW(clone); + CPPUNIT_ASSERT_DOUBLES_EQUAL(45.6,((OutputToyPort*)(clone->getOutPort("T2.o1")))->get()->getDoubleValue(),DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT(8==(int)((OptimizerLoop *)(clone->getChildByName("myOptWthAlgSync")))->getNumberOfEltsConsumed() or 7==(int)((OptimizerLoop *)(clone->getChildByName("Bloc.myOptWthAlgSync")))->getNumberOfEltsConsumed()); + CPPUNIT_ASSERT_EQUAL(2,(int)((OptimizerLoop *)(clone->getChildByName("myOptWthAlgSync")))->getNumberOfBranchesCreatedDyn()); + exe.RunW(clone); + CPPUNIT_ASSERT_DOUBLES_EQUAL(45.6,((OutputToyPort*)(clone->getOutPort("T2.o1")))->get()->getDoubleValue(),DBL_PRECISION_COMPARE ); + CPPUNIT_ASSERT(8==(int)((OptimizerLoop *)(clone->getChildByName("myOptWthAlgSync")))->getNumberOfEltsConsumed() or 7==(int)((OptimizerLoop *)(clone->getChildByName("Bloc.myOptWthAlgSync")))->getNumberOfEltsConsumed()); + CPPUNIT_ASSERT_EQUAL(2,(int)((OptimizerLoop *)(clone->getChildByName("myOptWthAlgSync")))->getNumberOfBranchesCreatedDyn()); + delete clone; +} + +/*! + * Test to check that in for compil-time known connectivity of a graph, deployment calculation is OK. + */ +void EngineIntegrationTest::testForDeployment1() +{ + // First test of NON ServiceNodes deployment calculation + ToyNode *n1=new ToyNode("T1"); + ToyNode *n2=new ToyNode("T2"); + Bloc *graph=new Bloc("Global"); + graph->edAddChild(n1); graph->edAddChild(n2); + DeploymentTree tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT(tree.isNull());//No placement info + graph->edRemoveChild(n2); + delete n2; + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT(tree.isNull());//No placement info to. + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + // + ToyNode1S *n1S=new ToyNode1S("T1S"); graph->edAddChild(n1S); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT(!tree.isNull());//Here placement info. + CPPUNIT_ASSERT_EQUAL( 1, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL((Task *)n1S, tree.getFreeDeployableTasks()[0]); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + // + Bloc *b1=new Bloc("B1"); + ToyNode1S *n2S=new ToyNode1S("T2S"); b1->edAddChild(n2S); ToyNode1S *n3S=new ToyNode1S("T3S"); b1->edAddChild(n3S); ToyNode2S *n4S=new ToyNode2S("T4S"); + ToyNode2S *n5S=new ToyNode2S("T5S"); b1->edAddChild(n5S); + graph->edAddChild(b1); graph->edAddChild(n4S); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT(!tree.isNull());//Here placement info. + CPPUNIT_ASSERT_EQUAL( 5, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + //Ok now let's associate some components... + ComponentInstanceTest1 *comp1=new ComponentInstanceTest1("FLICA"); + n1S->setComponent(comp1); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT(!tree.isNull());//Here placement info. + CPPUNIT_ASSERT_EQUAL( 4, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(tree.presenceOfDefaultContainer()); + n3S->setComponent(comp1); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT(!tree.isNull());//Here placement info. + CPPUNIT_ASSERT_EQUAL( 3, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(tree.presenceOfDefaultContainer()); + vector ta=tree.getTasksLinkedToComponent(comp1); + set setToTest1(ta.begin(),ta.end()); set setToTest2; setToTest2.insert(n1S); setToTest2.insert(n3S); + checkSetsEqual(setToTest1,setToTest2); + ComponentInstanceTest1 *comp2=new ComponentInstanceTest1("CRONOS"); + n2S->setComponent(comp2); + CPPUNIT_ASSERT_THROW(n4S->setComponent(comp2),YACS::Exception);//incompatibility between ComponentInstanceTest1 and ToyNode2S + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 2, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(tree.presenceOfDefaultContainer()); + ComponentInstanceTest2 *comp3=new ComponentInstanceTest2("PYDK"); + n4S->setComponent(comp3); + n5S->setComponent(comp3); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(tree.presenceOfDefaultContainer()); + // Ok let's play with containers now + ContainerTest *cont1=new ContainerTest; + comp1->setContainer(cont1); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(tree.presenceOfDefaultContainer()); + ContainerTest *cont2=new ContainerTest; + comp2->setContainer(cont2); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(tree.presenceOfDefaultContainer()); + comp2->setContainer(cont1); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(tree.presenceOfDefaultContainer()); + ContainerTest2 *cont3=new ContainerTest2; + CPPUNIT_ASSERT_THROW(comp3->setContainer(cont2),YACS::Exception); + comp3->setContainer(cont3); + tree=graph->getDeploymentTree(); + vector tb=tree.getAllCTDefContainers(); set tbs(tb.begin(),tb.end()); set tb2; tb2.insert(cont1); tb2.insert(cont3); + checkSetsEqual(tbs,tb2); + vector tc=tree.getComponentsLinkedToContainer(cont1); set tcs(tc.begin(),tc.end()); + set tc2; tc2.insert(comp1); tc2.insert(comp2); + checkSetsEqual(tcs,tc2); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + ta=tree.getTasksLinkedToComponent(comp1); + //Ok now let's see behaviour on cloning. + Bloc *cl=(Bloc *)graph->clone(0); + tree=cl->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + tb=tree.getAllCTDefContainers(); tbs.clear(); tbs.insert(tb.begin(),tb.end()); + checkSetsNotEqual(tbs,tb2); + delete cl; + // + cont1->attachOnCloning(); cont3->attachOnCloning(); + cl=(Bloc *)graph->clone(0); + tree=cl->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + tb=tree.getAllCTDefContainers(); tbs.clear(); tbs.insert(tb.begin(),tb.end()); + checkSetsEqual(tbs,tb2); + delete cl; + // + cont1->dettachOnCloning(); + cl=(Bloc *)graph->clone(0); + tree=cl->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + tb=tree.getAllCTDefContainers(); tbs.clear(); tbs.insert(tb.begin(),tb.end()); + CPPUNIT_ASSERT(tbs.find(cont1)==tbs.end()); + CPPUNIT_ASSERT(!(tbs.find(cont3)==tbs.end())); + delete cl; + cont1->attachOnCloning(); + comp1->attachOnCloning(); + comp2->attachOnCloning(); + cl=(Bloc *)graph->clone(0); + tree=cl->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + tc=tree.getComponentsLinkedToContainer(cont1); tcs.clear(); tcs.insert(tc.begin(),tc.end()); + checkSetsEqual(tcs,tc2); + delete cl; + comp1->dettachOnCloning(); + comp2->dettachOnCloning(); + cl=(Bloc *)graph->clone(0); + tree=cl->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + tc=tree.getComponentsLinkedToContainer(cont1); tcs.clear(); tcs.insert(tc.begin(),tc.end()); + checkSetsNotEqual(tcs,tc2); + delete cl; + comp1->attachOnCloning(); + cl=(Bloc *)graph->clone(0); + tree=cl->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + tc=tree.getComponentsLinkedToContainer(cont1); tcs.clear(); tcs.insert(tc.begin(),tc.end()); + CPPUNIT_ASSERT(tcs.find(comp1)!=tcs.end()); + CPPUNIT_ASSERT(tcs.find(comp2)==tcs.end()); + delete cl; + //Final clean up + comp3->decrRef(); + comp2->decrRef(); + comp1->decrRef(); + cont1->decrRef(); + cont2->decrRef(); + cont3->decrRef(); + delete graph; +} + +/*! + * Test to check that in for compil-time known connectivity of a graph, deployment calculation is OK. + */ +void EngineIntegrationTest::testForDeployment2() +{ + Bloc *graph=new Bloc("graph"); + ToyNode1S *n1S=new ToyNode1S("T1S"); graph->edAddChild(n1S); + ForEachLoop *fe1=new ForEachLoop("fe1",Runtime::_tc_double); + Bloc *b1=new Bloc("B1"); + fe1->edSetNode(b1); + ToyNode1S *n2S=new ToyNode1S("T2S"); b1->edAddChild(n2S); ToyNode1S *n3S=new ToyNode1S("T3S"); b1->edAddChild(n3S); ToyNode2S *n4S=new ToyNode2S("T4S"); + ToyNode2S *n5S=new ToyNode2S("T5S"); b1->edAddChild(n5S); + graph->edAddChild(fe1); graph->edAddChild(n4S); + DeploymentTree tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT(!tree.isNull());//Here placement info. + CPPUNIT_ASSERT_EQUAL( 5, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + //Check that compatibility is checked... + ComponentInstanceTest1 *comp1=new ComponentInstanceTest1("FLICA"); + n1S->setComponent(comp1); + CPPUNIT_ASSERT_THROW(n4S->setComponent(comp1),YACS::Exception);//Impossible not compatible between ToyNode1S and ToyNode2S + CPPUNIT_ASSERT_THROW(n2S->setComponent(comp1),YACS::Exception);//Failure here to but due to incompatibility of scopes n2S is in a ForEachLoop and not n1S and comp1 is NOT attached here. + comp1->attachOnCloning(); + n2S->setComponent(comp1);//here it's ok because comp1 is attached... + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT(!tree.isNull()); + CPPUNIT_ASSERT_EQUAL( 3, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(tree.presenceOfDefaultContainer()); + //Check that RTO (runtime only) components are detected + ComponentInstanceTest1 *comp2=new ComponentInstanceTest1("DKCORE"); + n3S->setComponent(comp2); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT(!tree.isNull()); + CPPUNIT_ASSERT_EQUAL( 2, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfRTODefComponentInstances()); + ComponentInstanceTest2 *comp3=new ComponentInstanceTest2("DKCORE"); + n4S->setComponent(comp3); + CPPUNIT_ASSERT_THROW(n5S->setComponent(comp3),YACS::Exception);//For fun just like 19 lines before. + comp3->attachOnCloning(); + n5S->setComponent(comp3);//ok + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT(!tree.isNull()); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(tree.presenceOfDefaultContainer()); + ContainerTest *cont1=new ContainerTest; + comp1->setContainer(cont1); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(tree.presenceOfDefaultContainer()); + ContainerTest2 *cont3=new ContainerTest2; + comp3->setContainer(cont3); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(tree.presenceOfDefaultContainer()); + ContainerTest *cont2=new ContainerTest; + comp2->setContainer(cont2); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + vector conts=tree.getAllCTDefContainers(); set contsS(conts.begin(),conts.end()); + set expectedContSet; expectedContSet.insert(cont1); expectedContSet.insert(cont3); + checkSetsEqual(expectedContSet,contsS); + conts=tree.getAllRTODefContainers(); contsS.clear(); contsS.insert(conts.begin(),conts.end()); + expectedContSet.clear(); expectedContSet.insert(cont2); + checkSetsEqual(expectedContSet,contsS); + cont2->attachOnCloning(); + tree=graph->getDeploymentTree(); + CPPUNIT_ASSERT_EQUAL( 0, (int) tree.getFreeDeployableTasks().size()); + tree.getNumberOfCTDefContainer(); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(2, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(1, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + comp2->attachOnCloning(); + tree.getNumberOfCTDefContainer(); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefContainer()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefContainer()); + CPPUNIT_ASSERT_EQUAL(3, (int) tree.getNumberOfCTDefComponentInstances()); CPPUNIT_ASSERT_EQUAL(0, (int) tree.getNumberOfRTODefComponentInstances()); + CPPUNIT_ASSERT(!tree.presenceOfDefaultContainer()); + //clean up + cont1->decrRef(); + cont2->decrRef(); + cont3->decrRef(); + comp1->decrRef(); + comp2->decrRef(); + comp3->decrRef(); + delete graph; +} + +/*! + * Checking firstley fondamentals tools for check consistency. Essentially CF dependancy by visiting CF Graph. + * Secondly check that data link at one level is correctly dealed. + */ +void EngineIntegrationTest::testForCheckConsistency1() +{ + LinkInfo info(LinkInfo::ALL_DONT_STOP); + ToyNode *n1=new ToyNode("T1"); ToyNode *n5=new ToyNode("T5"); ToyNode *n9=new ToyNode("T9"); + ToyNode *n2=new ToyNode("T2"); ToyNode *n6=new ToyNode("T6"); ToyNode *n10=new ToyNode("T10"); + ToyNode *n3=new ToyNode("T3"); ToyNode *n7=new ToyNode("T7"); ToyNode *n11=new ToyNode("T11"); + ToyNode *n4=new ToyNode("T4"); ToyNode *n8=new ToyNode("T8"); ToyNode *n12=new ToyNode("T12"); + Bloc *graph=new Bloc("Global"); + graph->edAddChild(n1); graph->edAddChild(n2); graph->edAddChild(n3); graph->edAddChild(n4); graph->edAddChild(n5); graph->edAddChild(n6); + graph->edAddChild(n7); graph->edAddChild(n8); graph->edAddChild(n9); graph->edAddChild(n10); graph->edAddChild(n11); graph->edAddChild(n12); + graph->edAddCFLink(n1,n2); graph->edAddCFLink(n1,n4); graph->edAddCFLink(n1,n3); graph->edAddCFLink(n3,n10); graph->edAddCFLink(n4,n6); + graph->edAddCFLink(n2,n10); graph->edAddCFLink(n6,n7); graph->edAddCFLink(n5,n8); graph->edAddCFLink(n9,n6); graph->edAddCFLink(n3,n5); + graph->edAddCFLink(n5,n6); graph->edAddCFLink(n10,n7); graph->edAddCFLink(n10,n11); graph->edAddCFLink(n11,n12); + graph->edAddCFLink(n12,n5); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(2,(int)info.getNumberOfInfoLinks(I_CF_USELESS)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); + set< pair > s=info.getInfoUselessLinks(); + set< pair > s2; s2.insert(pair(n3,n5)); s2.insert(pair(n10,n7)); + checkSetsEqual< pair >(s,s2); + set s3; set setExpected; setExpected.insert(n2); setExpected.insert(n4); setExpected.insert(n3); setExpected.insert(n10); + setExpected.insert(n11); setExpected.insert(n12); setExpected.insert(n5); setExpected.insert(n6); setExpected.insert(n7); setExpected.insert(n8); + map > accelStr; + graph->findAllNodesStartingFrom(n1,s3,accelStr,info); accelStr.clear(); + checkSetsEqual(setExpected,s3); s3.clear(); setExpected.clear(); + graph->findAllNodesStartingFrom(n7,s3,accelStr,info); accelStr.clear(); + checkSetsEqual(setExpected,s3); s3.clear(); setExpected.clear(); + graph->findAllNodesStartingFrom(n1,s3,accelStr,info); accelStr.clear(); + checkSetsEqual(setExpected,s3); s3.clear(); setExpected.clear(); + list< vector > vec; + graph->findAllPathsStartingFrom(n7, vec,accelStr); + graph->findAllNodesStartingFrom(n7,s3,accelStr,info); accelStr.clear();setExpected=graph->edGetDirectDescendants(); setExpected.erase(n8); setExpected.erase(n7); + checkSetsEqual(setExpected,s3); s3.clear(); setExpected.clear(); + //Testing good reinitialisation + setExpected.insert(n2); setExpected.insert(n4); setExpected.insert(n3); setExpected.insert(n10); + setExpected.insert(n11); setExpected.insert(n12); setExpected.insert(n5); setExpected.insert(n6); setExpected.insert(n7); setExpected.insert(n8); + graph->findAllNodesStartingFrom(n1,s3,accelStr,info); accelStr.clear(); + checkSetsEqual(setExpected,s3); s3.clear(); setExpected.clear(); + graph->findAllNodesStartingFrom(n1,s3,accelStr,info); accelStr.clear(); + checkSetsEqual(setExpected,s3); s3.clear(); setExpected.clear(); + //End test good reinitialisation + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(2,(int)info.getNumberOfInfoLinks(I_CF_USELESS)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); + s=info.getInfoUselessLinks(); + s2.clear(); s2.insert(pair(n3,n5)); s2.insert(pair(n10,n7)); + checkSetsEqual< pair >(s,s2); + //n3->n5 and n10->n7 have been detected to be useless... try to remove them and relaunch : normally no useless links should be detected + graph->edRemoveCFLink(n3,n5); graph->edRemoveCFLink(n10,n7); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfInfoLinks(I_CF_USELESS)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); + //Playing with check at one level of scope. + InputPort *i11_1=n11->edAddInputPort("i1",Runtime::_tc_double); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_ALL)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_ALL)); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_NEVER_SET_INPUTPORT)); + pair p1=info.getErrLink(0,E_NEVER_SET_INPUTPORT); pair p2(0,i11_1); + CPPUNIT_ASSERT(p1==p2); + // + i11_1->edInit(3.14); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); + i11_1->edRemoveManInit(); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_ALL)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_ALL)); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_NEVER_SET_INPUTPORT)); + //only back defined + OutputPort *o11_1=n11->edAddOutputPort("o11_1",Runtime::_tc_double); + graph->edAddLink(o11_1,i11_1); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_BACK)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_ALL)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_ONLY_BACKWARD_DEFINED)); + graph->edRemoveLink(o11_1,i11_1); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_ALL)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_ALL)); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_NEVER_SET_INPUTPORT)); + // + OutputPort *o10_1=n10->edAddOutputPort("o10_1",Runtime::_tc_double); + graph->edAddLink(o10_1,i11_1); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); + OutputPort *o2_1=n2->edAddOutputPort("o2_1",Runtime::_tc_double); + graph->edAddLink(o2_1,i11_1); + // useless + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_USELESS)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); + // many useless + OutputPort *o1_1=n1->edAddOutputPort("o1_1",Runtime::_tc_double); + graph->edAddLink(o1_1,i11_1); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(2,(int)info.getNumberOfInfoLinks(I_USELESS)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); + // collapse and useless ; useless + OutputPort *o3_1=n3->edAddOutputPort("o3_1",Runtime::_tc_double); + graph->edAddLink(o3_1,i11_1); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_USELESS)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfWarnLinksGrp(W_COLLAPSE_AND_USELESS)); + // collapse ; useless + graph->edRemoveLink(o10_1,i11_1); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_USELESS)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfWarnLinksGrp(W_COLLAPSE)); + // collapse ; useless ; unpredictable' + OutputPort *o4_1=n4->edAddOutputPort("o4_1",Runtime::_tc_double); + graph->edAddLink(o4_1,i11_1); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_USELESS)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfWarnLinksGrp(W_ALL)); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_ALL)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfErrLinks(E_UNPREDICTABLE_FED)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfWarnLinksGrp(W_COLLAPSE)); + CPPUNIT_ASSERT( (pair(o4_1,i11_1)==info.getErrLink(0,E_UNPREDICTABLE_FED)) ); + // restart all + graph->edRemoveLink(o3_1,i11_1); graph->edRemoveLink(o4_1,i11_1); graph->edRemoveLink(o1_1,i11_1); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); + // back link + OutputPort *o5_1=n5->edAddOutputPort("o5_1",Runtime::_tc_double); graph->edAddLink(o5_1,i11_1); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_BACK)); + CPPUNIT_ASSERT( (pair(o5_1,i11_1)==info.getInfoLink(0,I_BACK)) ); + // back - useless link + OutputPort *o12_1=n12->edAddOutputPort("o12_1",Runtime::_tc_double); graph->edAddLink(o12_1,i11_1); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(2,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_BACK)); CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_BACK_USELESS)); + CPPUNIT_ASSERT( (pair(o5_1,i11_1)==info.getInfoLink(0,I_BACK)) ); + CPPUNIT_ASSERT( (pair(o12_1,i11_1)==info.getInfoLink(0,I_BACK_USELESS)) ); + graph->edAddLink(o11_1,i11_1); + graph->checkConsistency(info); + CPPUNIT_ASSERT_EQUAL(2,(int)info.getNumberOfInfoLinks(I_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfWarnLinksGrp(W_ALL)); CPPUNIT_ASSERT_EQUAL(0,(int)info.getNumberOfErrLinks(E_ALL)); + CPPUNIT_ASSERT_EQUAL(1,(int)info.getNumberOfInfoLinks(I_BACK)); CPPUNIT_ASSERT_EQUAL(2,(int)info.getNumberOfInfoLinks(I_BACK_USELESS)); + delete graph; +} + +void EngineIntegrationTest::testForCheckConsistency2() +{ + LinkInfo info(LinkInfo::ALL_DONT_STOP); + Bloc *graph=new Bloc("Global"); + ToyNode *n1=new ToyNode("T1"); ToyNode *n5=new ToyNode("T5"); ToyNode *n9=new ToyNode("T9"); + ToyNode *n2=new ToyNode("T2"); ToyNode *n6=new ToyNode("T6"); ToyNode *n10=new ToyNode("T10"); + ToyNode *n3=new ToyNode("T3"); ToyNode *n7=new ToyNode("T7"); ToyNode *n11=new ToyNode("T11"); + ToyNode *n4=new ToyNode("T4"); ToyNode *n8=new ToyNode("T8"); ToyNode *n12=new ToyNode("T12"); + graph->edAddChild(n1); graph->edAddChild(n2); graph->edAddChild(n3); graph->edAddChild(n4); graph->edAddChild(n5); graph->edAddChild(n6); + graph->edAddChild(n7); graph->edAddChild(n8); graph->edAddChild(n9); graph->edAddChild(n10); graph->edAddChild(n11); graph->edAddChild(n12); + graph->edAddCFLink(n1,n10); + graph->edAddCFLink(n10,n8); graph->edAddCFLink(n8,n7); graph->edAddCFLink(n10,n7); graph->edAddCFLink(n1,n3); + graph->checkConsistency(info); + set< pair > s=info.getInfoUselessLinks(); set< pair > s2; s2.insert(pair(n10,n7)); + checkSetsEqual< pair >(s,s2); + set s3; set setExpected; map > accelStr; + graph->findAllNodesStartingFrom(n1,s3,accelStr,info); accelStr.clear(); + delete graph; +} diff --git a/src/engine/Test/engineIntegrationTest.hxx b/src/engine/Test/engineIntegrationTest.hxx new file mode 100644 index 000000000..edac72be8 --- /dev/null +++ b/src/engine/Test/engineIntegrationTest.hxx @@ -0,0 +1,109 @@ +#ifndef __ENGINEINTEGRATIONTEST_HXX__ +#define __ENGINEINTEGRATIONTEST_HXX__ + +#include + +namespace YACS +{ + namespace ENGINE + { + class Task; + + class EngineIntegrationTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( EngineIntegrationTest ); + CPPUNIT_TEST( testBloc1 ); + CPPUNIT_TEST( testBloc2 ); + CPPUNIT_TEST( testBloc3 ); + CPPUNIT_TEST( testForLoop1 ); + CPPUNIT_TEST( testForLoop2 ); + CPPUNIT_TEST( testForLoop3 ); + CPPUNIT_TEST( testForLoop4 ); + CPPUNIT_TEST( testForLoop5 ); + CPPUNIT_TEST( testWhileLoop1 ); + CPPUNIT_TEST( testWhileLoop2 ); + CPPUNIT_TEST( testSwitch ); + CPPUNIT_TEST( testSwitch2 ); + CPPUNIT_TEST( testSwitch3 ); + CPPUNIT_TEST( testEdInitOnLoops ); + CPPUNIT_TEST( testLinkUpdate1 ); + CPPUNIT_TEST( testLinkUpdate1DS ); + CPPUNIT_TEST( testLinkUpdate2 ); + CPPUNIT_TEST( testLinkUpdate2DS ); + CPPUNIT_TEST( testInterLoopDFLink ); + CPPUNIT_TEST( deathTestForLinks ); + CPPUNIT_TEST( testForEachLoop1 ); + CPPUNIT_TEST( testForEachLoop2 ); + CPPUNIT_TEST( testForEachLoop3 ); + CPPUNIT_TEST( testForEachLoop4 ); + CPPUNIT_TEST( testForEachLoop5 ); + CPPUNIT_TEST( testForOptimizerLoop1 ); + CPPUNIT_TEST( testForOptimizerLoop2 ); + CPPUNIT_TEST( testForDeployment1 ); + CPPUNIT_TEST( testForDeployment2 ); + CPPUNIT_TEST( testForCheckConsistency1 ); + CPPUNIT_TEST( testForCheckConsistency2 ); + CPPUNIT_TEST_SUITE_END(); + public: + void setUp(); + void tearDown(); + void testBloc1(); + void testBloc2(); + void testBloc3(); + void testSwitch(); + void testSwitch2(); + void testSwitch3(); + void testForLoop1(); + void testForLoop2(); + void testForLoop3(); + void testForLoop4(); + void testForLoop5(); + void testWhileLoop1(); + void testWhileLoop2(); + void testEdInitOnLoops(); + void testLinkUpdate1(); + void testLinkUpdate1DS(); + void testLinkUpdate2(); + void testLinkUpdate2DS(); + void testInterLoopDFLink(); + void deathTestForLinks(); + void testForEachLoop1(); + void testForEachLoop2(); + void testForEachLoop3(); + void testForEachLoop4(); + void testForEachLoop5(); + void testForOptimizerLoop1(); + void testForOptimizerLoop2(); + void testForDeployment1(); + void testForDeployment2(); + void testForCheckConsistency1(); + void testForCheckConsistency2(); + protected: + template + static void checkSetsEqual(const std::set& setToTest1, const std::set& setToTest2); + template + static void checkSetsNotEqual(const std::set& setToTest1, const std::set&setToTest2); + }; + + template + void EngineIntegrationTest::checkSetsEqual(const std::set& setToTest1, const std::set& setToTest2) + { + typename std::set::iterator iter1=setToTest1.begin(); + typename std::set::iterator iter2=setToTest2.begin(); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Sets can't be equal : size different", (int)setToTest1.size(), (int)setToTest2.size()); + for(;iter1!=setToTest1.end();iter1++,iter2++) + CPPUNIT_ASSERT_MESSAGE("Sets can't be equal : value different", *iter1==*iter2); + } + + template + void EngineIntegrationTest::checkSetsNotEqual(const std::set& setToTest1, const std::set&setToTest2) + { + typename std::set::iterator iter1=setToTest1.begin(); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Sets can't be equal : size different", (int)setToTest1.size(), (int)setToTest2.size()); + for(;iter1!=setToTest1.end();iter1++) + CPPUNIT_ASSERT_MESSAGE("Elements is in set : not expected.",setToTest2.find(*iter1)==setToTest2.end()); + } + } +} + +#endif diff --git a/src/engine/Test/engineTest.cxx b/src/engine/Test/engineTest.cxx index 25a91deed..b7828bbc1 100644 --- a/src/engine/Test/engineTest.cxx +++ b/src/engine/Test/engineTest.cxx @@ -5,7 +5,10 @@ #include "ElementaryNode.hxx" #include "Loop.hxx" #include "Switch.hxx" -#include "Runtime.hxx" +#include "VisitorSaveState.hxx" + +#include "SharedPtr.hxx" +#include "RuntimeForEngineTest.hxx" #include "engineTest.hxx" @@ -15,19 +18,13 @@ #include #include +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + 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; @@ -46,16 +43,403 @@ void EngineTest::tearDown() { } +void EngineTest::cleanUp() +{ + map::iterator iter2,iter3; + for(map::iterator iter=_nodeMap.begin();iter!=_nodeMap.end();iter++) + if((*iter).second->getFather()==0) + delete (*iter).second; +} + void EngineTest::checkGetRuntime() { CPPUNIT_ASSERT_THROW(Runtime *myrun = getRuntime(), YACS::Exception); - Runtime::setRuntime(); + RuntimeForEngineTest::setRuntime(); Runtime *myrun1 = getRuntime(); CPPUNIT_ASSERT(myrun1); Runtime *myrun2 = getRuntime(); CPPUNIT_ASSERT_EQUAL(myrun1, myrun2); } +void toto2(void *t) +{ + delete [] (char *)t; +} + +void toto3(void *t) +{ + delete [] (int *)t; +} + +void EngineTest::checkAny1() +{ + char *toto=new char[10]; + strcpy(toto,"lkjlkj"); + Any *tmp=AtomAny::New(toto,toto2);//no copy here + CPPUNIT_ASSERT( tmp->getStringValue() == "lkjlkj"); + CPPUNIT_ASSERT( tmp->getStringValue() == "lkjlkj"); + tmp->incrRef(); + CPPUNIT_ASSERT( tmp->getStringValue() == "lkjlkj"); + CPPUNIT_ASSERT( tmp->getStringValue() == "lkjlkj"); + tmp->decrRef(); + CPPUNIT_ASSERT( tmp->getStringValue() == "lkjlkj"); + CPPUNIT_ASSERT( tmp->getStringValue() == "lkjlkj"); + tmp->decrRef(); + tmp=AtomAny::New("coucou",0); + CPPUNIT_ASSERT( tmp->getStringValue() == "coucou"); + CPPUNIT_ASSERT( tmp->getStringValue() == "coucou"); + tmp->decrRef(); + tmp=AtomAny::New(string("abcdef")); + CPPUNIT_ASSERT( tmp->getStringValue() == "abcdef"); + CPPUNIT_ASSERT( tmp->getStringValue() == "abcdef"); + tmp->decrRef(); + tmp=AtomAny::New("ghijk"); + CPPUNIT_ASSERT( tmp->getStringValue() == "ghijk"); + CPPUNIT_ASSERT( tmp->getStringValue() == "ghijk"); + tmp->decrRef(); + tmp=AtomAny::New((char *)"ghijk"); + CPPUNIT_ASSERT( tmp->getStringValue() == "ghijk"); + CPPUNIT_ASSERT( tmp->getStringValue() == "ghijk"); + tmp->decrRef(); +} + +class A7 +{ +private: + double _d; + int _cnt; +public: + A7(double toto):_d(toto),_cnt(1) { } + static A7 *New(double toto) { return new A7(toto); } + double getToto() const { return _d; } + void setToto(double val) { _d=val; } + void incrRef() { _cnt++; } + void decrRef(); +private: + ~A7() { } +}; + +void A7::decrRef() +{ + if(--_cnt==0) + delete this; +} + + +void checkSharedPtrFct2(const A7& a) +{ + a.getToto(); +} + +void checkSharedPtrFct1(const SharedPtr& a) +{ + checkSharedPtrFct2(a); +} + + +void EngineTest::checkSharedPtr() +{ + SharedPtr titi=A7::New(5.); + SharedPtr toto=A7::New(5.1); + SharedPtr tutu(toto); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,titi->getToto(),1e-12); + titi->setToto(7.1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.1,titi->getToto(),1e-12); + checkSharedPtrFct2(titi); + checkSharedPtrFct2(toto); + titi=toto; + checkSharedPtrFct2(titi); + checkSharedPtrFct2(tutu); +} + +void EngineTest::checkAny2() +{ + double tabStack[8]={1.2, 3.4, 5.6, 7.8, 9.0, 2.3, 4.5, 6.7}; + double *tabHeap=new double[8]; + memcpy(tabHeap,tabStack,8*sizeof(double)); + SequenceAnyPtr tmp(SequenceAny::New(tabStack,8,0)); + CPPUNIT_ASSERT_EQUAL(8,(int)tmp->size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.6,(*tmp)[2]->getDoubleValue(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.7,(*tmp)[7]->getDoubleValue(),1e-12); + AtomAnyPtr tmp2(AtomAny::New(8.9)); + tmp->pushBack(tmp2); + CPPUNIT_ASSERT_EQUAL(9,(int)tmp->size()); + tmp2=AtomAny::New(10.2); + tmp->pushBack(tmp2); + CPPUNIT_ASSERT_EQUAL(10,(int)tmp->size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.9,(*tmp)[8]->getDoubleValue(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(10.2,(*tmp)[9]->getDoubleValue(),1e-12); + tmp->popBack(); + CPPUNIT_ASSERT_EQUAL(9,(int)tmp->size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.9,(*tmp)[8]->getDoubleValue(),1e-12); + tmp2=AtomAny::New(10.3); + tmp->pushBack(tmp2); + CPPUNIT_ASSERT_EQUAL(10,(int)tmp->size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.9,(*tmp)[8]->getDoubleValue(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(10.3,(*tmp)[9]->getDoubleValue(),1e-12); + tmp=SequenceAny::New(tabHeap,8,toto2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.6,(*tmp)[2]->getDoubleValue(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.7,(*tmp)[7]->getDoubleValue(),1e-12); + tmp2=AtomAny::New(8.5); + tmp->pushBack(tmp2); + tmp2=AtomAny::New(10.27); + tmp->pushBack(tmp2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.5,(*tmp)[8]->getDoubleValue(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(10.27,(*tmp)[9]->getDoubleValue(),1e-12); + CPPUNIT_ASSERT_EQUAL(10,(int)tmp->size()); + tmp->popBack(); + CPPUNIT_ASSERT_EQUAL(9,(int)tmp->size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.5,(*tmp)[8]->getDoubleValue(),1e-12); + tmp2=AtomAny::New(10.445); + tmp->pushBack(tmp2); + CPPUNIT_ASSERT_EQUAL(10,(int)tmp->size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.5,(*tmp)[8]->getDoubleValue(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(10.445,(*tmp)[9]->getDoubleValue(),1e-12); + // Idem but for int + int tabStackI[8]={1, 3, 5, 7, 9, 2, 4, 6}; + int *tabHeapI=new int[8]; + memcpy(tabHeapI,tabStackI,8*sizeof(int)); + tmp=SequenceAny::New(tabStackI,8,0); + CPPUNIT_ASSERT_EQUAL(5,(*tmp)[2]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(6,(*tmp)[7]->getIntValue()); + tmp2=AtomAny::New(8); + tmp->pushBack(tmp2); + tmp2=AtomAny::New(25); + tmp->pushBack(tmp2); + CPPUNIT_ASSERT_EQUAL(5,(*tmp)[2]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(6,(*tmp)[7]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(8,(*tmp)[8]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(25,(*tmp)[9]->getIntValue()); + //Same with no copy constructor + tmp=SequenceAny::New(tabHeapI,8,toto3); + CPPUNIT_ASSERT_EQUAL(5,(*tmp)[2]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(6,(*tmp)[7]->getIntValue()); + tmp2=AtomAny::New(8); + tmp->pushBack(tmp2); + tmp2=AtomAny::New(27); + tmp->pushBack(tmp2); + CPPUNIT_ASSERT_EQUAL(5,(*tmp)[2]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(6,(*tmp)[7]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(8,(*tmp)[8]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(27,(*tmp)[9]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(10,(int)tmp->size()); + tmp->popBack(); + CPPUNIT_ASSERT_EQUAL(9,(int)tmp->size()); + CPPUNIT_ASSERT_EQUAL(8,(*tmp)[8]->getIntValue()); + tmp2=AtomAny::New(202); + tmp->pushBack(tmp2); + CPPUNIT_ASSERT_EQUAL(10,(int)tmp->size()); + CPPUNIT_ASSERT_EQUAL(8,(*tmp)[8]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(202,(*tmp)[9]->getIntValue()); + try + { + double d=(*tmp)[2]->getDoubleValue(); + CPPUNIT_ASSERT(0); + } + catch(Exception& e) + { + CPPUNIT_ASSERT(std::string(e.what())=="Value is not a Double"); + } + SequenceAnyPtr tmp3=SequenceAny::New(tmp->getType()); + try + { + tmp3->pushBack(tmp2); + CPPUNIT_ASSERT(0); + } + catch(Exception& e) + { + CPPUNIT_ASSERT(std::string(e.what())=="Invalid runtime of YACS::Any struct : having Int and you want Sequence"); + } + CPPUNIT_ASSERT_EQUAL(0,(int)tmp3->size()); + CPPUNIT_ASSERT_EQUAL(202,(*tmp)[9]->getIntValue()); + tmp3->pushBack(tmp); + CPPUNIT_ASSERT_EQUAL(1,(int)tmp3->size()); + CPPUNIT_ASSERT_EQUAL(202,(*tmp3)[0][9]->getIntValue()); + tmp=SequenceAny::New(tabStackI,8,0); + tmp3->pushBack(tmp); + CPPUNIT_ASSERT_EQUAL(2,(int)tmp3->size()); + CPPUNIT_ASSERT_EQUAL(202,(*tmp3)[0][9]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(7,(*tmp3)[1][3]->getIntValue()); + tmp3->pushBack(tmp); + tmp3->pushBack(tmp); + CPPUNIT_ASSERT_EQUAL(4,(int)tmp3->size()); + CPPUNIT_ASSERT_EQUAL(202,(*tmp3)[0][9]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(7,(*tmp3)[1][3]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(7,(*tmp3)[3][3]->getIntValue()); + tmp2=AtomAny::New(89); + tmp->pushBack(tmp2); + CPPUNIT_ASSERT_EQUAL(4,(int)tmp3->size()); + CPPUNIT_ASSERT_EQUAL(9,(int)tmp->size()); + CPPUNIT_ASSERT_EQUAL(202,(*tmp3)[0][9]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(89,(*tmp3)[1][8]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(89,(*tmp3)[2][8]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(89,(*tmp3)[3][8]->getIntValue()); + tmp3->popBack(); + CPPUNIT_ASSERT_EQUAL(3,(int)tmp3->size()); + CPPUNIT_ASSERT_EQUAL(9,(int)tmp->size()); + CPPUNIT_ASSERT_EQUAL(202,(*tmp3)[0][9]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(89,(*tmp3)[1][8]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(89,(*tmp3)[2][8]->getIntValue()); + SequenceAnyPtr tmp4=(SequenceAny *)tmp3->clone(); + CPPUNIT_ASSERT_EQUAL(3,(int)tmp4->size()); + CPPUNIT_ASSERT_EQUAL(202,(*tmp4)[0][9]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(89,(*tmp4)[1][8]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(89,(*tmp4)[2][8]->getIntValue()); + tmp4->popBack(); + CPPUNIT_ASSERT_EQUAL(2,(int)tmp4->size()); + CPPUNIT_ASSERT_EQUAL(3,(int)tmp3->size()); + CPPUNIT_ASSERT_EQUAL(202,(*tmp3)[0][9]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(202,(*tmp4)[0][9]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(89,(*tmp3)[1][8]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(89,(*tmp4)[1][8]->getIntValue()); + tmp->popBack(); + tmp2=AtomAny::New(107); + tmp->pushBack(tmp2); + CPPUNIT_ASSERT_EQUAL(2,(int)tmp4->size()); + CPPUNIT_ASSERT_EQUAL(3,(int)tmp3->size()); + CPPUNIT_ASSERT_EQUAL(202,(*tmp3)[0][9]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(202,(*tmp4)[0][9]->getIntValue()); + CPPUNIT_ASSERT_EQUAL(107,(*tmp3)[1][8]->getIntValue());//These 2 lines to show that deepCpy has been done + CPPUNIT_ASSERT_EQUAL(89,(*tmp4)[1][8]->getIntValue()); +} + +void EngineTest::checkAny3() +{ + vector vec; + vec.push_back("tata00000"); vec.push_back("toto"); vec.push_back("tutu"); + SequenceAnyPtr tmp(SequenceAny::New(vec)); + CPPUNIT_ASSERT_EQUAL(3,(int)tmp->size()); + CPPUNIT_ASSERT((*tmp)[0]->getStringValue()=="tata00000"); + CPPUNIT_ASSERT((*tmp)[1]->getStringValue()=="toto"); + CPPUNIT_ASSERT((*tmp)[2]->getStringValue()=="tutu"); + tmp->pushBack(AtomAnyPtr(AtomAny::New("abcdefgh"))); + CPPUNIT_ASSERT_EQUAL(4,(int)tmp->size()); + CPPUNIT_ASSERT((*tmp)[0]->getStringValue()=="tata00000"); + CPPUNIT_ASSERT((*tmp)[1]->getStringValue()=="toto"); + CPPUNIT_ASSERT((*tmp)[2]->getStringValue()=="tutu"); + CPPUNIT_ASSERT((*tmp)[3]->getStringValue()=="abcdefgh"); + tmp->popBack(); + CPPUNIT_ASSERT_EQUAL(3,(int)tmp->size()); + CPPUNIT_ASSERT((*tmp)[0]->getStringValue()=="tata00000"); + CPPUNIT_ASSERT((*tmp)[1]->getStringValue()=="toto"); + CPPUNIT_ASSERT((*tmp)[2]->getStringValue()=="tutu"); + tmp->popBack(); + CPPUNIT_ASSERT_EQUAL(2,(int)tmp->size()); + CPPUNIT_ASSERT((*tmp)[0]->getStringValue()=="tata00000"); + CPPUNIT_ASSERT((*tmp)[1]->getStringValue()=="toto"); + tmp->popBack(); + CPPUNIT_ASSERT_EQUAL(1,(int)tmp->size()); + CPPUNIT_ASSERT((*tmp)[0]->getStringValue()=="tata00000"); + tmp->popBack(); + CPPUNIT_ASSERT_EQUAL(0,(int)tmp->size()); + // + vector vec2; + tmp=SequenceAny::New(vec2); + CPPUNIT_ASSERT_EQUAL(0,(int)tmp->size()); + vec2.push_back(true); vec2.push_back(false); vec2.push_back(true); vec2.push_back(true); vec2.push_back(true); + tmp=SequenceAny::New(vec2); + CPPUNIT_ASSERT_EQUAL(5,(int)tmp->size()); + CPPUNIT_ASSERT((*tmp)[0]->getBoolValue() && !(*tmp)[1]->getBoolValue() && (*tmp)[2]->getBoolValue() && (*tmp)[3]->getBoolValue() && (*tmp)[4]->getBoolValue()); + //in perspective of SequenceAny of bool were optimized as std::vector does. + tmp->pushBack(AtomAnyPtr(AtomAny::New(false))); tmp->pushBack(AtomAnyPtr(AtomAny::New(true))); tmp->pushBack(AtomAnyPtr(AtomAny::New(false))); + tmp->pushBack(AtomAnyPtr(AtomAny::New(true))); + CPPUNIT_ASSERT_EQUAL(9,(int)tmp->size()); + CPPUNIT_ASSERT((*tmp)[0]->getBoolValue() && !(*tmp)[1]->getBoolValue() && (*tmp)[2]->getBoolValue() && (*tmp)[3]->getBoolValue() && (*tmp)[4]->getBoolValue()); + CPPUNIT_ASSERT(!(*tmp)[5]->getBoolValue() && (*tmp)[6]->getBoolValue() && !(*tmp)[7]->getBoolValue() && (*tmp)[8]->getBoolValue()); + // + vector vec3; + vec3.push_back(2); vec3.push_back(5); vec3.push_back(7); vec3.push_back(1); vec3.push_back(66); vec3.push_back(26); + tmp=SequenceAny::New(vec3); + CPPUNIT_ASSERT_EQUAL(6,(int)tmp->size()); + CPPUNIT_ASSERT_EQUAL(26,(*tmp)[5]->getIntValue()); + tmp->popBack(); + CPPUNIT_ASSERT_EQUAL(5,(int)tmp->size()); + // + vector vec4; + vec4.push_back(2.78); vec4.push_back(3.14); vec4.push_back(0.07); + tmp=SequenceAny::New(vec4); + CPPUNIT_ASSERT_EQUAL(3,(int)tmp->size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.07,(*tmp)[2]->getDoubleValue(),1e-12); + tmp->popBack(); + CPPUNIT_ASSERT_EQUAL(2,(int)tmp->size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.14,(*tmp)[1]->getDoubleValue(),1e-12); +} + +void EngineTest::checkAny4() +{ + SequenceAnyPtr tmp(SequenceAny::New(Runtime::_tc_int,8)); + tmp=SequenceAny::New(Runtime::_tc_int,4); + tmp=SequenceAny::New(Runtime::_tc_int); + tmp=SequenceAny::New(Runtime::_tc_int,7); + AnyPtr tmp2=AtomAny::New(107); + tmp->setEltAtRank(3,tmp2); + CPPUNIT_ASSERT_EQUAL(107,(*tmp)[3]->getIntValue()); + tmp=SequenceAny::New(Runtime::_tc_string,2); + tmp2=AtomAny::New("titi",0); + tmp->setEltAtRank(1,tmp2); + CPPUNIT_ASSERT((*tmp)[1]->getStringValue()=="titi"); + vector vec4; + vec4.push_back(2.78); vec4.push_back(3.14); vec4.push_back(0.07); + tmp2=SequenceAny::New(vec4); + tmp=SequenceAny::New(tmp2->getType(),3); + tmp->setEltAtRank(0,tmp2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.14,(*tmp)[0][1]->getDoubleValue(),1e-12); + CPPUNIT_ASSERT_EQUAL(3,(int)tmp->size()); + tmp->clear(); + CPPUNIT_ASSERT_EQUAL(0,(int)tmp->size()); + tmp->pushBack(tmp2); + tmp->pushBack(tmp2); + CPPUNIT_ASSERT_EQUAL(2,(int)tmp->size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.14,(*tmp)[1][1]->getDoubleValue(),1e-12); +} + +/*! + * Testing Any::operator == + */ +void EngineTest::checkAny5() +{ + //AtomAny + AnyPtr tmp1=AtomAny::New(107); + AnyPtr tmp2=AtomAny::New(107); + CPPUNIT_ASSERT( *tmp1==*tmp2 ); + tmp1=AtomAny::New(106); + CPPUNIT_ASSERT( ! (*tmp1==*tmp2) ); + CPPUNIT_ASSERT( ! (*tmp2==*tmp1) ); + tmp1=AtomAny::New("toto"); + CPPUNIT_ASSERT( ! (*tmp1==*tmp2) ); + tmp2=AtomAny::New("tot"); + CPPUNIT_ASSERT( ! (*tmp1==*tmp2) ); + tmp2=AtomAny::New("toto"); + CPPUNIT_ASSERT( (*tmp1==*tmp2) ); + tmp1=AtomAny::New("mmmmmlll"); + tmp2=tmp1->clone(); + CPPUNIT_ASSERT( (*tmp1==*tmp2) ); + //SequenceAny + vector vec; + vec.push_back("tata00000"); vec.push_back("toto"); vec.push_back("tutu"); + SequenceAnyPtr tmp3=(SequenceAny::New(vec)); + CPPUNIT_ASSERT_EQUAL(3,(int)tmp3->size()); + CPPUNIT_ASSERT((*tmp3)[0]->getStringValue()=="tata00000"); + CPPUNIT_ASSERT((*tmp3)[1]->getStringValue()=="toto"); + CPPUNIT_ASSERT((*tmp3)[2]->getStringValue()=="tutu"); + AnyPtr tmp4=tmp3->clone(); + CPPUNIT_ASSERT( (*tmp3==*tmp4) ); + tmp3->popBack(); + CPPUNIT_ASSERT( !(*tmp3==*tmp4) ); + tmp1=AtomAny::New("tutu"); + tmp3->pushBack(tmp1); + CPPUNIT_ASSERT( (*tmp3==*tmp4) ); + tmp3->pushBack(tmp1); + CPPUNIT_ASSERT( !(*tmp3==*tmp4) ); + tmp3->popBack(); + CPPUNIT_ASSERT( *tmp3==*tmp4 ); + tmp3->popBack(); + CPPUNIT_ASSERT( !(*tmp3==*tmp4) ); + tmp1=AtomAny::New("tutug"); + tmp3->pushBack(tmp1); + CPPUNIT_ASSERT( !(*tmp3==*tmp4) ); +} + void EngineTest::checkInGateOutGate() { string nodeName = "Node1"; @@ -104,9 +488,9 @@ void EngineTest::checkNodePortNumber() DEBTRACE(" --- check number of ports after ports creation" ); // DEBTRACE(" node1->getNumberOfInputPorts(): " -// << node1->getNumberOfInputPorts()); +// << node1->getNumberOfInputPorts()); // DEBTRACE(" node1->getNumberOfOutputPorts(): " -// << node1->getNumberOfOutputPorts()); +// << node1->getNumberOfOutputPorts()); CPPUNIT_ASSERT(node1->getNumberOfInputPorts() == 4); CPPUNIT_ASSERT(node1->getNumberOfOutputPorts() == 3); } @@ -135,7 +519,7 @@ 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); + YACS::Exception); } void EngineTest::checkRemovePort() @@ -153,7 +537,7 @@ void EngineTest::checkRemovePort() DEBTRACE(" --- check remove wrong port throws exception" ) { CPPUNIT_ASSERT_THROW(node1->edRemovePort(node1->getInputPort("ib1")), - YACS::Exception); + YACS::Exception); } } @@ -207,9 +591,10 @@ void EngineTest::checkAddingTwiceSameNodeInTwoBlocs() bloc2->edAddChild(_nodeMap["Node_3"]); CPPUNIT_ASSERT_THROW(bloc2->edAddChild(_nodeMap["Node_1"]), - YACS::Exception); + YACS::Exception); } + void EngineTest::checkRecursiveBlocs_NumberOfNodes() { Bloc *bloc1 = (Bloc*)_compoMap["bloc1"]; @@ -228,7 +613,7 @@ void EngineTest::checkRecursiveBlocs_NumberOfNodes() CPPUNIT_ASSERT(setelem.size() == 4); for (set::iterator it=setelem.begin(); it!=setelem.end(); it++) { - DEBTRACE(" elem name = " << (*it)->getName()); + DEBTRACE(" elem name = " << (*it)->getName()); } } } @@ -242,15 +627,15 @@ void EngineTest::checkRecursiveBlocs_NumberOfPorts() 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++) + list inset = bloc3->getSetOfInputPort(); + list outset = bloc3->getSetOfOutputPort(); + for (list::iterator it=inset.begin(); it!=inset.end(); it++) { - DEBTRACE(" input port name = " << bloc3->getInputPortName(*it)); + DEBTRACE(" input port name = " << bloc3->getInPortName(*it)); } - for (set::iterator it=outset.begin(); it!=outset.end(); it++) + for (list::iterator it=outset.begin(); it!=outset.end(); it++) { - DEBTRACE(" output port name = " << (*it)->getName()); + DEBTRACE(" output port name = " << bloc3->getOutPortName(*it)); } } } @@ -261,14 +646,71 @@ 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"); + CPPUNIT_ASSERT(_nodeMap["bloc3"]->getInPortName(inport) == "bloc1.Node_1.id1"); + CPPUNIT_ASSERT(((Bloc*)_nodeMap["bloc3"])->getChildName(_nodeMap["Node_1"]) == "bloc1.Node_1"); } void EngineTest::checkGetNameOfPortNotInBloc() { InputPort *inport = _nodeMap["Node_5"]->getInputPort("id1"); - CPPUNIT_ASSERT_THROW(string name = _nodeMap["bloc3"]->getInputPortName(inport), - YACS::Exception); + CPPUNIT_ASSERT_THROW(string name = _nodeMap["bloc3"]->getInPortName(inport), + YACS::Exception); +} + +void EngineTest::checkRemoveNode() +{ + DEBTRACE(" --- bloc and port inventory must be OK after bloc remove" ); + + Bloc* bloc = new Bloc("blocR"); + _nodeMap["blocR"] = bloc; + _compoMap["blocR"] = bloc; + bloc->edAddChild(_nodeMap["Node_5"]); + bloc->edAddChild(_nodeMap["Node_6"]); + bloc->edAddChild(_nodeMap["Node_7"]); + + { + set setelem = _nodeMap["blocR"]->getRecursiveConstituents(); + CPPUNIT_ASSERT(setelem.size() == 3); + + for (set::iterator it=setelem.begin(); it!=setelem.end(); it++) + { + DEBTRACE(" elem name = " << (*it)->getName()); + } + } + + ((Bloc *)_nodeMap["blocR"])->edRemoveChild(_nodeMap["Node_6"]); + + { + set setelem = _nodeMap["blocR"]->getRecursiveConstituents(); + CPPUNIT_ASSERT(setelem.size() == 2); + for (set::iterator it=setelem.begin(); it!=setelem.end(); it++) + { + DEBTRACE(" elem name = " << (*it)->getName()); + DEBTRACE(" elem name in Bloc = " << ((Bloc *)_nodeMap["blocR"])->getChildName(*it)); + } + } + + { + list inset = _nodeMap["blocR"]->getSetOfInputPort(); + list outset = _nodeMap["blocR"]->getSetOfOutputPort(); + CPPUNIT_ASSERT(inset.size() == 8); + CPPUNIT_ASSERT(outset.size() == 6); + for (list::iterator it=inset.begin(); it!=inset.end(); it++) + { + DEBTRACE(" input port name for blocR = " << _nodeMap["blocR"]->getInPortName(*it)); + } + for (list::iterator it=outset.begin(); it!=outset.end(); it++) + { + DEBTRACE(" output port name for blocR = " << _nodeMap["blocR"]->getOutPortName(*it)); + } + } + + ((Bloc *)_nodeMap["blocR"])->edRemoveChild(_nodeMap["Node_5"]); + ((Bloc *)_nodeMap["blocR"])->edRemoveChild(_nodeMap["Node_7"]); + { + set setelem = _nodeMap["blocR"]->getRecursiveConstituents(); + CPPUNIT_ASSERT(setelem.size() == 0); + } } void EngineTest::RecursiveBlocs_multipleRecursion() @@ -318,21 +760,66 @@ void EngineTest::RecursiveBlocs_multipleRecursion() CPPUNIT_ASSERT(setelem.size() == 9); for (set::iterator it=setelem.begin(); it!=setelem.end(); it++) { - DEBTRACE(" elem name = " << (*it)->getName()); + 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++) + list inset = _nodeMap["bloc7"]->getSetOfInputPort(); + list outset = _nodeMap["bloc7"]->getSetOfOutputPort(); + for (list::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)); + DEBTRACE(" input port name for bloc7 = " << _nodeMap["bloc7"]->getInPortName(*it)); + DEBTRACE(" input port name for graphe = " << _nodeMap["graphe"]->getInPortName(*it)); } - for (set::iterator it=outset.begin(); it!=outset.end(); it++) + for (list::iterator it=outset.begin(); it!=outset.end(); it++) { - DEBTRACE(" output port name = " << (*it)->getName()); + DEBTRACE(" output port name for bloc7 = " << _nodeMap["bloc7"]->getOutPortName(*it)); + DEBTRACE(" output port name for graphe = " << _nodeMap["graphe"]->getOutPortName(*it)); } + YACS::ENGINE::VisitorSaveState vst(_compoMap["graphe"]); + vst.openFileDump("dumpState.xml"); + _compoMap["graphe"]->accept(&vst); + vst.closeFileDump(); } } + +void EngineTest::RecursiveBlocs_removeNodes() +{ +// { +// set setNodes = ((Bloc*)_nodeMap["graphe"])->getChildren(); +// for (set::iterator it=setNodes.begin(); it!=setNodes.end(); it++) +// { +// DEBTRACE(" child name = " << (*it)->getName()); +// } +// } + + { + set setNode = ((Bloc*)_nodeMap["graphe"])->getAllRecursiveConstituents(); + CPPUNIT_ASSERT(setNode.size() == 16); + list inset = _nodeMap["bloc7"]->getSetOfInputPort(); + list outset = _nodeMap["bloc7"]->getSetOfOutputPort(); + DEBTRACE(" input port number in graph: " <edRemoveChild(_nodeMap["bloc6"]); + + { + set setNode = ((Bloc*)_nodeMap["graphe"])->getAllRecursiveConstituents(); + CPPUNIT_ASSERT(setNode.size() == 9); + for (set::iterator it=setNode.begin(); it!=setNode.end(); it++) + { + DEBTRACE(" elem name = " << ((Bloc *)_nodeMap["graphe"])->getChildName(*it)); + } + list inset = _nodeMap["bloc7"]->getSetOfInputPort(); + list outset = _nodeMap["bloc7"]->getSetOfOutputPort(); + DEBTRACE(" input port number in graph: " < _nodeMap; diff --git a/src/engine/TypeCode.cxx b/src/engine/TypeCode.cxx index 93e0f31b2..9aeb6ba72 100644 --- a/src/engine/TypeCode.cxx +++ b/src/engine/TypeCode.cxx @@ -1,14 +1,24 @@ #include "TypeCode.hxx" +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" using namespace YACS::ENGINE; using namespace std; +const char *TypeCode::KIND_STR_REPR []={ "None", "Double", "Int", "String", "Bool", "Objref", "Sequence", "Array","Struct" }; + // --- TypeCode -TypeCode::TypeCode(DynType kind) +TypeCode::TypeCode(DynType kind):_kind(kind) +{ +} + +TypeCode::TypeCode(const TypeCode& tc):_kind(tc._kind) { - _kind=kind; } TypeCode::~TypeCode() @@ -20,11 +30,37 @@ DynType TypeCode::kind() const return _kind; } +TypeCode *TypeCode::clone() const +{ + return new TypeCode(*this); +} + +void TypeCode::putReprAtPlace(char *pt, const char *val, bool deepCpy) const +{ + AtomAny::putReprAtPlace(pt,val,this,deepCpy); +} + +void TypeCode::destroyZippedAny(char *data) const +{ + AtomAny::destroyReprAtPlace(data,this); +} + +AnyPtr TypeCode::getOrBuildAnyFromZippedData(char *data) const +{ + return AtomAny::getOrBuildFromData(data,this); +} + const char * TypeCode::name() const throw(Exception) { - throw Exception("No name"); + //throw Exception("No name"); + return id(); } +const char * TypeCode::shortName() const +{ + //throw Exception("No shortName"); + return id(); +} const char * TypeCode::id() const throw(Exception) { @@ -36,146 +72,599 @@ const char * TypeCode::id() const throw(Exception) return "Int"; case String: return "String"; + case Bool: + return "Bool"; default: return ""; } } -int TypeCode::is_a(const char* id) +int TypeCode::isA(const char* id) const throw(Exception) { throw Exception("Not implemented for this type"); } -int TypeCode::is_a(TypeCode* tc) +int TypeCode::isA(const TypeCode* tc) const { if(_kind == tc->kind()) return 1; return 0; } -TypeCode * TypeCode::content_type() const throw(Exception) +//! Check if this TypeCode is adaptable to a given TypeCode (tc) +/*! + * this TypeCode is adaptable to tc if tc type can be converted to this type + * + * \param tc : the TypeCode that must be convertible to this + */ +int TypeCode::isAdaptable(const TypeCode* tc) const +{ + switch(_kind) + { + case Double: + if (tc->kind() == Double) return 1; + if (tc->kind() == Int) return 1; + return 0; + case Int: + if (tc->kind() == Int) return 1; + return 0; + case String: + if (tc->kind() == String) return 1; + return 0; + case Bool: + if (tc->kind() == Bool) return 1; + if (tc->kind() == Int) return 1; + return 0; + default: + //objref, sequence, ... + return 0; + } +} + +unsigned TypeCode::getSizeInByteOfAnyReprInSeq() const +{ + switch(_kind) + { + case Double: + return sizeof(double); + case Int: + return sizeof(int); + case String: + return sizeof(StringOnHeap *); + case Bool: + return sizeof(bool); + default: + return sizeof(void *); + } +} + +const TypeCode * TypeCode::contentType() const throw(Exception) { throw Exception("No content type"); }; -/** - * static factory of object reference types - */ +static inline int validChar0(char c) +{ + return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); +} -TypeCode * TypeCode::interface_tc(const char* id, - const char* name) +static inline int validNextChar(char c) { - return new TypeCode_objref(id, name); -}; + return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || (c == '_') || (c == '/')); +} -TypeCode * TypeCode::interface_tc(const char* id, - const char* name, - list ltc) +static void checkValidName(const char* name) { - return new TypeCode_objref(id, name,ltc); + int ok = 1; + if (*name) + { + if (!validChar0(*name++)) ok = 0; + for(; ok && *name; name++) if (!validNextChar(*name)) ok = 0; + } + if (!ok)throw YACS::Exception("Invalid Name"); +} + +const char *TypeCode::getKindRepr(DynType kind) +{ + return KIND_STR_REPR[(int)kind]; } +const char * TypeCode::getKindRepr() const +{ + return KIND_STR_REPR[(int)_kind]; +} -/** - * static factory of sequence types +//! static factory of object reference type given an id and a name +TypeCode * TypeCode::interfaceTc(const char* id, + const char* name) +{ + checkValidName(name); + return new TypeCodeObjref(id, name); +}; + +//! static factory of object reference type given an id, a name and a list of base types +/*! + * \param id : the id + * \param name : the name + * \param ltc : the list of base types + * + * The name must be a valid one (throw Exception is not) */ +TypeCode * TypeCode::interfaceTc(const char* id, + const char* name, + const std::list& ltc) +{ + checkValidName(name); + return new TypeCodeObjref(id, name,ltc); +} -TypeCode * TypeCode::sequence_tc(const char* id, - const char* name, - TypeCode *content) + +//! static factory of sequence type given an id, a name and a content type +TypeCode * TypeCode::sequenceTc(const char* id, + const char* name, + TypeCode *content) +{ + return new TypeCodeSeq(id, name,content); +}; +//! static factory of struct type given an id and a name +TypeCode * TypeCode::structTc(const char* id, + const char* name) { - return new TypeCode_seq(id, name,content); + return new TypeCodeStruct(id, name); }; -// --- TypeCode_objref +// --- TypeCodeObjref -TypeCode_objref::TypeCode_objref(const char* repositoryId, - const char* name) - : TypeCode(Objref) +TypeCodeObjref::TypeCodeObjref(const char* repositoryId, + const char* name) : TypeCode(Objref) { _repoId = repositoryId; _name = name; + string::size_type debut =_name.find_last_of('/'); + if(debut == std::string::npos)_shortName= name; + else _shortName=_name.substr(debut+1); } -TypeCode_objref::~TypeCode_objref() +TypeCodeObjref::~TypeCodeObjref() { + list::iterator iter; + for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++) + (*iter)->decrRef(); +} + +TypeCode *TypeCodeObjref::clone() const +{ + return new TypeCodeObjref(*this); } -const char * TypeCode_objref::id() const throw(Exception) +void TypeCodeObjref::putReprAtPlace(char *pt, const char *val, bool deepCpy) const +{ + throw Exception("Not implemented yet : YACS::Any for objs ref"); +} + +void TypeCodeObjref::destroyZippedAny(char *data) const +{ + throw Exception("Not implemented yet : YACS::Any for objs ref"); +} + +AnyPtr TypeCodeObjref::getOrBuildAnyFromZippedData(char *data) const +{ + throw Exception("Not implemented yet : YACS::Any for objs ref"); +} + +const char * TypeCodeObjref::id() const throw(Exception) { return _repoId.c_str(); }; -const char * TypeCode_objref::name() const throw(Exception) +const char * TypeCodeObjref::name() const throw(Exception) { return _name.c_str(); } -TypeCode_objref::TypeCode_objref(const char* repositoryId, - const char* name, - list ltc) - : TypeCode(Objref) +const char * TypeCodeObjref::shortName() const +{ + return _shortName.c_str(); +} + +TypeCodeObjref::TypeCodeObjref(const char* repositoryId, + const char* name, + const std::list& ltc) : TypeCode(Objref) { _repoId = repositoryId; _name = name; + string::size_type debut =_name.find_last_of('/'); + if(debut == std::string::npos)_shortName= name; + else _shortName=_name.substr(debut+1); _listOfBases=ltc; + list::const_iterator iter; + for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++) + (*iter)->incrRef(); } -int TypeCode_objref::is_a(const char* id) throw(Exception) +//! Check if this TypeCode is derived from a TypeCode with a given id +/*! + * \param id : a given id + * \return 1 if true, 0 if false + */ +int TypeCodeObjref::isA(const char* id) const throw(Exception) { - if(_repoId.c_str() == id)return 1; - list::iterator iter; + if(_repoId == id)return 1; + list::const_iterator iter; for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++) { - if ((*iter)->is_a(id)) return 1; + if ((*iter)->isA(id)) return 1; } return 0; } -int TypeCode_objref::is_a(TypeCode* tc) throw(Exception) +//! Check if this TypeCode is derived from a given TypeCode +/*! + * \param tc : the given TypeCode + * \return 1 if true, 0 if false + */ +int TypeCodeObjref::isA(const TypeCode* tc) const { - return is_a(tc->id()); + return isA(tc->id()); } -// --- TypeCode_seq +//! Check if this TypeCode is adaptable to a given TypeCode (tc) +/*! + * \param tc : the given TypeCode + * \return 1 if true, 0 if false + */ +int TypeCodeObjref::isAdaptable(const TypeCode* tc) const +{ + if(_kind == tc->kind()) return isA(tc->id()); + return 0; +} + +TypeCodeObjref::TypeCodeObjref(const TypeCodeObjref& other):TypeCode(other),_name(other._name), + _repoId(other._shortName), + _listOfBases(other._listOfBases) +{ + list::const_iterator iter; + for(iter=other._listOfBases.begin();iter!=other._listOfBases.end();iter++) + (*iter)->incrRef(); +} +// --- TypeCodeSeq -TypeCode_seq::TypeCode_seq(const char* repositoryId, - const char* name, - TypeCode *content) - : TypeCode(Sequence) + +//! Create a sequence type with a given name, a given id and a given contained type. +/*! + * \param repositoryId : the given id + * \param name : the given name + * \param content : the given contained TypeCode + */ +TypeCodeSeq::TypeCodeSeq(const char* repositoryId, + const char* name, + const TypeCode *content) : TypeCode(Sequence), _content(content) { _repoId = repositoryId; _name = name; - _content= content; + string::size_type debut =_name.find_last_of('/'); + if(debut == std::string::npos)_shortName= name; + else _shortName=_name.substr(debut+1); + _content->incrRef(); +} + +TypeCodeSeq::~TypeCodeSeq() +{ + ((TypeCode *)_content)->decrRef(); +} + +TypeCode *TypeCodeSeq::clone() const +{ + return new TypeCodeSeq(*this); +} + +void TypeCodeSeq::putReprAtPlace(char *pt, const char *val, bool deepCpy) const +{ + SequenceAny::putReprAtPlace(pt,val,this,deepCpy); } -TypeCode_seq::~TypeCode_seq() +void TypeCodeSeq::destroyZippedAny(char *data) const { + SequenceAny::destroyReprAtPlace(data,this); } -const char * TypeCode_seq::id() const throw(Exception) +AnyPtr TypeCodeSeq::getOrBuildAnyFromZippedData(char *data) const +{ + return SequenceAny::getOrBuildFromData(data,this); +} + +const char * TypeCodeSeq::id() const throw(Exception) { return _repoId.c_str(); } -const char * TypeCode_seq::name() const throw(Exception) +const char * TypeCodeSeq::name() const throw(Exception) { return _name.c_str(); } +const char * TypeCodeSeq::shortName() const +{ + return _shortName.c_str(); +} -TypeCode * TypeCode_seq::content_type() const throw(Exception) +const TypeCode * TypeCodeSeq::contentType() const throw(Exception) { return _content; } -int TypeCode_seq::is_a(TypeCode* tc) +int TypeCodeSeq::isA(const TypeCode* tc) const +{ + if(_kind == tc->kind()) + return _content->isA(tc->contentType()); + return 0; +} + +//! Check if this TypeCode is adaptable to a given TypeCode (tc) +/*! + * \param tc : the given TypeCode + * \return 1 if true, 0 if false + */ +int TypeCodeSeq::isAdaptable(const TypeCode* tc) const { if(_kind == tc->kind()) + return contentType()->isAdaptable(tc->contentType()); + return 0; +} + +TypeCodeSeq::TypeCodeSeq(const TypeCodeSeq& tc):TypeCode(tc), + _name(tc._name),_shortName(tc._shortName), + _repoId(tc._repoId), + _content(tc._content) +{ + _content->incrRef(); +} + +// --- TypeCodeArray + + +//! Create an Array type with a given name, a given id and a given contained type. +/*! + * \param repositoryId : the given id + * \param name : the given name + * \param content : the given contained TypeCode + */ +TypeCodeArray::TypeCodeArray(const char* repositoryId, + const char* name, + const TypeCode *content, + unsigned staticLgth) : TypeCode(Array), _content(content),_staticLgth(staticLgth) +{ + _repoId = repositoryId; + _name = name; + string::size_type debut =_name.find_last_of('/'); + if(debut == std::string::npos)_shortName= name; + else _shortName=_name.substr(debut+1); + _content->incrRef(); +} + +TypeCodeArray::~TypeCodeArray() +{ + ((TypeCode *)_content)->decrRef(); +} + +TypeCode *TypeCodeArray::clone() const +{ + return new TypeCodeArray(*this); +} + +void TypeCodeArray::putReprAtPlace(char *pt, const char *val, bool deepCpy) const +{ + ArrayAny::putReprAtPlace(pt,val,this,deepCpy); +} + +void TypeCodeArray::destroyZippedAny(char *data) const +{ + ArrayAny::destroyReprAtPlace(data,this); +} + +AnyPtr TypeCodeArray::getOrBuildAnyFromZippedData(char *data) const +{ + return ArrayAny::getOrBuildFromData(data,this); +} + +const char * TypeCodeArray::id() const throw(Exception) +{ + return _repoId.c_str(); +} + +const char * TypeCodeArray::name() const throw(Exception) +{ + return _name.c_str(); +} +const char * TypeCodeArray::shortName() const +{ + return _shortName.c_str(); +} + +unsigned TypeCodeArray::getStaticLgth() const +{ + return _staticLgth; +} + +const TypeCode * TypeCodeArray::contentType() const throw(Exception) +{ + return _content; +} + +int TypeCodeArray::isA(const TypeCode* tc) const +{ + if(_kind == tc->kind()) + if(_content->isA(tc->contentType())) + { + const TypeCodeArray *tcC=dynamic_cast(tc); + if(tcC) + return tcC->getStaticLgth()==_staticLgth; + return 0; + } + return 0; +} + +//! Check if this TypeCode is adaptable to a given TypeCode (tc) +/*! + * \param tc : the given TypeCode + * \return 1 if true, 0 if false + */ +int TypeCodeArray::isAdaptable(const TypeCode* tc) const +{ + if(_kind == tc->kind()) + return contentType()->isAdaptable(tc->contentType()); + return 0; +} + +TypeCodeArray::TypeCodeArray(const TypeCodeArray& tc):TypeCode(tc), + _name(tc._name),_shortName(tc._shortName), + _repoId(tc._repoId), + _content(tc._content), + _staticLgth(tc._staticLgth) +{ + _content->incrRef(); +} + +unsigned TypeCodeArray::getSizeInByteOfAnyReprInSeq() const +{ + return _staticLgth*_content->getSizeInByteOfAnyReprInSeq(); +} + +// --- TypeCodeStruct + + +//! Create a struct type with a given name and a given id +/*! + * \param repositoryId : the given id + * \param name : the given name + */ +TypeCodeStruct::TypeCodeStruct(const char* repositoryId, + const char* name) : TypeCode(Struct), _name(name),_repoId(repositoryId) +{ + string::size_type debut =_name.find_last_of('/'); + if(debut == std::string::npos)_shortName= name; + else _shortName=_name.substr(debut+1); +} + +TypeCodeStruct::~TypeCodeStruct() +{ +} + +TypeCode *TypeCodeStruct::clone() const +{ + return new TypeCodeStruct(*this); +} + +TypeCodeStruct::TypeCodeStruct(const TypeCodeStruct& tc):TypeCode(tc), + _name(tc._name),_shortName(tc._shortName), + _repoId(tc._repoId) +{ +} + +void TypeCodeStruct::putReprAtPlace(char *pt, const char *val, bool deepCpy) const +{ + throw Exception("Not implemented yet : YACS::Any for struct"); +} + +void TypeCodeStruct::destroyZippedAny(char *data) const +{ + throw Exception("Not implemented yet : YACS::Any for struct"); +} + +AnyPtr TypeCodeStruct::getOrBuildAnyFromZippedData(char *data) const +{ + throw Exception("Not implemented yet : YACS::Any for struct"); +} + +const char * TypeCodeStruct::id() const throw(Exception) +{ + return _repoId.c_str(); +}; + +const char * TypeCodeStruct::name() const throw(Exception) +{ + return _name.c_str(); +} + +const char * TypeCodeStruct::shortName() const +{ + return _shortName.c_str(); +} + +//! Check if this TypeCode is derived from a TypeCode with a given id +/*! + * \param id : a given id + * \return 1 if true, 0 if false + */ +int TypeCodeStruct::isA(const char* id) const throw(Exception) +{ + if(_repoId.c_str() == id)return 1; + return 0; +} + +//! Check if this TypeCode is derived from a given TypeCode +/*! + * \param tc : the given TypeCode + * \return 1 if true, 0 if false + */ +int TypeCodeStruct::isA(const TypeCode* tc) const +{ + return isA(tc->id()); +} + +//! Check if this TypeCode is adaptable to a given TypeCode (tc) +/*! + * \param tc : the given TypeCode + * \return 1 if true, 0 if false + */ +int TypeCodeStruct::isAdaptable(const TypeCode* tc) const +{ + if(_kind == tc->kind()) return isA(tc->id()); + return 0; +} + +void TypeCodeStruct::addMember(const std::string& name,TypeCode* tc) +{ + DEBTRACE(name << " " << tc->name()); + std::vector< std::pair >::const_iterator iter; + for(iter=_members.begin();iter != _members.end(); iter++) { - if(_content->is_a(tc->content_type())) return 1; + if((*iter).first == name) + throw Exception("Struct member " + name + " already defined"); } - return 0; + _members.push_back(std::pair(name,tc)); } + +int TypeCodeStruct::memberCount() const +{ + return _members.size(); +} + +const char* TypeCodeStruct::memberName(int index) const +{ + if(index > _members.size()) + { + stringstream msg; + msg << "Struct size less than " << index; + msg << " : " << __FILE__ << ":" << __LINE__; + throw Exception(msg.str()); + } + return _members[index].first.c_str(); +} + +TypeCode* TypeCodeStruct::memberType(int index) const +{ + if(index > _members.size()) + { + stringstream msg; + msg << "Struct size less than " << index; + msg << " : " << __FILE__ << ":" << __LINE__; + throw Exception(msg.str()); + } + return _members[index].second; +} + + diff --git a/src/engine/TypeCode.hxx b/src/engine/TypeCode.hxx index 430320c8d..222f865c6 100644 --- a/src/engine/TypeCode.hxx +++ b/src/engine/TypeCode.hxx @@ -1,9 +1,9 @@ #ifndef __TYPECODE_HXX__ #define __TYPECODE_HXX__ -//#include // here, to avoid warning: "_POSIX_C_SOURCE" redefined - +#include "RefCounter.hxx" #include "Exception.hxx" +#include "Any.hxx" #include #include @@ -12,91 +12,207 @@ namespace YACS { namespace ENGINE { + class Visitor; typedef enum { - None = 0, - Double = 1, - Int = 2, - String = 3, - Bool = 4, - Objref = 5, - Sequence = 6 + None = 0, + Double = 1, + Int = 2, + String = 3, + Bool = 4, + Objref = 5, + Sequence = 6, + Array = 7, + Struct = 8 } DynType; // typedef enum DynType StreamType; - class TypeCode_objref; - - class TypeCode + class TypeCodeObjref; + +/*! \brief Base class for all type objects. + * + * \ingroup TypeCodes + * + * All type objects should be a subclass of TypeCode. Some type objects, + * TypeCodeObjref for example, represent one individual type. Other type + * objects, such as TypeCodeSeq, are composite types (sequence, here) + * + * \see TypeCodeObjref + * \see TypeCodeSeq + * \see TypeCodeStruct + * \see TypeCodeArray + */ + class TypeCode : public RefCounter { public: TypeCode(DynType kind); - virtual ~TypeCode(); DynType kind() const; - + const char * getKindRepr() const; + + virtual TypeCode *clone() const; + virtual void putReprAtPlace(char *pt, const char *val, bool deepCpy) const; + virtual void destroyZippedAny(char *data) const; + virtual AnyPtr getOrBuildAnyFromZippedData(char *data) const; virtual const char * name() const throw(Exception); + virtual const char * shortName() const; 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); + virtual const TypeCode * contentType() const throw(Exception); + virtual int isA(const char* repositoryId) const throw(Exception); + virtual int isA(const TypeCode* tc) const ; + virtual int isAdaptable(const TypeCode* tc) const; + virtual unsigned getSizeInByteOfAnyReprInSeq() const; + + static const char *getKindRepr(DynType kind); + static TypeCode * interfaceTc(const char* id, const char* name); + static TypeCode * interfaceTc(const char* id, const char* name, const std::list& ltc); + static TypeCode * sequenceTc (const char* id, const char* name, TypeCode *content); + static TypeCode * structTc (const char* id, const char* name); protected: // --- These operators are placed here to avoid them being used externally TypeCode(const TypeCode& tc); TypeCode& operator=(const TypeCode& tc); - TypeCode() {} - + virtual ~TypeCode(); + protected: DynType _kind; + static const char *KIND_STR_REPR []; }; - class TypeCode_objref: public TypeCode +/*! \brief Class for reference objects. + * + * \ingroup TypeCodes + * + */ + class TypeCodeObjref: public TypeCode { + friend class Visitor; public: - TypeCode_objref(const char* repositoryId, const char* name); + TypeCodeObjref(const char* repositoryId, const char* name); - TypeCode_objref(const char* repositoryId, const char* name, std::list ltc); - virtual ~TypeCode_objref(); + TypeCodeObjref(const char* repositoryId, const char* name, const std::list& ltc); + TypeCode *clone() const; + void putReprAtPlace(char *pt, const char *val, bool deepCpy) const; + void destroyZippedAny(char *data) const; + AnyPtr getOrBuildAnyFromZippedData(char *data) const; 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); - + const char * shortName() const; + int isA(const char* repositoryId) const throw(Exception); + virtual int isA(const TypeCode* tc) const ; + virtual int isAdaptable(const TypeCode* tc) const; + protected: + ~TypeCodeObjref(); + TypeCodeObjref(const TypeCodeObjref& other); private: - TypeCode_objref() {} - std::string _name; + std::string _shortName; std::string _repoId; - std::list _listOfBases; + std::list _listOfBases; }; - class TypeCode_seq: public TypeCode +/*! \brief Class for sequence objects. + * + * \ingroup TypeCodes + * + */ + class TypeCodeSeq: public TypeCode { public: - TypeCode_seq(const char* repositoryId, const char* name, TypeCode *content); - virtual ~TypeCode_seq(); + TypeCodeSeq(const char* repositoryId, const char* name, const TypeCode *content); + TypeCode *clone() const; + void putReprAtPlace(char *pt, const char *val, bool deepCpy) const; + void destroyZippedAny(char *data) const; + AnyPtr getOrBuildAnyFromZippedData(char *data) const; const char * id() const throw(Exception); const char * name() const throw(Exception); + const char * shortName() const; + + virtual const TypeCode * contentType() const throw(Exception); + virtual int isA(const TypeCode* tc) const ; + virtual int isAdaptable(const TypeCode* tc) const; + protected: + ~TypeCodeSeq(); + TypeCodeSeq(const TypeCodeSeq& tc); + private: + std::string _name; + std::string _shortName; + std::string _repoId; + const TypeCode *_content; + }; - virtual TypeCode * content_type() const throw(Exception); - virtual int is_a(TypeCode* tc); +/*! \brief Class for array objects. + * + * \ingroup TypeCodes + * + */ + class TypeCodeArray : public TypeCode + { + public: + TypeCodeArray(const char* repositoryId, const char* name, const TypeCode *content, unsigned staticLgth); + TypeCode *clone() const; + void putReprAtPlace(char *pt, const char *val, bool deepCpy) const; + void destroyZippedAny(char *data) const; + AnyPtr getOrBuildAnyFromZippedData(char *data) const; + const char * id() const throw(Exception); + const char * name() const throw(Exception); + const char * shortName() const; + unsigned getStaticLgth() const; + virtual const TypeCode * contentType() const throw(Exception); + virtual int isA(const TypeCode* tc) const ; + virtual int isAdaptable(const TypeCode* tc) const; + unsigned getSizeInByteOfAnyReprInSeq() const; + protected: + ~TypeCodeArray(); + TypeCodeArray(const TypeCodeArray& tc); private: - TypeCode_seq() {} + std::string _name; + std::string _shortName; + std::string _repoId; + unsigned _staticLgth; + const TypeCode *_content; + }; +/*! \brief Class for struct type. + * + * \ingroup TypeCodes + * + */ + class TypeCodeStruct : public TypeCode + { + public: + TypeCodeStruct(const char* repositoryId, const char* name); + TypeCode *clone() const; + void putReprAtPlace(char *pt, const char *val, bool deepCpy) const; + void destroyZippedAny(char *data) const; + AnyPtr getOrBuildAnyFromZippedData(char *data) const; + const char * id() const throw(Exception); + const char * name() const throw(Exception); + const char * shortName() const; + virtual int isA(const char* repositoryId) const throw(Exception); + virtual int isA(const TypeCode* tc) const ; + virtual int isAdaptable(const TypeCode* tc) const; + virtual void addMember(const std::string& name,TypeCode* tc); + int memberCount() const; + const char* memberName(int index) const; + TypeCode* memberType(int index) const; + protected: + ~TypeCodeStruct(); + TypeCodeStruct(const TypeCodeStruct& tc); + private: std::string _name; + std::string _shortName; std::string _repoId; - TypeCode * _content; + std::vector< std::pair > _members; }; + } } #endif diff --git a/src/engine/Visitor.cxx b/src/engine/Visitor.cxx new file mode 100644 index 000000000..ca7b01954 --- /dev/null +++ b/src/engine/Visitor.cxx @@ -0,0 +1,31 @@ + +#include "Visitor.hxx" +#include "Node.hxx" +#include "Proc.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +Visitor::Visitor(ComposedNode *root): _root(root) +{ +} + +std::map Visitor::getNodeProperties(Node *node) +{ + return node->_propertyMap; +} + +std::map Visitor::getTypeCodeMap(Proc *proc) +{ + return proc->typeMap; +} + +std::map Visitor::getContainerMap(Proc *proc) +{ + return proc->containerMap; +} + +std::list Visitor::getListOfBases(TypeCodeObjref *objref) +{ + return objref->_listOfBases; +} diff --git a/src/engine/Visitor.hxx b/src/engine/Visitor.hxx new file mode 100644 index 000000000..22c566765 --- /dev/null +++ b/src/engine/Visitor.hxx @@ -0,0 +1,57 @@ +#ifndef __VISITOR_HXX__ +#define __VISITOR_HXX__ + +#include +#include +#include + +namespace YACS +{ + namespace ENGINE + { + class Node; + class Bloc; + class ElementaryNode; + class ComposedNode; + class ForEachLoop; + class InlineNode; + class InlineFuncNode; + class Loop; + class ForLoop; + class Proc; + class ServiceNode; + class ServiceInlineNode; + class Switch; + class WhileLoop; + class TypeCode; + class TypeCodeObjref; + class Container; + + class Visitor + { + public: + Visitor(ComposedNode *root); + virtual void visitBloc(Bloc *node) = 0; + virtual void visitElementaryNode(ElementaryNode *node) = 0; + virtual void visitForEachLoop(ForEachLoop *node) = 0; + virtual void visitForLoop(ForLoop *node) = 0; + virtual void visitInlineNode(InlineNode *node) = 0; + virtual void visitInlineFuncNode(InlineFuncNode *node) = 0; + virtual void visitLoop(Loop *node) = 0; + virtual void visitProc(Proc *node) = 0; + virtual void visitServiceNode(ServiceNode *node) = 0; + virtual void visitServiceInlineNode(ServiceInlineNode *node) = 0; + virtual void visitSwitch(Switch *node) = 0; + virtual void visitWhileLoop(WhileLoop *node) = 0; + + protected: + std::map getNodeProperties(Node *node); + std::map getTypeCodeMap(Proc *proc); + std::map getContainerMap(Proc *proc); + std::list getListOfBases(TypeCodeObjref *objref); + + ComposedNode *_root; + }; + } +} +#endif diff --git a/src/engine/VisitorSaveSchema.cxx b/src/engine/VisitorSaveSchema.cxx new file mode 100644 index 000000000..fd905b3ff --- /dev/null +++ b/src/engine/VisitorSaveSchema.cxx @@ -0,0 +1,886 @@ + +#include "VisitorSaveSchema.hxx" + +#include "ElementaryNode.hxx" +#include "InlineNode.hxx" +#include "ServiceNode.hxx" +#include "ServiceInlineNode.hxx" +#include "Bloc.hxx" +#include "Proc.hxx" +#include "ForEachLoop.hxx" +#include "Loop.hxx" +#include "ForLoop.hxx" +#include "WhileLoop.hxx" +#include "Switch.hxx" +#include "InputPort.hxx" +#include "TypeCode.hxx" +#include "ComponentInstance.hxx" +#include "InputDataStreamPort.hxx" +#include "OutputDataStreamPort.hxx" +#include "Container.hxx" + +#include +#include +#include +#include + +using namespace YACS::ENGINE; +using namespace std; + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +VisitorSaveSchema::VisitorSaveSchema(ComposedNode *root): _root(root), Visitor(root) +{ +} + +VisitorSaveSchema::~VisitorSaveSchema() +{ + if (_out) + { + _out << "" << endl; + _out.close(); + } +} + +void VisitorSaveSchema::openFileSchema(std::string xmlSchema) throw(Exception) +{ + _out.open(xmlSchema.c_str(), ios::out); + if (!_out) + { + string what = "Impossible to open file for writing: " + xmlSchema; + throw Exception(what); + } + _out << "" << endl; + _out << "" << endl; +} + +void VisitorSaveSchema::closeFileSchema() +{ + if (!_out) throw Exception("No file open for save schema"); + _out << "" << endl; + _out.close(); +} + +void VisitorSaveSchema::visitBloc(Bloc *node) +{ + DEBTRACE("START visitBloc " << _root->getChildName(node)); + beginCase(node); + int depth = depthNode(node); + _out << indent(depth) << "getName() << "\""; + if (node->getState() == YACS::DISABLED) + _out << " state=\"disabled\">" << endl; + else + _out << ">" << endl; + node->ComposedNode::accept(this); + writeControls(node); + writeSimpleDataLinks(node); + writeSimpleStreamLinks(node); + _out << indent(depth) << "" << endl; + endCase(node); + DEBTRACE("END visitBloc " << _root->getChildName(node)); +} + +void VisitorSaveSchema::visitElementaryNode(ElementaryNode *node) +{ + DEBTRACE("START visitElementaryNode " << _root->getChildName(node)); + beginCase(node); + writeInputPorts(node); + writeInputDataStreamPorts(node); + writeOutputPorts(node); + writeOutputDataStreamPorts(node); + endCase(node); + DEBTRACE("END visitElementaryNode " << _root->getChildName(node)); +} + +void VisitorSaveSchema::visitForEachLoop(ForEachLoop *node) +{ + DEBTRACE("START visitForEachLoop " << _root->getChildName(node)); + beginCase(node); + int depth = depthNode(node); + + _out << indent(depth) << "getName() << "\""; + AnyInputPort *nbranch = static_cast(node->edGetNbOfBranchesPort()); + if (node->getState() == YACS::DISABLED) + _out << " state=\"disabled\""; + if (!nbranch->isEmpty()) + _out << " nbranch=\"" << nbranch->getIntValue() << "\""; + if (node->edGetSamplePort()) + _out << " type=\"" << node->edGetSamplePort()->edGetType()->name() << "\""; + _out << ">" << endl; + + node->ComposedNode::accept(this); + writeSimpleDataLinks(node); + writeSimpleStreamLinks(node); + _out << indent(depth) << "" << endl; + endCase(node); + DEBTRACE("END visitForEachLoop " << _root->getChildName(node)); +} + +void VisitorSaveSchema::visitForLoop(ForLoop *node) +{ + DEBTRACE("START visitForLoop " << _root->getChildName(node)); + beginCase(node); + int depth = depthNode(node); + AnyInputPort *nsteps = static_cast(node->edGetNbOfTimesInputPort()); + _out << indent(depth) << "getName() << "\""; + if (node->getState() == YACS::DISABLED) + _out << " state=\"disabled\""; + if (nsteps->isEmpty()) + _out << ">" << endl; + else + _out << " nsteps=\"" << nsteps->getIntValue() << "\">" << endl; + node->ComposedNode::accept(this); + writeSimpleDataLinks(node); + writeSimpleStreamLinks(node); + _out << indent(depth) << "" << endl; + endCase(node); + DEBTRACE("END visitForLoop " << _root->getChildName(node)); +} + +void VisitorSaveSchema::visitInlineNode(InlineNode *node) +{ + DEBTRACE("START visitInlineNode " << _root->getChildName(node)); + beginCase(node); + int depth = depthNode(node); + _out << indent(depth) << "getName() << "\""; + if (node->getState() == YACS::DISABLED) + _out << " state=\"disabled\">" << endl; + else + _out << ">" << endl; + _out << indent(depth+1) << "" << endl; + writeInputPorts(node); + writeInputDataStreamPorts(node); + writeOutputPorts(node); + writeOutputDataStreamPorts(node); + _out << indent(depth) << "" << endl; + endCase(node); + DEBTRACE("END visitInlineNode " << _root->getChildName(node)); +} + +void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node) +{ + DEBTRACE("START visitInlineFuncNode " << _root->getChildName(node)); + beginCase(node); + int depth = depthNode(node); + _out << indent(depth) << "getName() << "\""; + if (node->getState() == YACS::DISABLED) + _out << " state=\"disabled\">" << endl; + else + _out << ">" << endl; + _out << indent(depth+1) << "getFname() << "\">" << endl; + _out << indent(depth+2) << "getScript(); + _out << "]]>" << endl; + _out << indent(depth+1) << "" << endl; + writeInputPorts(node); + writeInputDataStreamPorts(node); + writeOutputPorts(node); + writeOutputDataStreamPorts(node); + _out << indent(depth) << "" << endl; + endCase(node); + DEBTRACE("END visitInlineFuncNode " << _root->getChildName(node)); +} + +void VisitorSaveSchema::visitLoop(Loop *node) +{ + DEBTRACE("START visitLoop " << _root->getChildName(node)); + beginCase(node); + int depth = depthNode(node); + node->ComposedNode::accept(this); + writeControls(node); + writeSimpleDataLinks(node); + writeSimpleStreamLinks(node); + endCase(node); + DEBTRACE("END visitLoop " << _root->getChildName(node)); +} + +void VisitorSaveSchema::visitProc(Proc *node) +{ + DEBTRACE("START visitProc " << node->getName()); + beginCase(node); + writeProperties(node); + writeTypeCodes(node); + writeContainers(node); + node->ComposedNode::accept(this); + writeControls(node); + writeSimpleDataLinks(node); + writeSimpleStreamLinks(node); + writeParameters(node); + endCase(node); + DEBTRACE("END visitProc " << node->getName()); +} + +void VisitorSaveSchema::visitServiceNode(ServiceNode *node) +{ + DEBTRACE("START visitServiceNode " << _root->getChildName(node)); + beginCase(node); + int depth = depthNode(node); + _out << indent(depth) << "getName() << "\""; + if (node->getState() == YACS::DISABLED) + _out << " state=\"disabled\">" << endl; + else + _out << ">" << endl; + if (node->getKind() == "XML") + { + _out << indent(depth+1) << "xmlsh" << endl; + _out << indent(depth+1) << "" << node->getRef() << "" << endl; + } + else + { + ComponentInstance *compo = node->getComponent(); + if (_componentInstanceMap.find(compo) == _componentInstanceMap.end()) + { + _out << indent(depth+1) << compo->getFileRepr() << endl; + _componentInstanceMap[compo] = _root->getChildName(node); + Container *cont = compo->getContainer(); + if (cont) + { + map::const_iterator it; + for (it = _containerMap.begin(); it != _containerMap.end(); ++it) + { + if (it->second == cont) break; + } + if (it != _containerMap.end()) + _out << indent(depth+1) << "first << "\"/>" << endl; + } + } + else + { + _out << indent(depth+1) << "" << _componentInstanceMap[compo] << "" << endl; + } + } + _out << indent(depth+1) << "" << node->getMethod() << "" << endl; + + writeInputPorts(node); + writeInputDataStreamPorts(node); + writeOutputPorts(node); + writeOutputDataStreamPorts(node); + _out << indent(depth) << "" << endl; + endCase(node); + DEBTRACE("END visitServiceNode " << _root->getChildName(node)); +} + +void VisitorSaveSchema::visitServiceInlineNode(ServiceInlineNode *node) +{ + DEBTRACE("START visitServiceInlineNode " << _root->getChildName(node)); + beginCase(node); + int depth = depthNode(node); + _out << indent(depth) << "getName() << "\""; + if (node->getState() == YACS::DISABLED) + _out << " state=\"disabled\">" << endl; + else + _out << ">" << endl; + _out << indent(depth+1) << node->getComponent()->getFileRepr() << endl; + _out << indent(depth+1) << "getMethod() << "\">" << endl; + _out << indent(depth+2) << "getScript(); + _out << "]]>" << endl; + _out << indent(depth+1) << "" << endl; + writeInputPorts(node); + writeOutputPorts(node); + _out << indent(depth) << "" << endl; + endCase(node); + DEBTRACE("END visitServiceInlineNode " << _root->getChildName(node)); +} + + +void VisitorSaveSchema::visitSwitch(Switch *node) +{ + DEBTRACE("START visitSwitch " << _root->getChildName(node)); + beginCase(node); + int depth = depthNode(node); + AnyInputPort *condition = static_cast(node->edGetConditionPort()); + _out << indent(depth) << "getName() << "\""; + if (node->getState() == YACS::DISABLED) + _out << " state=\"disabled\""; + if (condition->isEmpty()) + _out << ">" << endl; + else + _out << " select=\"" << condition->getIntValue() << "\">" << endl; + node->ComposedNode::accept(this); + writeControls(node); + writeSimpleDataLinks(node); + writeSimpleStreamLinks(node); + _out << indent(depth) << "" << endl; + endCase(node); + DEBTRACE("END visitSwitch " << _root->getChildName(node)); +} + +void VisitorSaveSchema::visitWhileLoop(WhileLoop *node) +{ + DEBTRACE("START visitWhileLoop " << _root->getChildName(node)); + beginCase(node); + int depth = depthNode(node); + _out << indent(depth) << "getName() << "\""; + if (node->getState() == YACS::DISABLED) + _out << " state=\"disabled\">" << endl; + else + _out << ">" << endl; + node->ComposedNode::accept(this); + writeSimpleDataLinks(node); + writeSimpleStreamLinks(node); + _out << indent(depth) << "" << endl; + endCase(node); + DEBTRACE("END visitWhileLoop " << _root->getChildName(node)); +} + + +void VisitorSaveSchema::writeProperties(Node *node) +{ + int depth = depthNode(node)+1; + map properties = getNodeProperties(node); + map::const_iterator it; + for(it = properties.begin(); it != properties.end(); ++it) + { + _out << indent(depth) << "first + << "\" value=\"" << it->second << "\"/>" << endl; + } +} + +void VisitorSaveSchema::writeTypeCodes(Proc *proc) +{ + int depth = depthNode(proc)+1; + map typeMap = getTypeCodeMap(proc); + map::const_iterator it; + set typeNames; + + // --- force definition of simple types first + + _out << indent(depth) << "" << endl; + _out << indent(depth) << "" << endl; + _out << indent(depth) << "" << endl; + _out << indent(depth) << "" << endl; + typeNames.insert("Bool"); + typeNames.insert("Double"); + typeNames.insert("Int"); + typeNames.insert("String"); + + for (it = typeMap.begin(); it != typeMap.end(); it++) + { + DynType kind = (it->second)->kind(); + string typeId = (it->second)->id(); + switch(kind) + { + case YACS::ENGINE::Double: + { + if (typeNames.find(typeId) == typeNames.end()) + { + typeNames.insert(typeId); + _out << indent(depth) << "" << endl; + } + break; + } + case YACS::ENGINE::Int: + { + if (typeNames.find(typeId) == typeNames.end()) + { + typeNames.insert(typeId); + _out << indent(depth) << "" << endl; + } + break; + } + case YACS::ENGINE::String: + { + if (typeNames.find(typeId) == typeNames.end()) + { + typeNames.insert(typeId); + _out << indent(depth) << "" << endl; + } + break; + } + case YACS::ENGINE::Bool: + { + if (typeNames.find(typeId) == typeNames.end()) + { + typeNames.insert(typeId); + _out << indent(depth) << "" << endl; + } + break; + } + case YACS::ENGINE::Objref: + { + TypeCodeObjref *objref = dynamic_cast(it->second); + assert(objref); + std::list listOfBases = getListOfBases(objref); + _out << indent(depth) << "first << "\" id=\"" + << objref->id() << "\""; + if (listOfBases.empty()) + _out << "/>" << endl; + else + { + _out << ">" << endl; + for(std::list::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il) + { + _out << indent(depth+1) << ""; + _out << (*il)->name(); + _out << "" << endl; + } + _out << indent(depth) << "" << endl; + } + break; + } + case YACS::ENGINE::Sequence: + { + const TypeCode* content = (it->second)->contentType(); + + _out << indent(depth) << "first << "\" content=\"" + << content->name() << "\"/>" << endl; + break; + } + default: + { + string what = "wrong TypeCode: "; + throw Exception(what); + } + } + } +} + +void VisitorSaveSchema::writeContainers(Proc *proc) +{ + int depth = depthNode(proc)+1; + _containerMap = getContainerMap(proc); + map::const_iterator it; + for (it = _containerMap.begin(); it != _containerMap.end(); it++) + { + string name = it->first; + _out << indent(depth) << "" << endl; + _out << indent(depth) << "" << endl; + } +} + + +void VisitorSaveSchema::writeInputPorts(Node *node) +{ + int depth = depthNode(node)+1; + list listOfInputPorts = node->getSetOfInputPort(); + for (list::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it) + { + _out << indent(depth) << "getName() << "\" type=\"" + << (*it)->edGetType()->name() << "\"/>" << endl; + } +} + +void VisitorSaveSchema::writeInputDataStreamPorts(Node *node) +{ + int depth = depthNode(node)+1; + list listOfInputPorts = node->getSetOfInputDataStreamPort(); + for (list::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it) + { + std::map aPropMap = (*it)->getPropertyMap(); + if ( aPropMap.empty() ) + _out << indent(depth) << "getName() << "\" type=\"" + << (*it)->edGetType()->name() << "\"/>" << endl; + else + { + _out << indent(depth) << "getName() << "\" type=\"" + << (*it)->edGetType()->name() << "\">" << endl; + for (std::map::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++) + _out << indent(depth+1) << "" << endl; + _out << indent(depth) << "" << endl; + } + } +} + +void VisitorSaveSchema::writeOutputPorts(Node *node) +{ + int depth = depthNode(node)+1; + list listOfOutputPorts = node->getSetOfOutputPort(); + for (list::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it) + { + _out << indent(depth) << "getName() << "\" type=\"" + << (*it)->edGetType()->name() << "\"/>" << endl; + } +} + +void VisitorSaveSchema::writeOutputDataStreamPorts(Node *node) +{ + int depth = depthNode(node)+1; + list listOfOutputPorts = node->getSetOfOutputDataStreamPort(); + for (list::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it) + { + std::map aPropMap = (*it)->getPropertyMap(); + if ( aPropMap.empty() ) + _out << indent(depth) << "getName() << "\" type=\"" + << (*it)->edGetType()->name() << "\"/>" << endl; + else + { + _out << indent(depth) << "getName() << "\" type=\"" + << (*it)->edGetType()->name() << "\">" << endl; + for (std::map::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++) + _out << indent(depth+1) << "" << endl; + _out << indent(depth) << "" << endl; + } + } +} + +void VisitorSaveSchema::writeControls(ComposedNode *node) +{ + int depth = depthNode(node)+1; + set setOfChildren = node->edGetDirectDescendants(); + for (set::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic) + { + // --- Control links from direct descendant to nodes inside the bloc + set setOfInGates = (*ic)->getOutGate()->edSetInGate(); + for (set::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig) + { + Node *to = (*ig)->getNode(); + if (node->isInMyDescendance(to)) + { + Node *from = (*ic); + _out << indent(depth) << " " << node->getChildName(from) << " "; + _out << "" << node->getChildName(to) << " " << endl; + } + } + // --- Control links from nodes inside the bloc to direct descendant + // avoid links between direct descendants (already done above) + list listOfOutGates = (*ic)->getInGate()->getBackLinks(); + for (list::iterator ig = listOfOutGates.begin(); ig != listOfOutGates.end(); ++ig) + { + Node *from = (*ig)->getNode(); + if ((node->isInMyDescendance(from)) && (from->getFather()->getNumId() != node->getNumId())) + { + Node *to = *ic; + _out << indent(depth) << " " << node->getChildName(from) << " "; + _out << "" << node->getChildName(to) << " " << endl; + } + } + } +} + +/*! + * Write simple data links from and to direct children of node (grand children already done). + * First, for all output ports of direct children, write links where the input port is inside + * the node scope. Keep in memory the links where the input port is outside the node scope. + * Second, retreive links where the output port is inside the scope, using the links kept in memory + * and not yet written. + */ +void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node) +{ + int depth = depthNode(node)+1; + set setOfChildren = node->edGetDirectDescendants(); + + set setOfChildrenPlusSplitters = setOfChildren; + + for (set::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic) + // add "splitter" node of ForEachLoop nodes to the set of children + if ( dynamic_cast( *ic ) ) + setOfChildrenPlusSplitters.insert( (*ic)->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE) ); + + // --- first pass, write links where the input port is inside the node scope. Keep in memory others. + + for (set::iterator ic = setOfChildrenPlusSplitters.begin(); ic != setOfChildrenPlusSplitters.end(); ++ic) + { + Node* from = *ic; + list listOP = from->getLocalOutputPorts(); + for (list::iterator io = listOP.begin(); io != listOP.end(); ++io) + { + OutputPort* anOP = *io; + set setIP = anOP->edSetInPort(); + for (set::iterator iip = setIP.begin(); iip != setIP.end(); ++iip) + { + InPort *anIP = *iip; + Node* to = anIP->getNode(); + cerr << "from " << from->getName() << " outputPort " << anOP->getName() + << " to " << to->getName() << " inputPort " << anIP->getName() << endl; + Node* child = node->isInMyDescendance(to); + if (child && (child->getNumId() != node->getNumId()) + && (from->getNumId() != to->getNumId())) + { + cerr << "BINGO!" << endl; + + string fromName; + if ( dynamic_cast(from) && dynamic_cast(from->getFather()) ) + fromName = from->getFather()->getName(); + else + fromName = node->getChildName(from); + + string childName; + if ( dynamic_cast(to) && dynamic_cast(to->getFather()) ) + childName = node->getChildName(to->getFather()); + else + childName = node->getChildName(to); + _out << indent(depth) << "" << endl; + _out << indent(depth+1) << "" << fromName << " "; + _out << "" << anOP->getName() << "" << endl; + _out << indent(depth+1) << "" << childName << " "; + _out << "" << anIP->getName() << "" << endl; + _out << indent(depth) << "" << endl; + } + else + { // --- store info to create the link later, given the input port + cerr << "For later" << endl; + struct DataLinkInfo aLink = { from, to, anOP, anIP, false }; + _mapOfDLtoCreate.insert(make_pair(anIP->getNumId(), aLink)); + } + } + } + } + + // --- second pass, retreive links where the output port is inside the scope. + + if (!dynamic_cast(node)) // xml parser does not take into account datalinks in a switch context + { + std::multimap::iterator pos; + for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end(); ++pos) + { + Node* to = (pos->second).to; + Node* child = node->isInMyDescendance(to); + if (child && (child->getNumId() != node->getNumId())) + { + InPort* anIP = (pos->second).inp; + int portId = anIP->getNumId(); + Node* from = (pos->second).from; + child = node->isInMyDescendance(from); + if (child && (child->getNumId() != node->getNumId())) + if((from->getNumId() != to->getNumId()) || dynamic_cast(node)) + { + string childName = node->getChildName(from); + OutPort *anOP = (pos->second).outp; + (pos->second).toDelete = true; + _out << indent(depth) << "" << endl; + _out << indent(depth+1) << "" << childName << " "; + _out << "" << anOP->getName() << "" << endl; + _out << indent(depth+1) << "" << node->getChildName(to) << " "; + _out << "" << anIP->getName() << "" << endl; + _out << indent(depth) << "" << endl; + } + } + } + + // --- remove the link written from the multimap + + for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end();) + { + if ((pos->second).toDelete) + _mapOfDLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting! + else + ++pos; + } + } +} + +void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node) +{ + int depth = depthNode(node)+1; + set setOfChildren = node->edGetDirectDescendants(); + + // --- first pass, write links where the input port is inside the node scope. Keep in memory others. + + for (set::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic) + { + Node* from = *ic; + if ( dynamic_cast(from) ) continue; + list listOP = from->getSetOfOutputDataStreamPort(); + for (list::iterator io = listOP.begin(); io != listOP.end(); ++io) + { + OutputDataStreamPort* anOP = *io; + set setIP = anOP->edSetInPort(); + for (set::iterator iip = setIP.begin(); iip != setIP.end(); ++iip) + { + InPort *anIP = *iip; + Node* to = anIP->getNode(); + cerr << "from " << from->getName() << " outputPort " << anOP->getName() + << " to " << to->getName() << " inputPort " << anIP->getName() << endl; + Node* child = node->isInMyDescendance(to); + if (child && (child->getNumId() != node->getNumId()) + && (from->getNumId() != to->getNumId())) + { + cerr << "BINGO!" << endl; + string childName = node->getChildName(to); + _out << indent(depth) << "" << endl; + _out << indent(depth+1) << "" << node->getChildName(from) << " "; + _out << "" << anOP->getName() << "" << endl; + _out << indent(depth+1) << "" << childName << " "; + _out << "" << anIP->getName() << "" << endl; + + std::map aPropMap = anOP->getPropertyMap(); + for (std::map::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++) + _out << indent(depth+1) << "" << endl; + + _out << indent(depth) << "" << endl; + } + else + { // --- store info to create the link later, given the input port + cerr << "For later" << endl; + struct StreamLinkInfo aLink = { from, to, anOP, anIP, false }; + _mapOfSLtoCreate.insert(make_pair(anIP->getNumId(), aLink)); + } + } + } + } + + // --- second pass, retreive links where the output port is inside the scope. + + if (!dynamic_cast(node)) // xml parser does not take into account datalinks in a switch context + { + std::multimap::iterator pos; + for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end(); ++pos) + { + Node* to = (pos->second).to; + Node* child = node->isInMyDescendance(to); + if (child && (child->getNumId() != node->getNumId())) + { + InPort* anIP = (pos->second).inp; + int portId = anIP->getNumId(); + Node* from = (pos->second).from; + child = node->isInMyDescendance(from); + if (child && (child->getNumId() != node->getNumId())) + if((from->getNumId() != to->getNumId()) || dynamic_cast(node)) + { + string childName = node->getChildName(from); + OutputDataStreamPort *anOP = (pos->second).outp; + (pos->second).toDelete = true; + _out << indent(depth) << "" << endl; + _out << indent(depth+1) << "" << childName << " "; + _out << "" << anOP->getName() << "" << endl; + _out << indent(depth+1) << "" << node->getChildName(to) << " "; + _out << "" << anIP->getName() << "" << endl; + + std::map aPropMap = anOP->getPropertyMap(); + for (std::map::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++) + _out << indent(depth+1) << "" << endl; + + _out << indent(depth) << "" << endl; + } + } + } + + // --- remove the link written from the multimap + + for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end();) + { + if ((pos->second).toDelete) + _mapOfSLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting! + else + ++pos; + } + } +} + +std::set VisitorSaveSchema::getAllNodes(ComposedNode *node) +{ + set ret; + set setOfNode = node->edGetDirectDescendants(); + for(set::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++) + { + if ( dynamic_cast (*iter) ) + { + set myCurrentSet = getAllNodes(dynamic_cast (*iter)); + ret.insert(myCurrentSet.begin(),myCurrentSet.end()); + ret.insert(*iter); + } + else + { + set myCurrentSet=(*iter)->getRecursiveConstituents(); + ret.insert(myCurrentSet.begin(),myCurrentSet.end()); + ret.insert(*iter); + } + } + return ret; +} + +void VisitorSaveSchema::writeParameters(Proc *proc) +{ + // set nodeSet = proc->getAllRecursiveConstituents(); + set nodeSet = getAllNodes(proc); + for (set::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter) + { +// ElementaryNode *node = dynamic_cast(*iter); +// if (node) +// writeParametersNode(proc,node); + writeParametersNode(proc,(*iter)); + } +} + +void VisitorSaveSchema::writeParametersNode(ComposedNode *proc, Node *node) +{ + int depth = 1; + list setOfInputPort = node->getLocalInputPorts(); + if (ForEachLoop* foreach = dynamic_cast(node)) + { + DEBTRACE("writeParametersNode foreach"); + setOfInputPort.push_back( foreach->edGetSeqOfSamplesPort()); + } + list::iterator iter; + for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); ++iter) + { + if (!(*iter)->isEmpty()) + { + _out << indent(depth) << "" << endl; + _out << indent(depth+1) << "" << proc->getChildName(node) << ""; + _out << "" << (*iter)->getName() << "" <dump(); + } + catch (YACS::Exception &e) + { + _out << "" << endl; + } + _out << indent(depth) << "" << endl; + } + } +} + +void VisitorSaveSchema::beginCase(Node* node) +{ + Switch *myFather =dynamic_cast(node->getFather()); + if (myFather) + { + int depth = depthNode(node) -1; + int myCase = myFather->getRankOfNode(node); + if (myCase == Switch::ID_FOR_DEFAULT_NODE) + _out << indent(depth) << "" << endl; + else + _out << indent(depth) << "" << endl; + } +} + +void VisitorSaveSchema::endCase(Node* node) +{ + Switch *myFather =dynamic_cast(node->getFather()); + if (myFather) + { + int depth = depthNode(node) -1; + int myCase = myFather->getRankOfNode(node); + if (myCase == Switch::ID_FOR_DEFAULT_NODE) + _out << indent(depth) << "" << endl; + else + _out << indent(depth) << "" << endl; + } +} + +int VisitorSaveSchema::depthNode(Node* node) +{ + int depth = 0; + ComposedNode *father = node->getFather(); + while (father) + { + depth +=1; + if (dynamic_cast(father)) depth +=1; + if (father->getNumId() == _root->getNumId()) break; + father = father->getFather(); + } + return depth; +} + +SchemaSave::SchemaSave(Proc* proc): _p(proc) +{ + assert(_p); +} + +void SchemaSave::save(std::string xmlSchemaFile) +{ + VisitorSaveSchema vss(_p); + vss.openFileSchema(xmlSchemaFile); + _p->accept(&vss); + vss.closeFileSchema(); +} diff --git a/src/engine/VisitorSaveSchema.hxx b/src/engine/VisitorSaveSchema.hxx new file mode 100644 index 000000000..d8673a668 --- /dev/null +++ b/src/engine/VisitorSaveSchema.hxx @@ -0,0 +1,98 @@ +#ifndef __VISITOR_SAVESCHEMA_HXX__ +#define __VISITOR_SAVESCHEMA_HXX__ + +#include "Visitor.hxx" +#include "Exception.hxx" + +#include +#include +#include +#include + +namespace YACS +{ + namespace ENGINE + { + class OutputPort; + class OutputDataStreamPort; + class InPort; + class ComponentInstance; + + struct DataLinkInfo + { + Node* from; + Node* to; + OutputPort* outp; + InPort* inp; + bool toDelete; + }; + + struct StreamLinkInfo + { + Node* from; + Node* to; + OutputDataStreamPort* outp; + InPort* inp; + bool toDelete; + }; + + class VisitorSaveSchema: public Visitor + { + public: + VisitorSaveSchema(ComposedNode *root); + virtual ~VisitorSaveSchema(); + void openFileSchema(std::string xmlDump) throw(Exception); + void closeFileSchema(); + virtual void visitBloc(Bloc *node); + virtual void visitElementaryNode(ElementaryNode *node); + virtual void visitForEachLoop(ForEachLoop *node); + virtual void visitForLoop(ForLoop *node); + virtual void visitInlineNode(InlineNode *node); + virtual void visitInlineFuncNode(InlineFuncNode *node); + virtual void visitLoop(Loop *node); + virtual void visitProc(Proc *node); + virtual void visitServiceNode(ServiceNode *node); + virtual void visitServiceInlineNode(ServiceInlineNode *node); + virtual void visitSwitch(Switch *node); + virtual void visitWhileLoop(WhileLoop *node); + + protected: + virtual void writeProperties(Node *node); + virtual void writeTypeCodes(Proc *proc); + virtual void writeContainers(Proc *proc); + virtual void writeInputPorts(Node *node); + virtual void writeInputDataStreamPorts(Node *node); // OCC : mkr : add possibility to write input data stream ports + virtual void writeOutputPorts(Node *node); + virtual void writeOutputDataStreamPorts(Node *node); // OCC : mkr : add possibility to write output data stream ports + virtual void writeControls(ComposedNode *node); + virtual void writeSimpleDataLinks(ComposedNode *node); + virtual void writeSimpleStreamLinks(ComposedNode *node); // OCC : mkr : add possibility to write stream links + virtual void writeParameters(Proc *proc); + virtual void writeParametersNode(ComposedNode *proc, Node *node); + virtual void beginCase(Node* node); + virtual void endCase(Node* node); + std::set getAllNodes(ComposedNode *node); + int depthNode(Node* node); + inline std::string indent(int val) + {std::string white; white.append(3*val,' '); return white;}; + + std::ofstream _out; + std::map _nodeStateName; + std::map _containerMap; + std::map _componentInstanceMap; + ComposedNode *_root; + std::multimap _mapOfDLtoCreate; + std::multimap _mapOfSLtoCreate; + }; + + class SchemaSave + { + public: + SchemaSave(Proc* proc); + virtual void save(std::string xmlSchemaFile); + protected: + Proc* _p; + }; + } +} +#endif diff --git a/src/engine/VisitorSaveState.cxx b/src/engine/VisitorSaveState.cxx new file mode 100644 index 000000000..088c102ec --- /dev/null +++ b/src/engine/VisitorSaveState.cxx @@ -0,0 +1,242 @@ + +#include "ElementaryNode.hxx" +#include "Bloc.hxx" +#include "Proc.hxx" +#include "ForEachLoop.hxx" +#include "Loop.hxx" +#include "ForLoop.hxx" +#include "WhileLoop.hxx" +#include "Switch.hxx" +#include "InputPort.hxx" +#include "InlineNode.hxx" +#include "ServiceNode.hxx" +#include "ServiceInlineNode.hxx" + +#include "VisitorSaveState.hxx" + +#include +#include + +using namespace YACS::ENGINE; +using namespace std; + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +VisitorSaveState::VisitorSaveState(ComposedNode *root): Visitor(root) +{ + _nodeStateName[YACS::INITED] ="INITED"; + _nodeStateName[YACS::TOLOAD] ="TOLOAD"; + _nodeStateName[YACS::LOADED] ="LOADED"; + _nodeStateName[YACS::TOACTIVATE] ="TOACTIVATE"; + _nodeStateName[YACS::ACTIVATED] ="ACTIVATED"; + _nodeStateName[YACS::DESACTIVATED] ="DESACTIVATED"; + _nodeStateName[YACS::DONE] ="DONE"; + _nodeStateName[YACS::SUSPENDED] ="SUSPENDED"; + _nodeStateName[YACS::LOADFAILED] ="LOADFAILED"; + _nodeStateName[YACS::EXECFAILED] ="EXECFAILED"; + _nodeStateName[YACS::PAUSE] ="PAUSE"; + _nodeStateName[YACS::INTERNALERR] ="INTERNALERR"; + _nodeStateName[YACS::DISABLED] ="DISABLED"; + _nodeStateName[YACS::FAILED] ="FAILED"; + _nodeStateName[YACS::ERROR] ="ERROR"; +} + +VisitorSaveState::~VisitorSaveState() +{ + if (_out) + { + _out << "" << endl; + _out.close(); + } +} + +void VisitorSaveState::openFileDump(std::string xmlDump) throw(Exception) +{ + _out.open(xmlDump.c_str(), ios::out); + if (!_out) + { + string what = "Impossible to open file for writing: " + xmlDump; + throw Exception(what); + } + _out << "" << endl; + _out << "" << endl; +} + +void VisitorSaveState::closeFileDump() +{ + if (!_out) throw Exception("No file open for dump state"); + _out << "" << endl; + _out.close(); +} + +void VisitorSaveState::visitElementaryNode(ElementaryNode *node) +{ + if (!_out) throw Exception("No file open for dump state"); + string name = _root->getChildName(node); + DEBTRACE("VisitorSaveState::visitElementaryNode --- " << name); + _out << " " << endl; + _out << " " << name << "" << endl; + int nodeState = node->getState(); + _out << " " << _nodeStateName[nodeState] << "" << endl; + + list setOfInputPort = node->getSetOfInputPort(); + list::iterator iter; + for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); iter++) + { + _out << " " << endl; + _out << " " << (*iter)->getName() << "" << endl; + try + { + _out << " "; + _out << (*iter)->dump(); + } + catch (YACS::Exception &e) + { + DEBTRACE("caught YACS:Exception: " << e.what()); + _out << "" << endl; + } + _out << " " << endl; + } + _out << " " << endl; +} + +void VisitorSaveState::visitBloc(Bloc *node) +{ + node->ComposedNode::accept(this); + if (!_out) throw Exception("No file open for dump state"); + string name = _root->getName(); + if (static_cast(node) != _root) name = _root->getChildName(node); + DEBTRACE("VisitorSaveState::visitBloc ------------- " << name); + _out << " " << endl; + _out << " " << name << "" << endl; + _out << " " << _nodeStateName[node->getState()] << "" << endl; + + _out << " " << endl; +} + +void VisitorSaveState::visitProc(Proc *node) +{ + node->ComposedNode::accept(this); + if (!_out) throw Exception("No file open for dump state"); + string name = _root->getName(); + if (static_cast(node) != _root) name = _root->getChildName(node); + DEBTRACE("VisitorSaveState::visitProc ------------- " << name); + _out << " " << endl; + _out << " " << name << "" << endl; + _out << " " << _nodeStateName[node->getState()] << "" << endl; + + _out << " " << endl; +} + +void VisitorSaveState::visitForEachLoop(ForEachLoop *node) +{ + node->ComposedNode::accept(this); + if (!_out) throw Exception("No file open for dump state"); + string name = _root->getName(); + if (static_cast(node) != _root) name = _root->getChildName(node); + DEBTRACE("VisitorSaveState::visitForEachLoop ------ " << name); + _out << " " << endl; + _out << " " << name << "" << endl; + _out << " " << _nodeStateName[node->getState()] << "" << endl; + + _out << " " << endl; +} + +void VisitorSaveState::visitLoop(Loop *node) +{ + node->ComposedNode::accept(this); + if (!_out) throw Exception("No file open for dump state"); + string name = _root->getName(); + if (static_cast(node) != _root) name = _root->getChildName(node); + DEBTRACE("VisitorSaveState::visitLoop ------------- " << name); + _out << " " << endl; + _out << " " << name << "" << endl; + _out << " " << _nodeStateName[node->getState()] << "" << endl; + _out << " " << node->getNbOfTurns() << "" << endl; + + _out << " " << endl; +} + +void VisitorSaveState::visitForLoop(ForLoop *node) +{ + node->ComposedNode::accept(this); + if (!_out) throw Exception("No file open for dump state"); + string name = _root->getName(); + if (static_cast(node) != _root) name = _root->getChildName(node); + DEBTRACE("VisitorSaveState::visitForLoop ---------- " << name); + _out << " " << endl; + _out << " " << name << "" << endl; + _out << " " << _nodeStateName[node->getState()] << "" << endl; + _out << " " << node->getNbOfTurns() << "" << endl; + InputPort * ip = node->edGetNbOfTimesInputPort(); + if (ip->isEmpty()) + throw Exception("NbOfTimesInputPort in forLoop empty, case not handled yet..."); + Any *val = static_cast(ip->get()); + int nsteps = val->getIntValue(); + _out << " " << nsteps << "" << endl; + + _out << " " << endl; +} + +void VisitorSaveState::visitWhileLoop(WhileLoop *node) +{ + node->ComposedNode::accept(this); + if (!_out) throw Exception("No file open for dump state"); + string name = _root->getName(); + if (static_cast(node) != _root) name = _root->getChildName(node); + DEBTRACE("VisitorSaveState::visitWhileLoop -------- " << name); + _out << " " << endl; + _out << " " << name << "" << endl; + _out << " " << _nodeStateName[node->getState()] << "" << endl; + _out << " " << node->getNbOfTurns() << "" << endl; + InputPort * ip = node->edGetConditionPort(); + if (ip->isEmpty()) + throw Exception("condition in WhileLoop empty, case not handled yet..."); + Any *val = static_cast(ip->get()); + bool condition = val->getBoolValue(); + _out << " " << condition << "" << endl; + + _out << " " << endl; +} + +void VisitorSaveState::visitSwitch(Switch *node) +{ + node->ComposedNode::accept(this); + if (!_out) throw Exception("No file open for dump state"); + string name = _root->getName(); + if (static_cast(node) != _root) name = _root->getChildName(node); + DEBTRACE("VisitorSaveState::visitSwitch ----------- " << name); + _out << " " << endl; + _out << " " << name << "" << endl; + _out << " " << _nodeStateName[node->getState()] << "" << endl; + InputPort * ip = node->edGetConditionPort(); + if (ip->isEmpty()) + throw Exception("condition in switch empty, case not handled yet..."); + Any *val = static_cast(ip->get()); + int condition = val->getIntValue(); + _out << " " << condition << "" << endl; + + _out << " " << endl; +} + +void VisitorSaveState::visitInlineNode(InlineNode *node) +{ + visitElementaryNode(node); +} + +void VisitorSaveState::visitInlineFuncNode(InlineFuncNode *node) +{ + visitElementaryNode(node); +} + +void VisitorSaveState::visitServiceNode(ServiceNode *node) +{ + visitElementaryNode(node); +} + + +void VisitorSaveState::visitServiceInlineNode(ServiceInlineNode *node) +{ + visitElementaryNode(node); +} diff --git a/src/engine/VisitorSaveState.hxx b/src/engine/VisitorSaveState.hxx new file mode 100644 index 000000000..279fadd3f --- /dev/null +++ b/src/engine/VisitorSaveState.hxx @@ -0,0 +1,41 @@ +#ifndef __VISITOR_SAVESTATE_HXX__ +#define __VISITOR_SAVESTATE_HXX__ + +#include "Visitor.hxx" +#include "Exception.hxx" + +#include +#include +#include + +namespace YACS +{ + namespace ENGINE + { + class VisitorSaveState: public Visitor + { + public: + VisitorSaveState(ComposedNode *root); + virtual ~VisitorSaveState(); + void openFileDump(std::string xmlDump) throw(Exception); + void closeFileDump(); + virtual void visitBloc(Bloc *node); + virtual void visitElementaryNode(ElementaryNode *node); + virtual void visitForEachLoop(ForEachLoop *node); + virtual void visitForLoop(ForLoop *node); + virtual void visitInlineNode(InlineNode *node); + virtual void visitInlineFuncNode(InlineFuncNode *node); + virtual void visitLoop(Loop *node); + virtual void visitProc(Proc *node); + virtual void visitServiceNode(ServiceNode *node); + virtual void visitServiceInlineNode(ServiceInlineNode *node); + virtual void visitSwitch(Switch *node); + virtual void visitWhileLoop(WhileLoop *node); + + protected: + std::ofstream _out; + std::map _nodeStateName; + }; + } +} +#endif diff --git a/src/engine/WhileLoop.cxx b/src/engine/WhileLoop.cxx new file mode 100644 index 000000000..d20e2f30c --- /dev/null +++ b/src/engine/WhileLoop.cxx @@ -0,0 +1,124 @@ +#include "WhileLoop.hxx" +#include "Runtime.hxx" +#include "OutputPort.hxx" +#include "Visitor.hxx" +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +const char WhileLoop::NAME_OF_INPUT_CONDITION[]="condition"; + +WhileLoop::WhileLoop(const std::string& name):Loop(name),_conditionPort(NAME_OF_INPUT_CONDITION,this) +{ +} + +WhileLoop::WhileLoop(const WhileLoop& other, ComposedNode *father, bool editionOnly):Loop(other,father,editionOnly), + _conditionPort(other._conditionPort,this) +{ +} + +void WhileLoop::init(bool start) +{ + Loop::init(start); + _conditionPort.exInit(start); +} + +void WhileLoop::exUpdateState() +{ + if(_state == YACS::DISABLED) + return; + if(_inGate.exIsReady()) + { + setState(YACS::TOACTIVATE); + _node->exUpdateState(); + if(_conditionPort.isLinkedOutOfScope()) + if(_conditionPort.isEmpty()) + { + delete _nodeForNullTurnOfLoops; + _nodeForNullTurnOfLoops=new FakeNodeForLoop(this,false,true); + } + else + if(!_conditionPort.getValue()) + { + bool normalFinish=getAllOutPortsLeavingCurrentScope().empty(); + delete _nodeForNullTurnOfLoops; + _nodeForNullTurnOfLoops=new FakeNodeForLoop(this,normalFinish); + } + else + { + delete _nodeForNullTurnOfLoops; + _nodeForNullTurnOfLoops=0; + } + } +} + +int WhileLoop::getNumberOfInputPorts() const +{ + return StaticDefinedComposedNode::getNumberOfInputPorts()+1; +} + +Node *WhileLoop::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new WhileLoop(*this,father,editionOnly); +} + +std::list WhileLoop::getSetOfInputPort() const +{ + list ret=StaticDefinedComposedNode::getSetOfInputPort(); + ret.push_back((InputPort *)&_conditionPort); + return ret; +} + +InputPort *WhileLoop::getInputPort(const std::string& name) const throw(Exception) +{ + if(name==NAME_OF_INPUT_CONDITION) + return (InputPort*)&_conditionPort; + return Loop::getInputPort(name); +} + +//! Method used to notify the node that a child node has ended +/*! + * Update the loop state and return the loop change state + * + * \param node : the child node that has ended + * \return the loop state change + */ +YACS::Event WhileLoop::updateStateOnFinishedEventFrom(Node *node) +{ + _nbOfTurns++; + if(!_conditionPort.getValue()) + { + setState(YACS::DONE); + return YACS::FINISH; + } + else + { + node->init(false); + node->exUpdateState(); + } + return YACS::NOEVENT; +} + +void WhileLoop::checkLinkPossibility(OutPort *start, + const std::set& pointsOfViewStart, + InPort *end, + const std::set& pointsOfViewEnd) throw(Exception) +{ + DEBTRACE("WhileLoop::checkLinkPossibility"); +} + +void WhileLoop::accept(Visitor *visitor) +{ + visitor->visitWhileLoop(this); +} + +std::list WhileLoop::getLocalInputPorts() const +{ + list ret; + ret.push_back((InputPort *)&_conditionPort); + return ret; +} diff --git a/src/engine/WhileLoop.hxx b/src/engine/WhileLoop.hxx new file mode 100644 index 000000000..3fa085129 --- /dev/null +++ b/src/engine/WhileLoop.hxx @@ -0,0 +1,43 @@ +#ifndef __WHILELOOP_HXX__ +#define __WHILELOOP_HXX__ + +#include "Loop.hxx" +#include "ConditionInputPort.hxx" + +namespace YACS +{ + namespace ENGINE + { +/*! \brief Class for a while loop + * + * \ingroup Nodes + * + * This node makes steps while the condition is true + * + */ + class WhileLoop : public Loop + { + protected: + static const char NAME_OF_INPUT_CONDITION[]; + ConditionInputPort _conditionPort; + public: + WhileLoop(const WhileLoop& other, ComposedNode *father, bool editionOnly); + WhileLoop(const std::string& name); + void exUpdateState(); + void init(bool start=true); + InputPort *edGetConditionPort() { return &_conditionPort; } + int getNumberOfInputPorts() const; + std::list getSetOfInputPort() const; + InputPort* getInputPort(const std::string& name) const throw(Exception); + std::list getLocalInputPorts() const; + virtual void accept(Visitor *visitor); + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; + void checkLinkPossibility(OutPort *start, const std::set& pointsOfViewStart, + InPort *end, const std::set& pointsOfViewEnd) throw(Exception); + YACS::Event updateStateOnFinishedEventFrom(Node *node); + }; + } +} + +#endif diff --git a/src/engine/pilot.i b/src/engine/pilot.i new file mode 100644 index 000000000..aec9934ec --- /dev/null +++ b/src/engine/pilot.i @@ -0,0 +1,957 @@ +// ---------------------------------------------------------------------------- +%define DOCSTRING +"Pilot docstring +All is needed to create and execute a calculation schema." +%enddef + +%module(directors="1",docstring=DOCSTRING) pilot + +%feature("autodoc", "0"); + +%include std_except.i +%include std_string.i +%include std_map.i +%include std_list.i +%include std_vector.i +%include std_set.i + +// ---------------------------------------------------------------------------- + +%{ +#include "Runtime.hxx" +#include "Loop.hxx" +#include "WhileLoop.hxx" +#include "ForLoop.hxx" +#include "ForEachLoop.hxx" +#include "OptimizerLoop.hxx" +#include "Switch.hxx" +#include "Bloc.hxx" +#include "Proc.hxx" +#include "ElementaryNode.hxx" +#include "InlineNode.hxx" +#include "ServiceNode.hxx" +#include "ComponentInstance.hxx" +#include "Dispatcher.hxx" +#include "ServiceInlineNode.hxx" + +#include "TypeCode.hxx" + +#include "OutPort.hxx" +#include "InputPort.hxx" +#include "OutputPort.hxx" +#include "InputDataStreamPort.hxx" +#include "OutputDataStreamPort.hxx" + +#include "ExecutorSwig.hxx" +#include "Executor.hxx" +#include "Task.hxx" +#include "Scheduler.hxx" +#include "VisitorSaveSchema.hxx" +#include "Container.hxx" + +#include +#include +#include +#include +#include +#include + +using namespace YACS::ENGINE; +using namespace std; + +class InterpreterUnlocker +{ +public: + InterpreterUnlocker() + { + _save = PyEval_SaveThread(); // allow Python threads to run + } + ~InterpreterUnlocker() + { + PyEval_RestoreThread(_save); // restore the thread state + } +private: + PyThreadState *_save; +}; + +#define POINTER_OWN 1 + +namespace YACS +{ + namespace ENGINE + { + class PyObserver:public Observer + { + public: + virtual void notifyObserver(Node* object,const std::string& event) + { + //YACS engine processing is pure C++ : need to take the GIL + PyGILState_STATE gstate = PyGILState_Ensure(); + + try + { + pynotify(object,event); + if (PyErr_Occurred()) + { + // print the exception and clear it + PyErr_Print(); + //do not propagate the python exception (ignore it) + } + } + catch (...) + { + //ignore this exception:probably Swig::DirectorException + if (PyErr_Occurred()) + PyErr_Print(); + } + PyGILState_Release(gstate); + } + virtual void pynotify(Node* object,const std::string& event) + { + //To inherit (Python class) + std::cerr << "pynotify " << event << object << std::endl; + } + }; + } +} + +%} + +%typemap(python,out) std::list +{ + int i; + std::list::iterator iL; + + $result = PyList_New($1.size()); + for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++) + PyList_SetItem($result,i,PyLong_FromLong((*iL))); +} + +%typemap(python,out) std::list +{ + int i; + std::list::iterator iL; + + $result = PyList_New($1.size()); + for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++) + PyList_SetItem($result,i,PyString_FromString((*iL).c_str())); +} + +%typemap(python,in) std::list +{ + /* Check if input is a list */ + if (PyList_Check($input)) + { + int size = PyList_Size($input); + int i = 0; + std::list myList; + $1 = myList; + for (i = 0; i < size; i++) + { + PyObject *o = PyList_GetItem($input,i); + if (PyString_Check(o)) + $1.push_back(std::string(PyString_AsString(PyList_GetItem($input,i)))); + else + { + PyErr_SetString(PyExc_TypeError,"list must contain strings"); + return NULL; + } + } + } + else + { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } +} + +%typemap(python,out) std::set +{ + int i; + std::set::iterator iL; + + $result = PyList_New($1.size()); + PyObject * ob; + for (i=0, iL=$1.begin(); iL!=$1.end(); i++, iL++) + { + if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::Bloc *),0); + else if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::ForLoop *),0); + else if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::WhileLoop *), 0); + else if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::ForEachLoop *), 0); + else if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::Switch *), 0); + else if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::ComposedNode *), 0); + else if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::InlineFuncNode *), 0); + else if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::InlineNode *), 0); + else if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::ServiceNode *), 0); + else if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::ServiceInlineNode *), 0); + else if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::ElementaryNode *), 0); + else + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::Node *), 0); + + PyList_SetItem($result,i,ob); + } +} + +%typemap(python,out) std::set +{ + std::set::iterator iL; + $result = PyList_New(0); + PyObject * ob; + int status; + for (iL=$1.begin(); iL!=$1.end(); iL++) + { + if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::InputPort *), 0); + else if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::InputDataStreamPort *), 0); + else + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::InPort *), 0); + + //ob=swig::from((YACS::ENGINE::InPort *)(*iL)); + + status=PyList_Append($result,ob); + Py_DECREF(ob); + if (status < 0) + { + PyErr_SetString(PyExc_TypeError,"cannot build the inport list"); + return NULL; + } + } +} + +%typemap(python,out) std::set +{ + std::set::iterator iL; + $result = PyList_New(0); + PyObject * ob; + int status; + for (iL=$1.begin(); iL!=$1.end(); iL++) + { + if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::OutputPort *), 0); + else if(dynamic_cast(*iL)) + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::OutputDataStreamPort *), 0); + else + ob=SWIG_NewPointerObj((void*)(*iL),$descriptor(YACS::ENGINE::OutPort *), 0); + + //ob=swig::from((YACS::ENGINE::OutPort *)(*iL)); + + status=PyList_Append($result,ob); + Py_DECREF(ob); + if (status < 0) + { + PyErr_SetString(PyExc_TypeError,"cannot build the outport list"); + return NULL; + } + } +} + +/* + * Exception section + */ +// a general exception handler +%exception { + try + { + $action + } + catch(YACS::Exception& _e) + { + PyErr_SetString(PyExc_ValueError,_e.what()); + return NULL; + } + catch (Swig::DirectorException &e) + { + SWIG_fail; + } +} + +// a specific exception handler = generic + release lock +%exception RunW { + try { + InterpreterUnlocker _l; + $action + } catch(YACS::Exception& _e) { + PyErr_SetString(PyExc_ValueError,_e.what()); + return NULL; + } +} +%exception RunB { + try { + InterpreterUnlocker _l; + $action + } catch(YACS::Exception& _e) { + PyErr_SetString(PyExc_ValueError,_e.what()); + return NULL; + } +} + +%exception setExecMode { + try { + InterpreterUnlocker _l; + $action + } catch(YACS::Exception& _e) { + PyErr_SetString(PyExc_ValueError,_e.what()); + return NULL; + } +} + +%exception resumeCurrentBreakPoint { + try { + InterpreterUnlocker _l; + $action + } catch(YACS::Exception& _e) { + PyErr_SetString(PyExc_ValueError,_e.what()); + return NULL; + } +} + +%exception stopExecution { + try { + InterpreterUnlocker _l; + $action + } catch(YACS::Exception& _e) { + PyErr_SetString(PyExc_ValueError,_e.what()); + return NULL; + } +} + +/* + * End of Exception section + */ + +/* + * Template section + */ + + +%wrapper %{ + /* Modification de la mecanique swig pour caster les objets dans les containers STL + * Probablement trop dependant de swig (desactive) + namespace swig { + template <> struct traits_from { + static PyObject *from(YACS::ENGINE::InPort* val) { + //std::cerr << "typeid: " << typeid(*val).name() << std::endl; + if(dynamic_cast(val)) + return traits_from_ptr::from((YACS::ENGINE::InputPort*)val, 0); + else if(dynamic_cast(val)) + return traits_from_ptr::from((YACS::ENGINE::InputDataStreamPort*)val, 0); + else + return traits_from_ptr::from(val, 0); + } + }; + template <> struct traits_from { + static PyObject *from(YACS::ENGINE::OutPort* val) { + std::cerr << "from:YACS::ENGINE::OutPort*" << std::endl; + std::cerr << "typeid: " << typeid(val).name() << std::endl; + std::cerr << "typeid: " << typeid(*val).name() << std::endl; + std::cerr << val->getNameOfTypeOfCurrentInstance() << std::endl; + std::cerr << dynamic_cast(val) << std::endl; + if(dynamic_cast(val)) + return traits_from_ptr::from((YACS::ENGINE::OutputPort*)val, 0); + else if(dynamic_cast(val)) + return traits_from_ptr::from((YACS::ENGINE::OutputDataStreamPort*)val, 0); + else + return traits_from_ptr::from(val, 0); + } + }; + } + */ +%} + + +%template() std::pair; +%template() std::pair; +%template() std::pair; +%template() std::pair; +%template() std::pair; +%template() std::pair; +%template(TypeList) std::list; +%template(TCmap) std::map; +%template(NODEmap) std::map; +%template(INODEmap) std::map; +%template(SNODEmap) std::map; +%template(strvec) std::vector; +%template(linksvec) std::vector< std::pair >; +%template(linkvec) std::vector< std::pair >; +%template(inlist) std::list; +%template(outlist) std::list; +%template(inputlist) std::list; +%template(outputlist) std::list; +%template(instreamlist) std::list; +%template(outstreamlist) std::list; + +//Pb : cannot iterate with SWIG 1.3.24 +//%template(NODEset) std::set; +//%template(InPortset) std::set; +//%template(OutPortset) std::set; + +/* + * End of Template section + */ + +/* + * Ownership section + */ +//Take ownership : it is not the default (constructor) as it is a factory +%newobject YACS::ENGINE::Runtime::createProc; +%newobject YACS::ENGINE::Runtime::createScriptNode; +%newobject YACS::ENGINE::Runtime::createFuncNode; +%newobject YACS::ENGINE::Runtime::createRefNode; +%newobject YACS::ENGINE::Runtime::createCompoNode; +%newobject YACS::ENGINE::Runtime::createSInlineNode; +%newobject YACS::ENGINE::Runtime::createBloc; +%newobject YACS::ENGINE::Runtime::createForLoop; +%newobject YACS::ENGINE::Runtime::createForEachLoop; +%newobject YACS::ENGINE::Runtime::createWhileLoop; +%newobject YACS::ENGINE::Runtime::createSwitch; + +//Release ownership : transfer it to C++ +%apply SWIGTYPE *DISOWN { YACS::ENGINE::Node *DISOWNnode }; + +//Take ownership : transfer it from C++ (to complete) +%newobject YACS::ENGINE::Loop::edRemoveNode; +%newobject YACS::ENGINE::Switch::edReleaseDefaultNode; +%newobject YACS::ENGINE::Switch::edReleaseCase; +%newobject YACS::ENGINE::DynParaLoop::edRemoveNode; +%newobject YACS::ENGINE::DynParaLoop::edRemoveInitNode; +//No other way to do +%feature("pythonappend") YACS::ENGINE::Bloc::edRemoveChild(Node *node)%{ + args[1].thisown=1 +%} +/* + * End of ownership section + */ + +/* + * Reference counting section + */ +//not well understood +//%feature("ref") YACS::ENGINE::RefCounter "$this->incrRef();" +//%feature("unref") YACS::ENGINE::RefCounter "$this->decrRef();" +/* + * End of Reference counting section + */ + +%feature("director") YACS::ENGINE::PyObserver; +%feature("nodirector") YACS::ENGINE::PyObserver::notifyObserver; +/* +%feature("director:except") { + if ($error != NULL) { + // print the exception and clear it + PyErr_Print(); + //do not propagate the python exception (ignore it) + //throw Swig::DirectorMethodException(); + } +} +*/ + +%include +%include +%include +%include +%include +%include +%include + +%import +%import + + +namespace YACS +{ + namespace ENGINE + { + typedef enum + { + //Problem with None (same name as python) + // None = 0, + Double = 1, + Int = 2, + String = 3, + Bool = 4, + Objref = 5, + Sequence = 6, + Array = 7 + } DynType; + + class TypeCode : public RefCounter + { + public: + TypeCode(DynType kind); + DynType kind() const; + virtual TypeCode *clone() const; + virtual const char * name() ; + virtual const char * shortName() ; + virtual const char * id() ; + virtual const TypeCode * contentType() ; + virtual int isA(const char* repositoryId) ; + virtual int isA(const TypeCode* tc) const; + virtual int isAdaptable(const TypeCode* tc) const; + protected: + TypeCode(const TypeCode& tc); + virtual ~TypeCode(); + }; + + class TypeCodeObjref: public TypeCode + { + public: + TypeCodeObjref(const char* repositoryId, const char* name); + TypeCodeObjref(const char* repositoryId, const char* name, + const std::list& ltc); + protected: + virtual ~TypeCodeObjref(); + }; + + class DeploymentTree + { + public: + DeploymentTree(); + ~DeploymentTree(); + unsigned char appendTask(Task *task, Scheduler *cloner); + // + unsigned getNumberOfCTDefContainer() const; + unsigned getNumberOfRTODefContainer() const; + unsigned getNumberOfCTDefComponentInstances() const; + unsigned getNumberOfRTODefComponentInstances() const; + // + bool presenceOfDefaultContainer() const; + }; + + class Node; + + class Observer + { + public: + virtual void notifyObserver(Node* object,const std::string& event); + virtual ~Observer(); + }; + + class PyObserver:public Observer + { + public: + //virtual void notifyObserver(Node* object,const std::string& event); + virtual void pynotify(Node* object,const std::string& event); + }; + + class Dispatcher + { + public: + static Dispatcher* getDispatcher(); + virtual void dispatch(Node* object,const std::string& event); + virtual void addObserver(Observer* observer,Node* object,const std::string& event); + virtual void removeObserver(Observer* observer,Node* object,const std::string& event); + virtual void printObservers(); + }; + + class Port + { + public: + virtual ~Port(); + Node *getNode() const ; + virtual std::string getNameOfTypeOfCurrentInstance() const; + %extend{ + int __cmp__(Port* other) + { + if(self==other)return 0; + else return 1; + } + long ptr() + { + return (long)self; + } + } + protected: + Port(Node *node); + Port(const Port& other, Node *newHelder); + }; + + class DataPort : public virtual Port + { + public: + static const char NAME[]; + TypeCode* edGetType() const ; + void edSetType(TypeCode* type); + std::string getName() const ; + std::string getNameOfTypeOfCurrentInstance() const; + virtual void edRemoveAllLinksLinkedWithMe() = 0; + protected: + virtual ~DataPort(); + DataPort(const DataPort& other, Node *newHelder); + DataPort(const std::string& name, Node *node, TypeCode* type); + }; + + class InPort; + class OutPort : virtual public DataPort + { + protected: + OutPort(const OutPort& other, Node *newHelder); + OutPort(const std::string& name, Node *node, TypeCode* type); + public: + virtual int edGetNumberOfOutLinks() const; + virtual std::set edSetInPort() const = 0; + virtual bool isAlreadyLinkedWith(InPort *with) const = 0; + virtual void getAllRepresented(std::set& represented) const; + virtual bool addInPort(InPort *inPort) throw(Exception) = 0; + virtual int removeInPort(InPort *inPort, bool forward) throw(Exception) = 0; + virtual ~OutPort(); + std::vector calculateHistoryOfLinkWith(InPort *end); + }; + + class InPort : virtual public DataPort + { + public: + virtual int edGetNumberOfLinks() const; + virtual std::set edSetOutPort() const; + virtual ~InPort(); + protected: + InPort(const InPort& other, Node *newHelder); + InPort(const std::string& name, Node *node, TypeCode* type); + void edRemoveAllLinksLinkedWithMe() throw(Exception); + virtual void edNotifyReferencedBy(OutPort *fromPort); + virtual void edNotifyDereferencedBy(OutPort *fromPort); + virtual void getAllRepresentants(std::set& repr) const; + }; + } +} + +%include +%include +%include +%include + +namespace YACS +{ + namespace ENGINE + { + class InputPort : public DataFlowPort, public InPort + { + public: + std::string getNameOfTypeOfCurrentInstance() const; + template + void edInit(T value); + %template(edInitInt) edInit; + %template(edInitBool) edInit; + %template(edInitString) edInit; + %template(edInitDbl) edInit; + void edInit(const std::string& impl,char* value); + virtual InputPort *clone(Node *newHelder) const = 0; + bool isEmpty(); + virtual void put(const void *data) throw(ConversionException) = 0; + virtual std::string dump(); + protected: + InputPort(const std::string& name, Node *node, TypeCode* type); + }; + + class OutputPort : public DataFlowPort, public OutPort + { + public: + virtual ~OutputPort(); + std::set edSetInPort() const; + bool isAlreadyLinkedWith(InPort *with) const; + bool isAlreadyInSet(InputPort *inputPort) const; + std::string getNameOfTypeOfCurrentInstance() const; + int removeInPort(InPort *inPort, bool forward) throw(Exception); + virtual bool edAddInputPort(InputPort *phyPort) throw(Exception); + virtual int edRemoveInputPort(InputPort *inputPort, bool forward) throw(Exception); + bool addInPort(InPort *inPort) throw(Exception); + void edRemoveAllLinksLinkedWithMe() throw(Exception);//entry point for forward port deletion + virtual void exInit(); + virtual OutputPort *clone(Node *newHelder) const = 0; + virtual void put(const void *data) throw(ConversionException); + virtual std::string dump(); + protected: + OutputPort(const OutputPort& other, Node *newHelder); + OutputPort(const std::string& name, Node *node, TypeCode* type); + }; + + class InputDataStreamPort : public DataStreamPort, public InPort + { + public: + InputDataStreamPort(const std::string& name, Node *node, TypeCode* type); + std::string getNameOfTypeOfCurrentInstance() const; + InputDataStreamPort *clone(Node *newHelder) const; + }; + + class OutputDataStreamPort : public DataStreamPort, public OutPort + { + public: + OutputDataStreamPort(const OutputDataStreamPort& other, Node *newHelder); + OutputDataStreamPort(const std::string& name, Node *node, TypeCode* type); + virtual ~OutputDataStreamPort(); + virtual OutputDataStreamPort *clone(Node *newHelder) const; + std::set edSetInPort() const; + virtual int edGetNumberOfOutLinks() const; + bool isAlreadyLinkedWith(InPort *with) const; + virtual std::string getNameOfTypeOfCurrentInstance() const; + virtual bool addInPort(InPort *inPort) throw(Exception); + virtual bool edAddInputDataStreamPort(InputDataStreamPort *port) throw(ConversionException); + int edRemoveInputDataStreamPort(InputDataStreamPort *inPort, bool forward) throw(Exception); + void edRemoveAllLinksLinkedWithMe() throw(Exception); + int removeInPort(InPort *inPort, bool forward) throw(Exception); + }; + + class ComposedNode; + class ElementaryNode; + + class Node + { + protected: + Node(const std::string& name); + public: + virtual ~Node(); + YACS::StatesForNode getState() ; + virtual YACS::StatesForNode getEffectiveState() ; + std::string getColorState(YACS::StatesForNode state); + InGate *getInGate() ; + OutGate *getOutGate(); + const std::string& getName(); + ComposedNode * getFather() ; + std::set getOutNodes() const; + virtual std::set getRecursiveConstituents() const = 0; + virtual int getNumberOfInputPorts() const = 0; + virtual int getNumberOfOutputPorts() const = 0; + std::list getSetOfInPort() const; + std::list getSetOfOutPort() const; + virtual std::list getSetOfInputPort() const = 0; + virtual std::list getSetOfOutputPort() const = 0; + virtual std::string getInPortName(const InPort *) const = 0; + virtual std::string getOutPortName(const OutPort *) const = 0; + virtual std::list getSetOfInputDataStreamPort() const = 0; + virtual std::list getSetOfOutputDataStreamPort() const = 0; + InPort *getInPort(const std::string& name) const ; + virtual OutPort *getOutPort(const std::string& name) const ; + virtual std::set getAllOutPortsLeavingCurrentScope() const = 0; + virtual std::set getAllInPortsComingFromOutsideOfCurrentScope() const = 0; + virtual InputPort *getInputPort(const std::string& name) const = 0; + virtual OutputPort *getOutputPort(const std::string& name) const = 0; + virtual InputDataStreamPort *getInputDataStreamPort(const std::string& name) const = 0; + virtual OutputDataStreamPort *getOutputDataStreamPort(const std::string& name) const = 0; + std::set getAllAscendanceOf(ComposedNode *levelToStop = 0); + std::string getImplementation(); + virtual ComposedNode *getRootNode() ; + virtual void setProperty(const std::string& name,const std::string& value); + virtual Node *getChildByName(const std::string& name) const = 0; + virtual void sendEvent(const std::string& event); + + %extend{ + int __cmp__(Node* other) + { + if(self==other)return 0; + else return 1; + } + long ptr() + { + return (long)self; + } + } + }; + + class Container + { + public: + virtual bool isAlreadyStarted() const; + virtual std::string getPlacementId() const = 0; + virtual void attachOnCloning() const; + virtual void dettachOnCloning() const; + bool isAttachedOnCloning() const; + protected: + ~Container(); + }; + + class ElementaryNode: public Node, public Task + { + public: + virtual InputPort *edAddInputPort(const std::string& inputPortName, TypeCode* type) ; + virtual OutputPort *edAddOutputPort(const std::string& outputPortName, TypeCode* type) ; + InputPort *getInputPort(const std::string& name) ; + OutputPort *getOutputPort(const std::string& name) ; + InputDataStreamPort *getInputDataStreamPort(const std::string& name) ; + OutputDataStreamPort *getOutputDataStreamPort(const std::string& name) ; + virtual InputDataStreamPort *edAddInputDataStreamPort(const std::string& inputPortDSName, TypeCode* type) ; + virtual OutputDataStreamPort *edAddOutputDataStreamPort(const std::string& outputPortDSName, TypeCode* type) ; + protected: + ElementaryNode(const std::string& name); + }; + + class ComposedNode: public Node, public Scheduler + { + protected: + ComposedNode(const std::string& name); + ComposedNode(const ComposedNode& other, ComposedNode *father); + public: + virtual ~ComposedNode(); + bool isFinished(); + DeploymentTree getDeploymentTree() const; + std::vector getNextTasks(bool& isMore); + void notifyFrom(const Task *sender, YACS::Event event); + bool edAddLink(OutPort *start, InPort *end) throw(Exception); + virtual bool edAddDFLink(OutPort *start, InPort *end) throw(Exception); + bool edAddLink(OutGate *start, InGate *end) throw(Exception); + bool edAddCFLink(Node *nodeS, Node *nodeE) throw(Exception); + void edRemoveLink(OutPort *start, InPort *end) throw(Exception); + void edRemoveLink(OutGate *start, InGate *end) throw(Exception); + virtual bool isRepeatedUnpredictablySeveralTimes() const { return false; } + virtual std::set edGetDirectDescendants() const = 0; + std::set getRecursiveConstituents() const; + std::string getInPortName(const InPort *) const throw (Exception); + std::string getOutPortName(const OutPort *) const throw (Exception); + + int getNumberOfInputPorts() const; + int getNumberOfOutputPorts() const; + std::list getSetOfInputPort() const; + std::list getSetOfOutputPort() const; + std::set getAllOutPortsLeavingCurrentScope() const; + std::set getAllInPortsComingFromOutsideOfCurrentScope() const; + std::list getSetOfInputDataStreamPort() const; + std::list getSetOfOutputDataStreamPort() const; + OutPort *getOutPort(const std::string& name) const throw(Exception); + InputPort *getInputPort(const std::string& name) const throw(Exception); + OutputPort *getOutputPort(const std::string& name) const throw(Exception); + InputDataStreamPort *getInputDataStreamPort(const std::string& name) const throw(Exception); + OutputDataStreamPort *getOutputDataStreamPort(const std::string& name) const throw(Exception); + std::vector< std::pair > getSetOfInternalLinks() const; + std::vector< std::pair > getSetOfLinksLeavingCurrentScope() const; + virtual std::vector< std::pair > getSetOfLinksComingInCurrentScope() const; + // + ComposedNode *getRootNode() throw(Exception); + bool isNodeAlreadyAggregated(Node *node) const; + Node *isInMyDescendance(Node *nodeToTest) const; + std::string getChildName(Node* node) const throw(Exception); + Node *getChildByName(const std::string& name) const throw(Exception); + static ComposedNode *getLowestCommonAncestor(Node *node1, Node *node2) throw(Exception); + void loaded(); + }; + + class Bloc: public ComposedNode + { + public: + Bloc(const std::string& name); + bool edAddChild(Node *DISOWNnode) ; + void edRemoveChild(Node *node) ; + std::set getChildren(); + std::set edGetDirectDescendants() const; + bool isFinished(); + }; + + class Loop : public ComposedNode + { + public: + Loop(const std::string& name); + int getNbOfTurns() ; + void edSetNode(Node *DISOWNnode); + std::set edGetDirectDescendants() const; + Node *edRemoveNode(); + }; + + class ForLoop : public Loop + { + public: + ForLoop(const std::string& name); + InputPort *edGetNbOfTimesInputPort(); + }; + + class WhileLoop : public Loop + { + public: + WhileLoop(const std::string& name); + InputPort *edGetConditionPort(); + }; + + class DynParaLoop : public ComposedNode + { + public: + Node *edRemoveNode(); + Node *edRemoveInitNode(); + Node *edSetNode(Node *DISOWNnode); + Node *edSetInitNode(Node *DISOWNnode); + InputPort *edGetNbOfBranchesPort(); + OutputPort *edGetSamplePort(); + unsigned getNumberOfBranchesCreatedDyn() const throw(Exception); + Node *getChildByNameExec(const std::string& name, unsigned id) const throw(Exception); + protected: + ~DynParaLoop(); + }; + + class ForEachLoop : public DynParaLoop + { + public: + ForEachLoop(const std::string& name, TypeCode *typeOfDataSplitted); + std::set edGetDirectDescendants() const; + InputPort *edGetSeqOfSamplesPort(); + }; + + class Switch : public ComposedNode + { + public: + Switch(const std::string& name); + Node *clone(ComposedNode *father) const; + Node *edSetDefaultNode(Node *DISOWNnode); + Node *edReleaseDefaultNode() ; + Node *edReleaseCase(int caseId) ; + Node *edSetNode(int caseId, Node *DISOWNnode) ; + InputPort *edGetConditionPort(); + std::set edGetDirectDescendants() const; + void checkConsistency(); + }; + + class Proc: public Bloc + { + public: + Proc(const std::string& name); + bool isFinished(); + virtual TypeCode *createType(const std::string& name, const std::string& kind); + virtual TypeCodeObjref *createInterfaceTc(const std::string& id, const std::string& name, + std::list ltc); + virtual TypeCode *createSequenceTc(const std::string& id, const std::string& name, + TypeCode *content); + virtual TypeCode *createStructTc(const std::string& id, const std::string& name); + + virtual TypeCode* getTypeCode(const std::string& name); + virtual void setTypeCode(const std::string& name,TypeCode *t); + + YACS::StatesForNode getNodeState(int numId); + std::string getXMLState(int numId); + std::list getNumIds(); + std::list getIds(); + + std::map typeMap; + std::map nodeMap; + std::map serviceMap; + std::map inlineMap; + std::vector names; + void setName(const std::string& name); + }; + } +} + +%include +%include +%include +%include +%include +%include + +namespace YACS +{ + namespace ENGINE + { + class SchemaSave + { + public: + SchemaSave(Proc* proc); + virtual void save(std::string xmlSchemaFile); + }; + } +} diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am new file mode 100644 index 000000000..5826b30a9 --- /dev/null +++ b/src/gui/Makefile.am @@ -0,0 +1,133 @@ + +include $(top_srcdir)/adm/unix/make_begin.am + +lib_LTLIBRARIES = libYACSGui.la + +# Implementation files +LIBSOURCES = \ + YACSGui_Node.cxx \ + YACSGui_Graph.cxx \ + YACSGui_Module.cxx \ + YACSGui_DataModel.cxx \ + YACSGui_DataObject.cxx \ + YACSGui_Executor.cxx \ + YACSGui_Observer.cxx \ + YACSGui_XMLDriver.cxx \ + YACSGui_Swig.cxx \ + YACSGui_RunMode.cxx + +# Headers +LIBHEADERS = \ + YACSGui_Node.h \ + YACSGui_Graph.h \ + YACSGui_Module.h \ + YACSGui_DataModel.h \ + YACSGui_DataObject.h \ + YACSGui_Executor.h \ + YACSGui_Observer.h \ + YACSGui_XMLDriver.h \ + YACSGui_Swig.h + +# MOC-generated files +MOCSOURCES = \ + YACSGui_Module_moc.cxx \ + YACSGui_Executor_moc.cxx \ + runmode_moc.cxx \ + YACSGui_RunMode_moc.cxx + +# UIC-generated files +runmode.cxx : runmode.h +UISOURCES = runmode.cxx + +# Resources +LIBPOFILES = \ + YACSGui_msg_en.po \ + YACSGui_images.po + +LIBICONS = \ + sample.png \ + ModuleYacs.png \ + SalomeApp.xml \ + YACSGuiCatalog.xml \ + add_in_study.png \ + add_node.png \ + change_informations.png \ + control_view.png \ + export_dataflow.png \ + filter_next_steps.png \ + filter_notification.png \ + full_view.png \ + import_dataflow.png \ + import_superv_dataflow.png \ + insert_file.png \ + kill.png \ + mode_breakpoint.png \ + mode_continue.png \ + modify_dataflow.png \ + modify_superv_dataflow.png \ + new_dataflow.png \ + rebuild_links.png \ + reload.png \ + remote_run.png \ + run.png \ + save_dataflow_state.png \ + step_by_step.png \ + suspend_resume.png \ + table_view.png \ + toggle_stop_on_error.png + +# Add "resources" subdirectory to resource file names +POFILES = $(LIBPOFILES:%=resources/%) +ICONS = $(LIBICONS:%=resources/%) + +libYACSGui_la_SOURCES = $(LIBSOURCES) $(LIBHEADERS) +nodist_libYACSGui_la_SOURCES = $(UISOURCES) $(MOCSOURCES) + +# List all generated files here +BUILT_SOURCES = $(UISOURCES) $(MOCSOURCES) YACSGui_SwigWRAP.cxx + +MYSWIG_FLAGS = -noexcept -I$(srcdir)/../bases + +pkgpython_PYTHON = YACSGui_Swig.py \ + yacsguiloader.py +pkgpyexec_LTLIBRARIES = _YACSGui_Swig.la + +YACSGui_SwigWRAP.cxx:YACSGui_Swig.i YACSGui_Swig.h + $(SWIG) $(SWIG_PYTHON_OPT) $(SWIG_PYTHON_INCLUDES) $(MYSWIG_FLAGS) -o $@ $< + +_YACSGui_Swig_la_SOURCES = \ + YACSGui_SwigWRAP.cxx + +_YACSGui_Swig_la_CXXFLAGS = \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + $(PYTHON_CPPFLAGS) + +_YACSGui_Swig_la_LDFLAGS = -module + +_YACSGui_Swig_la_LIBADD = libYACSGui.la + +libYACSGui_la_LIBADD = \ + ../runtime/libYACSRuntimeSALOME.la \ + ../yacsloader/libYACSloader.la \ + ../prs/libYACSPrs.la \ + ../lineconn2d/libLineConn2d.la \ + ../yacsorb/libYACSorb.la \ + @QT_MT_LIBS@ @GUI_LDFLAGS@ \ + -lQxGraph -lCAM -lsuit -lLightApp -lexpat -lxml2 + +libYACSGui_la_CXXFLAGS = \ + $(THREAD_DEF) \ + $(PYTHON_CPPFLAGS) \ + -I$(KERNEL_ROOT_DIR)/include/salome \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + -I$(srcdir)/../runtime \ + -I$(srcdir)/../yacsloader \ + -I$(srcdir)/../prs \ + -I$(srcdir)/../lineconn2d \ + -I../../idl \ + -I../yacsorb \ + @QT_INCLUDES@ @GUI_CXXFLAGS@ @CAS_CPPFLAGS@ + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/gui/Pascal4.xml b/src/gui/Pascal4.xml new file mode 100644 index 000000000..9f3468c94 --- /dev/null +++ b/src/gui/Pascal4.xml @@ -0,0 +1,741 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node_4_2 collect + node_1_1 node_2_2 + node_1_1 node_2_1 + node_0_0 node_1_1 + node_0_0 node_1_0 + node_3_0 node_4_1 + node_3_0 node_4_0 + node_2_2 node_3_3 + node_2_2 node_3_2 + node_1_0 node_2_0 + node_1_0 node_2_1 + node_4_4 collect + node_2_0 node_3_0 + node_2_0 node_3_1 + node_4_1 collect + node_3_3 node_4_4 + node_3_3 node_4_3 + node_3_1 node_4_2 + node_3_1 node_4_1 + node_3_2 node_4_2 + node_3_2 node_4_3 + node_2_1 node_3_1 + node_2_1 node_3_2 + node_4_3 collect + node_4_0 collect + + node_4_2 c + collect a2 + + + node_1_1 c + node_2_1 b + + + node_1_1 c + node_2_2 a + + + node_0_0 c + node_1_1 a + + + node_0_0 c + node_1_0 b + + + node_3_0 c + node_4_0 b + + + node_3_0 c + node_4_1 a + + + node_2_2 c + node_3_2 b + + + node_2_2 c + node_3_3 a + + + node_1_0 c + node_2_1 a + + + node_1_0 c + node_2_0 b + + + node_4_4 c + collect a4 + + + node_2_0 c + node_3_1 a + + + node_2_0 c + node_3_0 b + + + node_4_1 c + collect a1 + + + node_3_3 c + node_4_4 a + + + node_3_3 c + node_4_3 b + + + node_3_1 c + node_4_1 b + + + node_3_1 c + node_4_2 a + + + node_3_2 c + node_4_2 b + + + node_3_2 c + node_4_3 a + + + node_2_1 c + node_3_2 a + + + node_2_1 c + node_3_1 b + + + node_4_3 c + collect a3 + + + node_4_0 c + collect a0 + + + node_1_1b + 0 + + + node_0_0a + 0 + + + node_0_0b + 1 + + + node_3_0a + 0 + + + node_2_2b + 0 + + + node_1_0a + 0 + + + node_4_4b + 0 + + + node_2_0a + 0 + + + node_3_3b + 0 + + + node_4_0a + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/gui/YACSGui_DataModel.cxx b/src/gui/YACSGui_DataModel.cxx new file mode 100644 index 000000000..1b62b494d --- /dev/null +++ b/src/gui/YACSGui_DataModel.cxx @@ -0,0 +1,99 @@ +// Copyright (C) 2003 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 +// + +#include +#include + +#include +#include +#include + + +using namespace YACS::ENGINE; + +/*! + Constructor +*/ +YACSGui_DataModel::YACSGui_DataModel( CAM_Module* theModule ) : + LightApp_DataModel(theModule) +{ +} + +/*! + Destructor +*/ +YACSGui_DataModel::~YACSGui_DataModel() +{ +} + + +/*! + Add item to the map of procs +*/ +void YACSGui_DataModel::add(Proc* theProc, bool isEditable) +{ + myProcs[theProc] = isEditable; +} + +/*! + Remove item from the map of procs +*/ +void YACSGui_DataModel::remove(Proc* theProc) +{ + myProcs.erase(theProc); +} + +/*! + Check if the proc is editable +*/ +bool YACSGui_DataModel::isEditable(Proc* theProc) +{ + return (*myProcs.find(theProc)).second; +} + +/*! + Builds tree. +*/ +void YACSGui_DataModel::build() +{ + YACSGui_ModuleObject* aRoot = dynamic_cast( root() ); + if( !aRoot ) { + aRoot = new YACSGui_ModuleObject( this, 0 ); + setRoot( aRoot ); + } + + std::list::iterator it = myProcData.begin(); + for(; it != myProcData.end(); it++) { + Proc* aProc = *it; + YACSGui_DataObject* aDataObj = new YACSGui_DataObject( aRoot, aProc ); + } +} + + void YACSGui_DataModel::addData(Proc* theProc) +{ + if(myProcData.size() > 0) { + std::list::iterator result = std::find(myProcData.begin(), myProcData.end(), theProc); + if (result != myProcData.end()) + return; + } + + myProcData.push_back(theProc); + update(); +} diff --git a/src/gui/YACSGui_DataModel.h b/src/gui/YACSGui_DataModel.h new file mode 100644 index 000000000..ae5f949ce --- /dev/null +++ b/src/gui/YACSGui_DataModel.h @@ -0,0 +1,52 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSGui_DataModel_HeaderFile +#define YACSGui_DataModel_HeaderFile + +#include + +#include + +#include + +class YACSGui_DataModel : public LightApp_DataModel +{ + +public: + YACSGui_DataModel(CAM_Module* theModule); + virtual ~YACSGui_DataModel(); + + void add(YACS::ENGINE::Proc*, bool); + void remove(YACS::ENGINE::Proc*); + + void addData(YACS::ENGINE::Proc*); + + bool isEditable(YACS::ENGINE::Proc*); + +protected: + virtual void build(); + +private: + typedef std::map ProcMap; + ProcMap myProcs; + + std::list myProcData; +}; + +#endif diff --git a/src/gui/YACSGui_DataObject.cxx b/src/gui/YACSGui_DataObject.cxx new file mode 100644 index 000000000..d4c078edd --- /dev/null +++ b/src/gui/YACSGui_DataObject.cxx @@ -0,0 +1,123 @@ +// Copyright (C) 2003 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 +// +#include + +#include +#include +#include + +using namespace YACS::ENGINE; + +/*! + * Constructor + */ +YACSGui_DataObject::YACSGui_DataObject( SUIT_DataObject* theParent, Proc* theProc ) + : LightApp_DataObject( theParent ), + CAM_DataObject( theParent ), + myObject( theProc ) +{ +} + +/*! + * Destructor + */ +YACSGui_DataObject::~YACSGui_DataObject() +{ +} + +/*! + * Returns the data object icon + */ +QPixmap YACSGui_DataObject::icon() const +{ + return QPixmap(); +} + +/*! + * Returns the data object name + */ +QString YACSGui_DataObject::name() const +{ + QString aName; + + if (myObject) + aName = myObject->getName(); + + return aName; +} + +/*! + * Returns the data object entry + */ +QString YACSGui_DataObject::entry() const +{ + return QString(""); +} + + +/*! + * Constructor + */ +YACSGui_ModuleObject::YACSGui_ModuleObject ( CAM_DataModel* theDataModel, + SUIT_DataObject* theParent ) + : YACSGui_DataObject(theParent), + LightApp_ModuleObject( theDataModel, theParent ), + CAM_DataObject( theParent ) +{ +} + +/*! + * Gets name of the root + */ +QString YACSGui_ModuleObject::name() const +{ + return CAM_RootObject::name(); +} + + +/*! + * Gets an icon for the root + */ +QPixmap YACSGui_ModuleObject::icon() const +{ + QPixmap aRes; + if ( dataModel() ) { + QString anIconName = dataModel()->module()->iconName(); + if ( !anIconName.isEmpty() ) + aRes = SUIT_Session::session()->resourceMgr()->loadPixmap("YACSGui", anIconName, false); + } + return aRes; +} + +/*! + * Gets a tootip for the root + */ +QString YACSGui_ModuleObject::toolTip() const +{ + return QObject::tr( "YACS_ROOT_TOOLTIP" ); +} + +/*! + * Inherited method, redefined + */ +QString YACSGui_ModuleObject::entry() const +{ + return "YACS_ModuleObject"; +} diff --git a/src/gui/YACSGui_DataObject.h b/src/gui/YACSGui_DataObject.h new file mode 100644 index 000000000..f01bb5763 --- /dev/null +++ b/src/gui/YACSGui_DataObject.h @@ -0,0 +1,61 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSGui_DataObject_HeaderFile +#define YACSGui_DataObject_HeaderFile + +#include + +#include + +/*! + * YACS module data object + */ +class YACSGui_DataObject : public virtual LightApp_DataObject +{ +public: + YACSGui_DataObject( SUIT_DataObject*, YACS::ENGINE::Proc* = 0 ); + virtual ~YACSGui_DataObject(); + + virtual QString entry() const; + + QString name() const; + QPixmap icon() const; + +private: + YACS::ENGINE::Proc* myObject; +}; + +/*! + * YACS module root object + */ + +class YACSGui_ModuleObject : public virtual YACSGui_DataObject, + public virtual LightApp_ModuleObject +{ +public: + YACSGui_ModuleObject ( CAM_DataModel*, SUIT_DataObject* = 0 ); + + virtual QString name() const; + virtual QString entry() const; + + QPixmap icon() const; + QString toolTip() const; +}; + +#endif diff --git a/src/gui/YACSGui_Executor.cxx b/src/gui/YACSGui_Executor.cxx new file mode 100644 index 000000000..398bedaf3 --- /dev/null +++ b/src/gui/YACSGui_Executor.cxx @@ -0,0 +1,390 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 +// + +#include +#include +#include +#include +#include +#include +#include +#include "utilities.h" + +#include + +#include + +using namespace YACS::ENGINE; +using namespace YACS; +using namespace std; + +//! Constructor +/*! + */ +YACSGui_Executor::YACSGui_Executor(YACSGui_Module* guiMod, Proc* theProc) : + QThread(), + _guiMod(guiMod), + _proc(theProc) +{ + _localEngine = 0; + _engineRef = YACSGui_ORB::YACSGui_Gen::_nil(); + _procRef = YACSGui_ORB::ProcExec::_nil(); + _observerRef = YACSGui_ORB::Observer::_nil(); + _serv = 0; + _isRunning = false; + _isSuspended = false; + _execMode = YACS::CONTINUE; +} + +//! Destructor +/*! + */ +YACSGui_Executor::~YACSGui_Executor() +{ +} + +//! local run in a QThread +/*! local run in a QThread Reimplemented from QThread class. + */ +void YACSGui_Executor::run() +{ + if (!_proc) + return; + int debug = 0; // for debug only + _localEngine->RunW(_proc, debug); + _isRunning = false; +} + +//! Run dataflow. +/*! local run or remote (in a SALOME Container) + */ +void YACSGui_Executor::runDataflow(const bool isRemoteRun) +{ + MESSAGE("YACSGui_Executor::runDataflow"); + _isRemoteRun = isRemoteRun; + if (!isRemoteRun) // --- wanted local run + { + if (! _localEngine) + _localEngine = new Executor(); + if (_isRunning) + if (! checkEndOfDataFlow()) return; + _isRunning = true; + _localEngine->setExecMode(YACS::CONTINUE); // --- control only on remote run + start(); + } + else // --- wanted run in a SALOME Container + { + if (CORBA::is_nil(_engineRef)) + _engineRef = YACSGui_Module::InitYACSGuiGen(_guiMod->getApp()); + + if (_isRunning) + if (! checkEndOfDataFlow()) return; + _isRunning = true; + //Export the proc into temporary XML file + QString aFileName = Qtx::tmpDir() + QDir::QDir::separator() + "tmp_" + _proc->getName(); + + if (CORBA::is_nil(_procRef)) + { + MESSAGE("init _procRef"); + VisitorSaveSchema aWriter( _proc ); + aWriter.openFileSchema( aFileName ); + aWriter.visitProc( _proc ); + aWriter.closeFileSchema(); + _procRef = _engineRef->LoadProc(aFileName.latin1()); + registerStatusObservers(); + MESSAGE("_procRef _init"); + } + _procRef->setExecMode(getCurrentExecMode()); + _setBPList(); + _procRef->Run(); + } +} + +//! test if a dataflow is running +/*! + * return true if no running dataflow (TODO: check save state ? delete procexec servant ?) + */ +bool YACSGui_Executor::checkEndOfDataFlow(bool display) +{ + if (_isRunning) + { + if(running()) // --- local run not finished + { + if (display) + SUIT_MessageBox::error1(_guiMod->getApp()->desktop(), + tr("ERROR"), + tr("Local Execution Already running..."), + tr("BUT_OK")); + return false; + } + if (CORBA::is_nil(_procRef)) + { + if (display) + SUIT_MessageBox::error1(_guiMod->getApp()->desktop(), + tr("ERROR"), + tr("Runtime error: connection lost on a running scheme"), + tr("BUT_OK")); + _isRunning = false; + return false; + } + if (_procRef->isNotFinished()) + { + if (display) + SUIT_MessageBox::error1(_guiMod->getApp()->desktop(), + tr("ERROR"), + tr("Remote Execution Already running..."), + tr("BUT_OK")); + return false; + } + else + { + _isRunning = false; + // --- TODO: delete procExec on server ... + } + } + return true; +} + +//! Kill dataflow. +/*! + */ +void YACSGui_Executor::killDataflow() +{ + MESSAGE("YACSGui_Executor::killDataflow"); + //terminate(); // not safe! + if (running()) // --- local run + { + _localEngine->stopExecution(); + } + else if (_isRunning) // --- remote run + { + _procRef->stopExecution(); + } +} + + +//! Suspend/Resume dataflow. +/*! + */ +void YACSGui_Executor::suspendResumeDataflow() +{ + MESSAGE("YACSGui_Executor::suspendResumeDataflow"); + if (running()) // --- local run + { + if (_isSuspended) + { + _localEngine->setExecMode(_execMode); + _localEngine->resumeCurrentBreakPoint(); + } + else + _localEngine->setExecMode(YACS::STEPBYSTEP); + } + else if (_isRunning) // --- remote run + { + if (_isSuspended) + { + _procRef->setExecMode(getCurrentExecMode()); + _procRef->resumeCurrentBreakPoint(); + } + else + _procRef->setExecMode(YACSGui_ORB::STEPBYSTEP); + } + _isSuspended = !_isSuspended; +} + +void YACSGui_Executor::suspendDataflow() +{ + MESSAGE("YACSGui_Executor::suspendDataflow"); + if (running()) // --- local run + { + _localEngine->setExecMode(YACS::STEPBYSTEP); + } + else if (_isRunning) // --- remote run + { + _procRef->setExecMode(YACSGui_ORB::STEPBYSTEP); + } +} + +void YACSGui_Executor::resumeDataflow() +{ + MESSAGE("YACSGui_Executor::ResumeDataflow"); + if (running()) // --- local run + { + _localEngine->setExecMode(_execMode); + _localEngine->resumeCurrentBreakPoint(); + } + else if (_isRunning) // --- remote run + { + _procRef->setExecMode(getCurrentExecMode()); + _procRef->resumeCurrentBreakPoint(); + } +} + +void YACSGui_Executor::stopDataflow() +{ + MESSAGE("YACSGui_Executor::stopDataflow"); + if (running()) // --- local run + { + _localEngine->stopExecution(); + } + else if (_isRunning) // --- remote run + { + _procRef->stopExecution(); + } + +} + +void YACSGui_Executor::setStepByStepMode() +{ + MESSAGE("YACSGui_Executor::setStepByStepMode"); + _execMode = YACS::STEPBYSTEP; + if (running()) // --- local run + { + _localEngine->setExecMode(YACS::STEPBYSTEP); + } + else if (_isRunning) // --- remote run + { + _procRef->setExecMode(YACSGui_ORB::STEPBYSTEP); + } +} + +void YACSGui_Executor::setContinueMode() +{ + MESSAGE("YACSGui_Executor::setContinueMode"); + _execMode = YACS::CONTINUE; + if (running()) // --- local run + { + _localEngine->setExecMode(YACS::CONTINUE); + } + else if (_isRunning) // --- remote run + { + _procRef->setExecMode(YACSGui_ORB::CONTINUE); + } +} + +void YACSGui_Executor::setBreakpointMode() +{ + MESSAGE("YACSGui_Executor::setBreakpointMode"); + _execMode = YACS::STOPBEFORENODES; + if (running()) // --- local run + { + _localEngine->setExecMode(YACS::STOPBEFORENODES); + } + else if (_isRunning) // --- remote run + { + _procRef->setExecMode(YACSGui_ORB::STOPBEFORENODES); + } +} + +void YACSGui_Executor::setStopOnError(bool aMode) +{ + MESSAGE("YACSGui_Executor::setStopOnError"); + if (running()) // --- local run + { + _localEngine->setStopOnError(aMode, "/tmp/dumpStateOnError.xml"); + } + else if (_isRunning) // --- remote run + { + _procRef->setStopOnError(aMode, "/tmp/dumpStateOnError.xml"); + } +} + +void YACSGui_Executor::setNextStepList(std::list nextStepList) +{ + MESSAGE("YACSGui_Executor::setNextStepList"); + if (running()) // --- local run + { + _localEngine->setStepsToExecute(nextStepList); + } + else if (_isRunning) // --- remote run + { + YACSGui_ORB::stringArray listOfNextStep; + listOfNextStep.length(nextStepList.size()); + int i=0; + for (list::iterator it = nextStepList.begin(); it != nextStepList.end(); ++it) + listOfNextStep[i++] = (*it).c_str(); + _procRef->setStepsToExecute(listOfNextStep); + } +} + +void YACSGui_Executor::setBreakpointList(std::list breakpointList) +{ + MESSAGE("YACSGui_Executor::setBreakpointList"); + _breakpointList.clear(); + _breakpointList = breakpointList; + _setBPList(); +} + +//! list must be sent, even empty (only way to remove all breakpoints) +void YACSGui_Executor::_setBPList() +{ + if (running()) // --- local run + { + _localEngine->setListOfBreakPoints(_breakpointList); + } + else if (_isRunning) // --- remote run + { + YACSGui_ORB::stringArray listOfBreakPoints; + listOfBreakPoints.length(_breakpointList.size()); + int i=0; + for (list::iterator it = _breakpointList.begin(); it != _breakpointList.end(); ++it) + listOfBreakPoints[i++] = (*it).c_str(); + _procRef->setListOfBreakPoints(listOfBreakPoints); + } +} + +void YACSGui_Executor::registerStatusObservers() +{ + MESSAGE("YACSGui_Executor::registerStatusObservers"); + if (CORBA::is_nil(_procRef)) + { + SUIT_MessageBox::error1(_guiMod->getApp()->desktop(), + tr("ERROR"), + tr("Runtime error (yacsgui): Lost connection on YACS executor"), + tr("BUT_OK")); + return; + } + if (CORBA::is_nil(_observerRef)) + { + _serv = new Observer_i(_proc, _guiMod, this); + _observerRef = _serv->_this(); + _serv->SetImpl(_graph->getStatusObserver()); + } + MESSAGE("---"); + _serv->SetRemoteProc(_procRef); + _serv->setConversion(); + MESSAGE("---"); + std::set aNodeSet = _proc->getAllRecursiveConstituents(); + for ( std::set::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ ) + { + _procRef->addObserver(_observerRef, _serv->getEngineId((*it)->getNumId()) , "status"); + } + _procRef->addObserver(_observerRef, _serv->getEngineId(_proc->getNumId()) , "executor"); +} + +YACSGui_ORB::executionMode YACSGui_Executor::getCurrentExecMode() +{ + switch (_execMode) + { + case YACS::CONTINUE: return YACSGui_ORB::CONTINUE; + case YACS::STEPBYSTEP: return YACSGui_ORB::STEPBYSTEP; + case YACS::STOPBEFORENODES: return YACSGui_ORB::STOPBEFORENODES; + default: return YACSGui_ORB::CONTINUE; + } +} diff --git a/src/gui/YACSGui_Executor.h b/src/gui/YACSGui_Executor.h new file mode 100644 index 000000000..d143e28c0 --- /dev/null +++ b/src/gui/YACSGui_Executor.h @@ -0,0 +1,88 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSGui_Executor_HeaderFile +#define YACSGui_Executor_HeaderFile + +#define YACS_PTHREAD //@ + +#include +#include + +#include + +#include +#include +#include + +#include +#include + +class YACSGui_Module; +class Observer_i; + +class YACSGui_Executor : public QObject, public QThread +{ + Q_OBJECT + + public: + YACSGui_Executor(YACSGui_Module* guiMod, YACS::ENGINE::Proc* theProc); + ~YACSGui_Executor(); + + void runDataflow(const bool isRemoteRun = false); + bool checkEndOfDataFlow(bool display = true); + void killDataflow(); + void suspendResumeDataflow(); + void suspendDataflow(); + void resumeDataflow(); + void stopDataflow(); + void setStepByStepMode(); + void setContinueMode(); + void setBreakpointMode(); + void setStopOnError(bool aMode); + void setBreakpointList(std::list breakpointList); + void setNextStepList(std::list nextStepList); + + void setGraph(YACSGui_Graph* theGraph) { _graph = theGraph; } + void registerStatusObservers(); + bool isRunning() { return _isRunning; }; + //YACS::ENGINE::Executor* getLocalEngine() { return _localEngine; }; + YACS::ENGINE::Proc* getProc() { return _proc; }; + protected: + virtual void run(); + YACSGui_ORB::executionMode getCurrentExecMode(); + void _setBPList(); + + private: + YACS::ENGINE::Executor* _localEngine; + YACS::ENGINE::Proc* _proc; + YACSGui_ORB::YACSGui_Gen_var _engineRef; + YACSGui_ORB::ProcExec_var _procRef; + YACSGui_ORB::Observer_var _observerRef; + YACS::ExecutionMode _execMode; + Observer_i* _serv; + YACSGui_Graph* _graph; + YACSGui_Module* _guiMod; + bool _isRemoteRun; + bool _isRunning; + bool _isSuspended; + std::list _breakpointList; +}; + +#endif diff --git a/src/gui/YACSGui_Graph.cxx b/src/gui/YACSGui_Graph.cxx new file mode 100644 index 000000000..42d1bf49d --- /dev/null +++ b/src/gui/YACSGui_Graph.cxx @@ -0,0 +1,665 @@ +// Copyright (C) 2003 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 +// + +#include "YACSGui_Graph.h" +#include "YACSGui_Node.h" +#include "YACSGui_Module.h" +#include "YACSGui_Observer.h" + +#include "YACSPrs_ElementaryNode.h" +#include "YACSPrs_BlocNode.h" +#include "YACSPrs_Link.h" +#include "YACSPrs_Def.h" + +#include "LineConn2d_Model.h" +#include "Standard_ProgramError.hxx" + +#include "QxGraph_ViewWindow.h" +#include "QxGraph_Canvas.h" +#include "QxGraph_CanvasView.h" + +#include "SUIT_Session.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "utilities.h" + +using namespace YACS::ENGINE; + +/*! + Constructor +*/ +YACSGui_Graph::YACSGui_Graph(YACSGui_Module* theModule, + QxGraph_Canvas* theCanvas, + Proc* theProc) : + QxGraph_Prs(theCanvas), + myModule(theModule), + myProc(theProc) +{ + // Create node status observer instance + myNodeStatusObserver = new YACSGui_Observer(this); +} + +/*! + Destructor +*/ +YACSGui_Graph::~YACSGui_Graph() +{ + Dispatcher* aDispatcher = Dispatcher::getDispatcher(); + + DMode2ItemList aDM = getDisplayMap(); + for ( DMode2ItemList::iterator it1 = aDM.begin(); + it1 != aDM.end(); + it1++ ) + { + for ( std::list::iterator it2 = (*it1).second.begin(); + it2 != (*it1).second.end(); + it2++ ) + { + QCanvasItem* anItem = *it2; + YACSPrs_ElementaryNode* aEN = 0; + aEN = dynamic_cast( *it2 ); + if ( aEN && aEN->isInBloc() ) + // remove item from the map of displayed items, because it is forbidden + // to destroy such items in QxGraph_Prs destructor: they will be deleted + // in the destructor of corresponding YACSPrs_BlocNode + removeItem( anItem ); + + // Remove status observer from dispatcher + aDispatcher->removeObserver(myNodeStatusObserver, aEN->getEngine(), "status"); + } + } +} + + +//! Re-builds all the elements of the graph's presentation +/*! + */ +void YACSGui_Graph::update() +{ + MESSAGE("YACSGui_Graph::update 1"); + if ( !isToUpdate() ) + return; + + MESSAGE("YACSGui_Graph::update 2"); + + // TODO - clean exisiting items first + // ... + + // maximum width and height of nodes presentation (for table arrangement first level nodes) + int aMaxNodeWidth=0, aMaxNodeHeight=0; + bool aNeedToArrange = false; + + // Iterate through myProc's nodes and create presentation items for them + /// comment set for testing, uncomment this code when myProc'll be really not null graph + if (myProc) + { + std::set aNodeSet = myProc->getAllRecursiveConstituents(); //myProc->getChildren(); + + if ( !getItem( *(aNodeSet.begin()) ) ) aNeedToArrange = true; + + for ( std::set::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ ) + { + // create presentations for all nodes except Bloc itself + // (for its internal not Bloc nodes presentations created too) + if ( !dynamic_cast( *it ) ) { + update( *it ); + + YACSPrs_ElementaryNode* aNodePrs = getItem( *it ); + if ( aNodePrs ) { + if ( aMaxNodeWidth < aNodePrs->maxWidth() ) aMaxNodeWidth = aNodePrs->maxWidth(); + if ( aMaxNodeHeight < aNodePrs->maxHeight() ) aMaxNodeHeight = aNodePrs->maxHeight(); + } + } + } + + // create presentations for Bloc nodes (for all other nodes, including internal + // nodes of Bloc's, presentations already created) + for ( std::set::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ ) + { + // create presentations for all nodes except Bloc itself + // (for its internal not Bloc nodes presentations created too) + if ( dynamic_cast( *it ) ) { + update( *it ); + + YACSPrs_ElementaryNode* aNodePrs = getItem( *it ); + if ( aNodePrs ) { + if ( aMaxNodeWidth < aNodePrs->maxWidth() ) aMaxNodeWidth = aNodePrs->maxWidth(); + if ( aMaxNodeHeight < aNodePrs->maxHeight() ) aMaxNodeHeight = aNodePrs->maxHeight(); + } + } + } + + // TODO - Create links + for ( std::set::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ ) + { + YACSPrs_ElementaryNode* aNodePrs = getItem( *it ); + if ( aNodePrs ) + { + QPtrList aPorts = aNodePrs->getPortList(); + for (YACSPrs_Port* aPort = aPorts.first(); aPort; aPort = aPorts.next()) + { + // data and control links + YACSPrs_InOutPort* anIOPort = dynamic_cast( aPort ); + if ( anIOPort ) { + update( anIOPort ); + continue; + } + // label links + YACSPrs_LabelPort* aLabelPort = dynamic_cast( aPort ); + if ( aLabelPort ) update( aLabelPort ); + } + } + } + + if ( aNeedToArrange ) + { + // table arrangement of the first level nodes + aNodeSet = myProc->edGetDirectDescendants(); + int aColNum, aRowNum; aColNum = aRowNum = (int)sqrt((double)aNodeSet.size()); + if ( aNodeSet.size() - aColNum*aRowNum > 0 ) aRowNum++; + int i=0,j=0; + int aMargin = 50; + for ( std::set::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ ) + { + YACSPrs_ElementaryNode* aNodePrs = getItem( *it ); + if ( aNodePrs ) + { + if ( j == aColNum) { j = 0; i++; } + aNodePrs->move( aNodePrs->x() + i*(aMaxNodeWidth+aMargin), aNodePrs->y() + j*(aMaxNodeHeight+aMargin) ); + j++; + } + } + } + + } + + QxGraph_Prs::update(); +} + +//! Updates the presentation items related to given graph node. +/*! + */ +void YACSGui_Graph::update(Node* theEngine) +{ + MESSAGE("YACSGui_Graph::update " << theEngine->getQualifiedName()); + /// comment set for testing, uncomment this code when theEngine'll be really not null node + if ( !theEngine ) + return; + + YACSGui_Node* aDriver = driver( theEngine ); + if ( !aDriver ) + return; + + YACSPrs_ElementaryNode* anItem = getItem( theEngine ); + bool needToAddItem = false; + if ( !anItem ) // we need to add items, which will be created in update(...) by a driver, + needToAddItem = true; // into display map for the current display mode + + // If is empty, it is filled by a driver, if not empty - only update by a driver + aDriver->update( theEngine, anItem ); + + if (needToAddItem) + { + addItem( anItem ); // add item for the current display mode + myItems[theEngine] = anItem; + } +} + +//! Updates the data and control links presentations related to given node port. +/*! + */ +void YACSGui_Graph::update( YACSPrs_InOutPort* thePort ) +{ + if ( thePort->getLinks().empty() ) + { + std::string aClassName = thePort->getEngine()->getNameOfTypeOfCurrentInstance(); + if ( !aClassName.compare(OutputPort::NAME) ) + { // this is an output data port => create all links going from it + OutputPort* anOutputDFPort = dynamic_cast( thePort->getEngine() ); + if ( anOutputDFPort ) createLinksFromGivenOutPortPrs( thePort, anOutputDFPort->edSetInPort() ); + } + + if ( !aClassName.compare(OutputDataStreamPort::NAME) || !aClassName.compare(OutputCalStreamPort::NAME) ) + { // this is an output data stream port => create all links going from it + OutputDataStreamPort* anOutputDSPort = dynamic_cast( thePort->getEngine() ); + if ( anOutputDSPort ) createLinksFromGivenOutPortPrs( thePort, anOutputDSPort->edSetInPort() ); + } + + if ( !aClassName.compare(OutGate::NAME) ) + { // this is an output control port (i.e. Gate) => create all links going from it + OutGate* anOutPort = dynamic_cast( thePort->getEngine() ); + if ( anOutPort ) + { + std::set anInPorts = anOutPort->edSetInGate(); + for(std::set::iterator iter=anInPorts.begin(); iter!=anInPorts.end(); iter++) + { // the pair <(*iter),anOutPort> is a link + YACSPrs_ElementaryNode* aToNodePrs = getItem((*iter)->getNode()); + if ( aToNodePrs ) + { + YACSPrs_InOutPort* anInPortPrs = aToNodePrs->getPortPrs( *iter ); + YACSPrs_Link* aLink = + new YACSPrs_PortLink( SUIT_Session::session()->resourceMgr(), getCanvas(), anInPortPrs, thePort ); + aLink->show(); + // push_back into the map in YACSGui_Graph + } + } + } + } + } + else + { // update already existing port links + } +} + +void YACSGui_Graph::createLinksFromGivenOutPortPrs( YACSPrs_InOutPort* theOutPortPrs, std::set theInPorts ) +{ + for(std::set::iterator iter=theInPorts.begin(); iter!=theInPorts.end(); iter++) + { // the pair <(*iter),OutPort> is a link + YACSPrs_ElementaryNode* aToNodePrs = 0; + if ( dynamic_cast( (*iter)->getNode() ) ) + aToNodePrs = getItem((*iter)->getNode()->getFather()); // for ForEachLoop nodes only + else + aToNodePrs = getItem((*iter)->getNode()); + if ( aToNodePrs ) + { + YACSPrs_InOutPort* anInPortPrs = aToNodePrs->getPortPrs( *iter ); + YACSPrs_Link* aLink = + new YACSPrs_PortLink( SUIT_Session::session()->resourceMgr(), getCanvas(), anInPortPrs, theOutPortPrs ); + aLink->show(); + // push_back into the map in YACSGui_Graph + } + } +} + +//! Updates the label links presentations related to given node port. +/*! + */ +void YACSGui_Graph::update( YACSPrs_LabelPort* thePort ) +{ + if ( thePort->getLinks().empty() ) + { + if ( thePort->getSlaveNode() ) + { + YACSPrs_ElementaryNode* aSlaveNodePrs = getItem(thePort->getSlaveNode()); + // the pair is a label link + if ( aSlaveNodePrs ) + { + YACSPrs_Link* aLink = + new YACSPrs_LabelLink( SUIT_Session::session()->resourceMgr(), getCanvas(), thePort, aSlaveNodePrs ); + aLink->show(); + // push_back into the map in YACSGui_Graph + } + } + } + else + { // update already existing label links + } +} + +void YACSGui_Graph::rebuildLinks() +{ + // Bloc I : create LineConn2d_Model object + LineConn2d_Model* aLineModel = new LineConn2d_Model; + aLineModel->SetTolerance( 0.01 ); + aLineModel->SetPortLength( 0. ); + aLineModel->SetSearchDepth( 2 ); + + // Bloc II : iteration on nodes -> output ports -> links => fill LineConn2d_Model object with datas + std::map aConnId2Link; + if (myProc) + { + std::map aNodePrs2ObjId; + std::map aPortPrs2PortId; + // 1 1 + // commented because LabelPort <----> MasterPoint + //std::map aHookPrs2PortId; + + std::set aNodeSet = myProc->getAllRecursiveConstituents(); + for ( std::set::iterator itN = aNodeSet.begin(); itN != aNodeSet.end(); itN++ ) + { + YACSPrs_ElementaryNode* aNodePrs = getItem( *itN ); + if ( aNodePrs ) + { + addObjectToLine2dModel(aNodePrs, aLineModel, aNodePrs2ObjId); + + QPtrList aPorts = aNodePrs->getPortList(); + for (YACSPrs_Port* aPort = aPorts.first(); aPort; aPort = aPorts.next()) + { + // data and control links + YACSPrs_InOutPort* anIOPort = dynamic_cast( aPort ); + if ( anIOPort && !anIOPort->isInput() ) + { // anIOPort is a "from" port of the link + std::list aLinks = anIOPort->getLinks(); + for(std::list::iterator itL = aLinks.begin(); itL != aLinks.end(); itL++) + { + int PortId1 = addPortToLine2dModel(anIOPort, aNodePrs, *itL, aLineModel, aNodePrs2ObjId, aPortPrs2PortId); + + if ( YACSPrs_PortLink* aPortLink = dynamic_cast( *itL ) ) + { + YACSPrs_InOutPort* anIPort = aPortLink->getInputPort(); + + int PortId2 = addPortToLine2dModel(anIPort, 0, *itL, aLineModel, aNodePrs2ObjId, aPortPrs2PortId); + int ConnId = aLineModel->AddConnection( PortId1, PortId2 ); + aConnId2Link.insert(std::make_pair(ConnId,aPortLink)); + } + } + } + + // label links + YACSPrs_LabelPort* aLabelPort = dynamic_cast( aPort ); + if ( aLabelPort ) + { // aLabelPort is a "from" port of the link, + //the master point of the slave node can be considered as a "to" port of the link + std::list aLinks = aLabelPort->getLinks(); + for(std::list::iterator itL = aLinks.begin(); itL != aLinks.end(); itL++) + { + int PortId1 = addPortToLine2dModel(aLabelPort, aNodePrs, *itL, aLineModel, aNodePrs2ObjId, aPortPrs2PortId); + + if ( YACSPrs_LabelLink* aLabelLink = dynamic_cast( *itL ) ) + { + YACSPrs_Hook* aMPoint = aLabelLink->getSlaveNode()->getMasterPoint(); + int PortId2 = addPortToLine2dModel(aMPoint, aLabelLink->getSlaveNode(), aLabelLink, aLineModel, aNodePrs2ObjId); + int ConnId = aLineModel->AddConnection( PortId1, PortId2 ); + aConnId2Link.insert(std::make_pair(ConnId,aLabelLink)); + } + } + } + } + } + } + } + + // Bloc V : compute new links points with help of LineConn2d_Model + if ( !aLineModel->NbObjects() ) + return; + int nbCon; + try + { + aLineModel->Compute(); + nbCon = aLineModel->NbConnections(); + } + catch (Standard_ProgramError) + { + nbCon = 0; + } + for ( int i = 1; i <= nbCon; i++ ) + { // iterates on computed connections + const LineConn2d_Connection& curConn = aLineModel->operator ()( i ); + // add check that no new segments computed. + bool isSimpleLine = curConn.NbSegments() == 0; + + const int portId1 = curConn.Port( 0 ); + const int portId2 = curConn.Port( 1 ); + if ( portId1 == -1 || portId2 == -1 ) + continue; // should not be + + std::list aList; + if ( !isSimpleLine ) + { + int nbSeg = curConn.NbSegments(); + LineConn2d_Connection::SegIterator segIt = curConn.SegmentIterator(); + for( int segId = 1; segIt.More(); segIt.Next(), segId++ ) + { + const LineConn2d_Segment& seg = segIt.Value(); + gp_XY aXY; + if ( segId > 1 ) { + aXY = seg.Origin(); + aList.push_front( QPoint( (int)(aXY.X()), (int)(aXY.Y()) ) ); + } + } + aConnId2Link[i]->setPoints(aList); + aConnId2Link[i]->merge(); + } + } + + getCanvas()->update(); +} + +int YACSGui_Graph::addObjectToLine2dModel(YACSPrs_ElementaryNode* theNode, + LineConn2d_Model* theLineModel, + std::map& theNodePrs2ObjId) +{ + int ObjId = -1; + + if ( !theNode ) return ObjId; + + if ( theNodePrs2ObjId.find( theNode ) != theNodePrs2ObjId.end() ) + ObjId = theNodePrs2ObjId[ theNode ]; + else + { // Bloc III : add node to LineConn2d_Model --> + ObjId = theLineModel->AddObject(); + LineConn2d_Object& anObj2d = theLineModel->ChangeObject( ObjId ); + + QPointArray aPA = theNode->maxAreaPoints(); + for (QPointArray::Iterator itPA = aPA.begin(); itPA != aPA.end(); itPA++) { + anObj2d.AddPoint( gp_XY( (*itPA).x(), (*itPA).y() ) ); + + // for Bloc nodes in expanded mode add to LineConn2d_Object only the first point from area points array + // ( Bloc nodes in expanded mode are transparent for links ). + // In this case the check in LineConn2d_Model (checkPort(...) method) allways returns true + // for all ports of other nodes inside Bloc node (i.e. any ports or objects are outside of the one point) + // => intersections with Bloc nodes isn't taken into account. + YACSPrs_BlocNode* aBNode = dynamic_cast( theNode ); + if ( aBNode && aBNode->getDisplayMode() == YACSPrs_BlocNode::Expanded ) break; + } + + theNodePrs2ObjId.insert( std::make_pair(theNode, ObjId) ); + // <-- + } + + return ObjId; +} + +int YACSGui_Graph::addPortToLine2dModel(YACSPrs_Port* thePort, + YACSPrs_ElementaryNode* theNode, + YACSPrs_Link* theLink, + LineConn2d_Model* theLineModel, + std::map& theNodePrs2ObjId, + std::map& thePortPrs2PortId) +{ + if ( thePortPrs2PortId.find( thePort ) != thePortPrs2PortId.end() ) + return thePortPrs2PortId[ thePort ]; + + int PortId = -1; + + YACSPrs_InOutPort* anIOPort = dynamic_cast( thePort ); + if ( anIOPort && !theNode) + // take from anIOPort its node presentation + theNode = getItem( anIOPort->getEngine()->getNode() ); + + if ( theNode ) + { + int ObjId = addObjectToLine2dModel(theNode, theLineModel, theNodePrs2ObjId); + + // Bloc IV : add port to LineConn2d_Model --> + gp_XY aP2d( theLink->getConnectionPoint(thePort).x(), theLink->getConnectionPoint(thePort).y() ); + gp_Dir2d aDir2d( 1, 0 ); + if ( anIOPort && anIOPort->isInput() ) aDir2d.SetX( -1 ); + PortId = theLineModel->AddPoort( ObjId, aP2d, aDir2d ); + thePortPrs2PortId.insert( std::make_pair(thePort, PortId) ); + // <-- + } + + return PortId; +} + +int YACSGui_Graph::addPortToLine2dModel(YACSPrs_Hook* theHook, + YACSPrs_ElementaryNode* theNode, + YACSPrs_LabelLink* theLink, + LineConn2d_Model* theLineModel, + std::map& theNodePrs2ObjId) +{ + int PortId = -1; + + if ( theNode ) + { + int ObjId = addObjectToLine2dModel(theNode, theLineModel, theNodePrs2ObjId); + + // Bloc IV : add port to LineConn2d_Model --> + gp_XY aP2d( theLink->getConnectionMasterPoint().x(), + theLink->getConnectionMasterPoint().y()+(NODEBOUNDARY_MARGIN+1)*2+LINKPOINT_SIZE/2 ); + gp_Dir2d aDir2d( 0, 1 ); + PortId = theLineModel->AddPoort( ObjId, aP2d, aDir2d ); + // <-- + } + + return PortId; +} + +//! Returns the presentation driver for given graph node. +/*! + */ +YACSGui_Node* YACSGui_Graph::driver(Node* theEngine) +{ + const char* aTypeName = typeid( *theEngine ).name(); + printf("== aTypeName = %s\n",aTypeName); + if ( myDrivers.find( aTypeName ) == myDrivers.end() ) + { + YACSGui_Node* aDriver = 0; + + // TODO - Analyze the type of and create a driver instance + if (ServiceNode* sNode = dynamic_cast( theEngine ) ) + { + if (sNode->getKind() == "XML") + aDriver = new YACSGui_InlineNode(this); + else + aDriver = new YACSGui_ServiceNode(this); + } + else if ( dynamic_cast( theEngine ) ) + aDriver = new YACSGui_InlineNode(this); + else if ( dynamic_cast( theEngine ) ) + // but getNbOfCases() is a private method of Switch node => how to recognize If node type in engine? + //if ( dynamic_cast( theEngine )->getNbOfCases() == 1 ) + // aDriver = new YACSGui_IfNode(this); + //else + aDriver = new YACSGui_SwitchNode(this); + else if ( dynamic_cast( theEngine ) || dynamic_cast( theEngine ) ) + aDriver = new YACSGui_LoopNode(this); + else if ( dynamic_cast( theEngine ) ) + aDriver = new YACSGui_ForEachLoopNode(this); + else if ( dynamic_cast( theEngine ) ) + aDriver = new YACSGui_BlocNode(this); + + if ( aDriver ) + myDrivers[aTypeName] = aDriver; + } + + return myDrivers[aTypeName]; +} + +YACSPrs_ElementaryNode* YACSGui_Graph::getItem( YACS::ENGINE::Node* theEngine ) +{ + YACSPrs_ElementaryNode* aNode = 0; + if ( myItems.find( theEngine ) == myItems.end() ) + myItems[theEngine] = aNode; + return myItems[theEngine]; +} + +void YACSGui_Graph::getAllBlocChildren(Bloc* theNode, std::set& theSet) +{ + if ( theNode ) + { + std::set aChildren = theNode->getChildren(); + for ( std::set::iterator it = aChildren.begin(); it != aChildren.end(); it++ ) + { + if ( dynamic_cast( *it ) + || + dynamic_cast( *it ) ) theSet.insert( *it ); + else + { + ComposedNode* aCNode = dynamic_cast( *it ); + if ( aCNode ) { + getAllComposedNodeChildren( aCNode, theSet ); + theSet.insert( *it ); + } + } + } + } +} + +void YACSGui_Graph::getAllComposedNodeChildren(ComposedNode* theNode, std::set& theSet) +{ + if ( theNode ) + { + std::set aDescendants = theNode->edGetDirectDescendants(); + for ( std::set::iterator it = aDescendants.begin(); it != aDescendants.end(); it++ ) + { + if ( dynamic_cast( *it ) + || + dynamic_cast( *it ) ) theSet.insert( *it ); + else + { + ComposedNode* aCNode = dynamic_cast( *it ); + if ( aCNode ) getAllComposedNodeChildren( aCNode, theSet ); + } + } + } +} + + +//! Register the status observer in the Dispatcher with the given node +/*! + */ +void YACSGui_Graph::registerStatusObserverWithNode(Node* theNode) +{ + MESSAGE("YACSGui_Graph::registerStatusObserverWithNode " << theNode->getQualifiedName()); + Dispatcher* aDispatcher = Dispatcher::getDispatcher(); + aDispatcher->addObserver(myNodeStatusObserver, theNode, "status"); +} + +//! Return node with id equal to theID +/*! + */ +YACS::ENGINE::Node* YACSGui_Graph::getNodeById( const int theID ) const +{ + if(YACS::ENGINE::Node::idMap.count(theID) == 0) + return 0; + + YACS::ENGINE::Node* aNode= YACS::ENGINE::Node::idMap[theID]; + + return aNode; +} + +//! Return node with name equal to theID +/*! + */ +YACS::ENGINE::Node* YACSGui_Graph::getNodeByName( const std::string theName ) const +{ + if (!getProc()) + return 0; + + return getProc()->getChildByName(theName); +} diff --git a/src/gui/YACSGui_Graph.h b/src/gui/YACSGui_Graph.h new file mode 100644 index 000000000..35d0dadcc --- /dev/null +++ b/src/gui/YACSGui_Graph.h @@ -0,0 +1,110 @@ +// Copyright (C) 2003 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 YACSGui_Graph_HeaderFile +#define YACSGui_Graph_HeaderFile + +#include +#include + +#include + +#include + +class QxGraph_ViewWindow; +class QxGraph_Canvas; +class QxGraph_CanvasView; + +class YACSGui_Module; +class YACSGui_Node; +class YACSGui_Observer; +class YACSPrs_ElementaryNode; +class YACSPrs_Hook; +class YACSPrs_Port; +class YACSPrs_InOutPort; +class YACSPrs_LabelPort; +class YACSPrs_Link; +class YACSPrs_LabelLink; + +class LineConn2d_Model; + +class YACSGui_Graph : public QxGraph_Prs +{ +public: + YACSGui_Graph(YACSGui_Module*, QxGraph_Canvas*, YACS::ENGINE::Proc*); + virtual ~YACSGui_Graph(); + + YACS::ENGINE::Proc* getProc() const { return myProc; } + + YACSGui_Observer* getStatusObserver() const { return myNodeStatusObserver; } + + virtual void update(); + void update( YACS::ENGINE::Node* ); + void update( YACSPrs_InOutPort* ); + void update( YACSPrs_LabelPort* ); + + void rebuildLinks(); + int addObjectToLine2dModel(YACSPrs_ElementaryNode* theNode, + LineConn2d_Model* theLineModel, + std::map& theNodePrs2ObjId); + int addPortToLine2dModel(YACSPrs_Port* thePort, + YACSPrs_ElementaryNode* theNode, + YACSPrs_Link* theLink, + LineConn2d_Model* theLineModel, + std::map& theNodePrs2ObjId, + std::map& thePortPrs2PortId); + int addPortToLine2dModel(YACSPrs_Hook* theHook, + YACSPrs_ElementaryNode* theNode, + YACSPrs_LabelLink* theLink, + LineConn2d_Model* theLineModel, + std::map& theNodePrs2ObjId); + + YACSPrs_ElementaryNode* getItem( YACS::ENGINE::Node* ); + + YACS::ENGINE::Node* getNodeById( const int theID ) const; + + YACS::ENGINE::Node* getNodeByName( const std::string theName ) const; + + void getAllBlocChildren(YACS::ENGINE::Bloc*, + std::set&); + void getAllComposedNodeChildren(YACS::ENGINE::ComposedNode*, + std::set&); + + void registerStatusObserverWithNode(YACS::ENGINE::Node* theNode); + +private: + YACSGui_Node* driver( YACS::ENGINE::Node* theNode ); + void createLinksFromGivenOutPortPrs( YACSPrs_InOutPort* theOutPortPrs, + std::set theInPorts ); + +private: + + typedef std::map DriverMap; + typedef std::map ItemMap; + + YACSGui_Module* myModule; + YACS::ENGINE::Proc* myProc; // graph engine + DriverMap myDrivers; // map of update drivers for specific node types + ItemMap myItems; // map of graphic items for a given engine node + + YACSGui_Observer* myNodeStatusObserver; +}; + +#endif diff --git a/src/gui/YACSGui_Module.cxx b/src/gui/YACSGui_Module.cxx new file mode 100644 index 000000000..2e311cf2e --- /dev/null +++ b/src/gui/YACSGui_Module.cxx @@ -0,0 +1,966 @@ +// Copyright (C) 2003 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 +// + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include "YACSGui_RunMode.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for test presentations +#include // for test presentations + +#include +#include + +#include + +#include // for debug only +#include "utilities.h" + +using namespace YACS; +using namespace YACS::ENGINE; + + +extern "C" +{ + CAM_Module* createModule() + { + return new YACSGui_Module(); + } +} + +//! Constructor. +/*! + */ +YACSGui_Module::YACSGui_Module() : SalomeApp_Module( "YACS" ) +{ + MESSAGE("YACSGui_Module::YACSGui_Module()"); + _myRunMode = 0; +} + +//! Destructor. +/*! + */ +YACSGui_Module::~YACSGui_Module() +{ + MESSAGE("YACSGui_Module::~YACSGui_Module()"); +} + +//! Initialize module. +/*! + */ +void YACSGui_Module::initialize( CAM_Application* theApp ) +{ + MESSAGE("YACSGui_Module::initialize"); + SalomeApp_Module::initialize(theApp); + InitYACSGuiGen( dynamic_cast( theApp ) ); + + createActions(); + createMenus(); +} + +//! Creates module actions. +/*! + */ +void YACSGui_Module::createActions() +{ + MESSAGE("YACSGui_Module::createActions()"); + QPixmap aPixmap; + QWidget* aDesktop = application()->desktop(); + SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr(); + + if (!aDesktop || !aResourceMgr) + return; + + // Menu "File" + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_NEW_DATAFLOW")); + createAction( NewDataflowId, tr("TOP_NEW_DATAFLOW"), QIconSet(aPixmap), + tr("MEN_NEW_DATAFLOW"), tr("STB_NEW_DATAFLOW"), + 0, aDesktop, false, this, SLOT(onNewDataflow())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_MODIFY_DATAFLOW")); + createAction( ModifyDataflowId, tr("TOP_MODIFY_DATAFLOW"), QIconSet(aPixmap), + tr("MEN_MODIFY_DATAFLOW"), tr("STB_MODIFY_DATAFLOW"), + 0, aDesktop, false, this, SLOT(onModifyDataflow())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_MODIFY_SUPERV_DATAFLOW")); + createAction( ModifySupervDataflowId, tr("TOP_MODIFY_SUPERV_DATAFLOW"), QIconSet(aPixmap), + tr("MEN_MODIFY_SUPERV_DATAFLOW"), tr("STB_MODIFY_SUPERV_DATAFLOW"), + 0, aDesktop, false, this, SLOT(onModifySupervDataflow())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_IMPORT_DATAFLOW")); + createAction( ImportDataflowId, tr("TOP_IMPORT_DATAFLOW"), QIconSet(aPixmap), + tr("MEN_IMPORT_DATAFLOW"), tr("STB_IMPORT_DATAFLOW"), + 0, aDesktop, false, this, SLOT(onImportDataflow())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_IMPORT_SUPERV_DATAFLOW")); + createAction( ImportSupervDataflowId, tr("TOP_IMPORT_SUPERV_DATAFLOW"), QIconSet(aPixmap), + tr("MEN_IMPORT_SUPERV_DATAFLOW"), tr("STB_IMPORT_SUPERV_DATAFLOW"), + 0, aDesktop, false, this, SLOT(onImportSupervDataflow())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_EXPORT_DATAFLOW")); + createAction( ExportDataflowId, tr("TOP_EXPORT_DATAFLOW"), QIconSet(aPixmap), + tr("MEN_EXPORT_DATAFLOW"), tr("STB_EXPORT_DATAFLOW"), + 0, aDesktop, false, this, SLOT(onExportDataflow())); + + // Menu "Supervisor" + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_ADD_NODE")); + createAction( AddNodeId, tr("TOP_ADD_NODE"), QIconSet(aPixmap), + tr("MEN_ADD_NODE"), tr("STB_ADD_NODE"), + 0, aDesktop, false, this, SLOT(onAddNode())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_SUSPEND_RESUME_DATAFLOW")); + createAction( SuspendResumeDataflowId, tr("TOP_SUSPEND_RESUME_DATAFLOW"), QIconSet(aPixmap), + tr("MEN_SUSPEND_RESUME_DATAFLOW"), tr("STB_SUSPEND_RESUME_DATAFLOW"), + 0, aDesktop, false, this, SLOT(onSuspendResumeDataflow())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_RUN_DATAFLOW")); + createAction( RunDataflowId, tr("TOP_RUN_DATAFLOW"), QIconSet(aPixmap), + tr("MEN_RUN_DATAFLOW"), tr("STB_RUN_DATAFLOW"), + 0, aDesktop, false, this, SLOT(onRunDataflow())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_REMOTE_RUN_DATAFLOW")); + createAction( RemoteRunDataflowId, tr("TOP_REMOTE_RUN_DATAFLOW"), QIconSet(aPixmap), + tr("MEN_REMOTE_RUN_DATAFLOW"), tr("STB_REMOTE_RUN_DATAFLOW"), + 0, aDesktop, false, this, SLOT(onRemoteRunDataflow())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_KILL_DATAFLOW")); + createAction( KillDataflowId, tr("TOP_KILL_DATAFLOW"), QIconSet(aPixmap), + tr("MEN_KILL_DATAFLOW"), tr("STB_KILL_DATAFLOW"), + 0, aDesktop, false, this, SLOT(onKillDataflow())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_TOGGLESTOPONERROR")); + createAction( ToggleStopOnErrorId, tr("TOP_TOGGLESTOPONERROR"), QIconSet(aPixmap), + tr("MEN_TOGGLESTOPONERROR"), tr("STB_TOGGLESTOPONERROR"), + 0, aDesktop, false, this, SLOT(onToggleStopOnError())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_FILTERNEXTSTEPS")); + createAction( FilterNextStepsId, tr("TOP_FILTERNEXTSTEPS"), QIconSet(aPixmap), + tr("MEN_FILTERNEXTSTEPS"), tr("STB_FILTERNEXTSTEPS"), + 0, aDesktop, false, this, SLOT(onFilterNextSteps())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_ADD_DATAFLOW_IN_STUDY")); + createAction( AddDataflowInStudyId, tr("TOP_ADD_DATAFLOW_IN_STUDY"), QIconSet(aPixmap), + tr("MEN_ADD_DATAFLOW_IN_STUDY"), tr("STB_ADD_DATAFLOW_IN_STUDY"), + 0, aDesktop, false, this, SLOT(onAddDataflowInStudy())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_CHANGE_INFORMATIONS")); + createAction( ChangeInformationsId, tr("TOP_CHANGE_INFORMATIONS"), QIconSet(aPixmap), + tr("MEN_CHANGE_INFORMATIONS"), tr("STB_CHANGE_INFORMATIONS"), + 0, aDesktop, false, this, SLOT(onChangeInformations())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_SAVEDATAFLOWSTATE")); + createAction( SaveDataflowStateId, tr("TOP_SAVEDATAFLOWSTATE"), QIconSet(aPixmap), + tr("MEN_SAVEDATAFLOWSTATE"), tr("STB_SAVEDATAFLOWSTATE"), + 0, aDesktop, false, this, SLOT(onSaveDataflowState())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_RELOAD_DATAFLOW")); + createAction( ReloadDataflowId, tr("TOP_RELOAD_DATAFLOW"), QIconSet(aPixmap), + tr("MEN_RELOAD_DATAFLOW"), tr("STB_RELOAD_DATAFLOW"), + 0, aDesktop, false, this, SLOT(onReloadDataflow())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_REBUILD_LINKS")); + createAction( RebuildLinksId, tr("TOP_REBUILD_LINKS"), QIconSet(aPixmap), + tr("MEN_REBUILD_LINKS"), tr("STB_REBUILD_LINKS"), + 0, aDesktop, false, this, SLOT(onRebuildLinks())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_FULL_VIEW")); + createAction( FullViewId, tr("TOP_FULL_VIEW"), QIconSet(aPixmap), + tr("MEN_FULL_VIEW"), tr("STB_FULL_VIEW"), + 0, aDesktop, false, this, SLOT(onFullView())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_CONTROL_VIEW")); + createAction( ControlViewId, tr("TOP_CONTROL_VIEW"), QIconSet(aPixmap), + tr("MEN_CONTROL_VIEW"), tr("STB_CONTROL_VIEW"), + 0, aDesktop, false, this, SLOT(onControlView())); + + aPixmap = aResourceMgr->loadPixmap("YACSGui", tr("ICON_TABLE_VIEW")); + createAction( TableViewId, tr("TOP_TABLE_VIEW"), QIconSet(aPixmap), + tr("MEN_TABLE_VIEW"), tr("STB_TABLE_VIEW"), + 0, aDesktop, false, this, SLOT(onTableView())); + +} + +//! Creates module menus. +/*! + */ +void YACSGui_Module::createMenus() +{ + MESSAGE("YACSGui_Module::createMenus"); + int fileId = createMenu( tr( "MEN_FILE" ), -1, -1 ); + createMenu( NewDataflowId, fileId, 10 ); + createMenu( ModifyDataflowId, fileId, 10 ); + createMenu( ModifySupervDataflowId, fileId, 10 ); + createMenu( ImportDataflowId, fileId, 10 ); + createMenu( ImportSupervDataflowId, fileId, 10 ); + createMenu( ExportDataflowId, fileId, 10 ); + + int supervisorId = createMenu( tr( "MEN_SUPERVISOR" ), -1, -1, 10 ); + createMenu( AddNodeId, supervisorId, -1 ); + createMenu( separator(), supervisorId, -1 ); + createMenu( SuspendResumeDataflowId, supervisorId, -1 ); + createMenu( RemoteRunDataflowId, supervisorId, -1 ); + createMenu( RunDataflowId, supervisorId, -1 ); + createMenu( KillDataflowId, supervisorId, -1 ); + createMenu( separator(), supervisorId, -1 ); + createMenu( ToggleStopOnErrorId, supervisorId, -1 ); + createMenu( separator(), supervisorId, -1 ); + createMenu( AddDataflowInStudyId, supervisorId, -1 ); + createMenu( ChangeInformationsId, supervisorId, -1 ); + createMenu( separator(), supervisorId, -1 ); + createMenu( SaveDataflowStateId, supervisorId, -1 ); + createMenu( ReloadDataflowId, supervisorId, -1 ); + createMenu( RebuildLinksId, supervisorId, -1 ); + + int dataflowTbId = createTool( tr("TOOLBAR_DATAFLOW") ); + createTool( NewDataflowId, dataflowTbId ); + createTool( ModifyDataflowId, dataflowTbId ); + createTool( ModifySupervDataflowId, dataflowTbId ); + createTool( ImportDataflowId, dataflowTbId ); + createTool( ImportSupervDataflowId, dataflowTbId ); + createTool( ExportDataflowId, dataflowTbId ); + createTool( separator(), dataflowTbId ); + createTool( AddDataflowInStudyId, dataflowTbId ); + createTool( separator(), dataflowTbId ); + createTool( ReloadDataflowId, dataflowTbId ); + createTool( RebuildLinksId, dataflowTbId ); + createTool( separator(), dataflowTbId ); + createTool( FullViewId, dataflowTbId ); + createTool( ControlViewId, dataflowTbId ); + createTool( TableViewId, dataflowTbId ); + createTool( separator(), dataflowTbId ); + createTool( SaveDataflowStateId, dataflowTbId ); + + int executionTbId = createTool( tr("TOOLBAR_EXECUTION") ); + createTool( SuspendResumeDataflowId, executionTbId ); + createTool( RemoteRunDataflowId, executionTbId ); + createTool( RunDataflowId, executionTbId ); + createTool( separator(), executionTbId ); + createTool( KillDataflowId, executionTbId ); + createTool( ToggleStopOnErrorId, executionTbId ); +} + +//! Defines which windows should be created. +/*! + */ +void YACSGui_Module::windows( QMap& mappa ) const +{ + MESSAGE("YACSGui_Module::windows"); + mappa.insert( LightApp_Application::WT_ObjectBrowser, Qt::DockLeft ); + mappa.insert( LightApp_Application::WT_PyConsole, Qt::DockBottom ); +} + +//! Defines viewer type. +/*! + */ +void YACSGui_Module::viewManagers( QStringList& lst ) const +{ + MESSAGE("YACSGui_Module::viewManagers"); + lst.append( QxGraph_Viewer::Type() ); +} + + +//! Inherited public slot. Called on a module activating. +/*! + */ +bool YACSGui_Module::activateModule( SUIT_Study* theStudy ) +{ + MESSAGE("YACSGui_Module::activateModule"); + bool bOk = SalomeApp_Module::activateModule( theStudy ); + setMenuShown( true ); + setToolShown( true ); + + RuntimeSALOME::setRuntime(); + return bOk; +} + +//! Inherited public slot. Called on a module deactivating. +/*! + */ +bool YACSGui_Module::deactivateModule( SUIT_Study* theStudy ) +{ + MESSAGE("YACSGui_Module::deactivateModule"); + setMenuShown( false ); + setToolShown( false ); + return SalomeApp_Module::deactivateModule( theStudy ); +} + +//! Module's engine IOR +/*! + */ +QString YACSGui_Module::engineIOR() const +{ + MESSAGE("YACSGui_Module::engineIOR"); + CORBA::String_var anIOR = getApp()->orb()->object_to_string( InitYACSGuiGen( getApp() ) ); + return QString( anIOR.in() ); +} + +//! Gets a reference to the module's engine +/*! + */ +YACSGui_ORB::YACSGui_Gen_ptr YACSGui_Module::InitYACSGuiGen( SalomeApp_Application* app ) +{ + MESSAGE("YACSGui_Module::InitYACSGuiGen"); + Engines::Component_var comp = app->lcc()->FindOrLoad_Component( "YACSContainer","YACSGui" ); + YACSGui_ORB::YACSGui_Gen_ptr clr = YACSGui_ORB::YACSGui_Gen::_narrow(comp); + ASSERT(!CORBA::is_nil(clr)); + return clr; +} + + +void YACSGui_Module::createGraph( SUIT_ViewManager* theVM ) +{ + MESSAGE("YACSGui_Module::createGraph"); + QxGraph_ViewWindow* aVW = dynamic_cast( theVM->getActiveView() ); + if ( aVW ) + { + // create graph with null Proc : waiting for import operation! + YACS::ENGINE::Proc* aProc = 0; + YACSGui_Loader::PrsDataMap aPrsData; + YACSGui_Loader::PortLinkDataMap aPortLinkData; + YACSGui_Loader::LabelLinkDataMap aLabelLinkData; + displayGraph( aProc, aPrsData, aPortLinkData, aLabelLinkData ); + } +} + +//! Private slot. Creates a new empty dataflow. +/*! + */ +void YACSGui_Module::onNewDataflow() +{ + MESSAGE("YACSGui_Module::onNewDataflow"); + printf("YACSGui_Module::newDataflow\n"); + SUIT_ViewManager* aVM = getApp()->createViewManager( QxGraph_Viewer::Type() ); + createGraph(aVM); +} + +//! Private slot. Imports uneditable dataflow from the XML file(choosing via a file dialog) +/*! + */ +void YACSGui_Module::onImportDataflow() +{ + MESSAGE("YACSGui_Module::onImportDataflow"); + ImportDataflowFromFile(false); +} + +//! Private slot. Imports editable dataflow from the XML file(choosing via a file dialog) +/*! + */ +void YACSGui_Module::onModifyDataflow() +{ + MESSAGE("YACSGui_Module::onModifyDataflow"); + ImportDataflowFromFile(true); +} + +//! Private slot. Imports uneditable SUPERV dataflow from the XML file(choosing via a file dialog) +/*! + */ +void YACSGui_Module::onImportSupervDataflow() +{ + MESSAGE("YACSGui_Module::onImportSupervDataflow"); + ImportDataflowFromFile(false, true); +} + +//! Private slot. Imports editable SUPERV dataflow from the XML file(choosing via a file dialog) +/*! + */ +void YACSGui_Module::onModifySupervDataflow() +{ + MESSAGE("YACSGui_Module::onModifySupervDataflow"); + ImportDataflowFromFile(true, true); +} + +//! Private slot. Exports current dataflow to XML file. +/*! + */ +void YACSGui_Module::onExportDataflow() +{ + MESSAGE("YACSGui_Module::onExportDataflow"); + if ( !activeGraph() ) + return; + Proc* aProc = activeGraph()->getProc(); + if ( !aProc ) + return; + + QString aFileName = SUIT_FileDlg::getFileName( application()->desktop(), aProc->getName(), "*.xml", tr("TLT_EXPORT_DATAFLOW"), false ); + if (aFileName.isEmpty()) + return; + + YACSGui_VisitorSaveSchema aWriter( this, aProc ); + aWriter.openFileSchema( aFileName ); + aWriter.visitProc( aProc ); + aWriter.closeFileSchema(); +} + +//! Private slot. Reloads current dataflow. +/*! + */ +void YACSGui_Module::onReloadDataflow() +{ + MESSAGE("YACSGui_Module::onReloadDataflow"); + YACSGui_Graph* aGraph = activeGraph(); + if (aGraph) + { + aGraph->setToUpdate(true); + aGraph->update(); + } +} + +//! Private slot. Rebuilds dataflow links. +/*! + */ +void YACSGui_Module::onRebuildLinks() +{ + MESSAGE("YACSGui_Module::onRebuildLinks"); + YACSGui_Graph* aGraph = activeGraph(); + if (aGraph) aGraph->rebuildLinks(); +} + +//! Private slot. Open dialog for add node to current dataflow. +/*! + */ +void YACSGui_Module::onAddNode() +{ + MESSAGE("YACSGui_Module::onAddNode"); + YACSGui_Graph* aGraph = activeGraph(); + if (!aGraph) + { + SUIT_MessageBox::warn1(getApp()->desktop(), + tr("WARNING"), + tr("MSG_NO_DATAFLOW_SELECTED"), + tr("BUT_OK")); + return; + } + + YACSGui_DataModel* aModel = getDataModel(); + if ( aModel && !aModel->isEditable(activeGraph()->getProc()) ) + { + SUIT_MessageBox::warn1(getApp()->desktop(), + tr("WARNING"), + tr("MSG_DATAFLOW_NOT_EDITABLE"), + tr("BUT_OK")); + return; + } +} + +//! Private slot. Starts dataflow execution. +/*! + */ +void YACSGui_Module::onRunDataflow() +{ + MESSAGE("YACSGui_Module::onRunDataflow"); + YACSGui_Executor* anExecutor = findExecutor(); + if (anExecutor) + anExecutor->runDataflow(); +} + +//! Private slot. Starts remote dataflow execution. +/*! + */ +void YACSGui_Module::onRemoteRunDataflow() +{ + MESSAGE("YACSGui_Module::onRemoteRunDataflow"); + YACSGui_Executor* anExecutor = findExecutor(); + if (anExecutor) + anExecutor->runDataflow(true); +} + +//! Private slot. Kills dataflow execution. +/*! + */ +void YACSGui_Module::onKillDataflow() +{ + MESSAGE("YACSGui_Module::onKillDataflow"); + YACSGui_Executor* anExecutor = findExecutor(); + if (anExecutor) + { + if (!anExecutor->isRunning()) + { + SUIT_MessageBox::warn1(getApp()->desktop(), + tr("WARNING"), + tr("MSG_DATAFLOW_IS_NOT_RUNNING"), + tr("BUT_OK")); + return; + } + } + anExecutor->stopDataflow(); + //myExecutors[aProc] = 0; //@ +} + +//! Private slot. Suspends or resumes dataflow execution. +/*! + */ +void YACSGui_Module::onSuspendResumeDataflow() +{ + MESSAGE("YACSGui_Module::onSuspendResumeDataflow"); + YACSGui_Executor* anExecutor = findExecutor(); + if (anExecutor) + { + RunModeMap::iterator anIterator = _runModeMap.find(anExecutor); + YACSGui_RunMode* aRunMode = 0; + if (anIterator != _runModeMap.end()) + aRunMode = (*anIterator).second; + else + { + aRunMode = new YACSGui_RunMode(anExecutor, application()->desktop()); + _runModeMap[anExecutor] = aRunMode; + } + if (!aRunMode->isShown()) + aRunMode->show(); + } +} + +void YACSGui_Module::onFilterNextSteps() +{ + MESSAGE("YACSGui_Module::onFilterNextSteps --- NOT YET IMPLEMENTED!"); + YACSGui_Executor* anExecutor = findExecutor(); + if (anExecutor) + { + } +} + +void YACSGui_Module::onSaveDataflowState() +{ + MESSAGE("YACSGui_Module::onSaveDataflowState --- NOT YET IMPLEMENTED!"); + YACSGui_Executor* anExecutor = findExecutor(); + if (anExecutor) + { + } +} + +void YACSGui_Module::onToggleStopOnError() +{ + MESSAGE("YACSGui_Module::onToggleStopOnError"); + YACSGui_Executor* anExecutor = findExecutor(); + if (anExecutor) + { + anExecutor->setStopOnError(true); + } +} + +//! Private slot. Add current dataflow to study. +/*! + */ +void YACSGui_Module::onAddDataflowInStudy() +{ + MESSAGE("YACSGui_Module::onAddDataflowInStudy"); + YACSGui_Graph* aGraph = activeGraph(); + + if (aGraph) { + Proc* aProc = aGraph->getProc(); + if (!aProc) + aProc = new Proc("NewDataflow"); + YACSGui_DataModel* aModel = getDataModel(); + if (aModel) + aModel->addData(aProc); + } +} + +//! Private slot. TD: what's this ? +/*! + */ +void YACSGui_Module::onChangeInformations() +{ + MESSAGE("YACSGui_Module::onChangeInformations --- NOT YET IMPLEMENTED!"); +} + +//! Private slot. Switch current dataflow to full view mode. +/*! + */ +void YACSGui_Module::onFullView() +{ + MESSAGE("YACSGui_Module::onFullView --- NOT YET IMPLEMENTED!"); +} + +//! Private slot. Switch current dataflow to control view mode. +/*! + */ +void YACSGui_Module::onControlView() +{ + MESSAGE("YACSGui_Module::onControlView --- NOT YET IMPLEMENTED!"); +} + +//! Private slot. Switch current dataflow to table view mode. +/*! + */ +void YACSGui_Module::onTableView() +{ + MESSAGE("YACSGui_Module::onTableView --- NOT YET IMPLEMENTED!"); +} + +//! Creates and displays presentation of a calculation graph. +/*! + * \param theGraph - graph to be displayed + * \param thePrsData - map of node coordinates and dimensions + */ +YACSGui_Graph* YACSGui_Module::displayGraph( YACS::ENGINE::Proc* theGraph, + const YACSGui_Loader::PrsDataMap& thePrsData, + const YACSGui_Loader::PortLinkDataMap& thePortLinkData, + const YACSGui_Loader::LabelLinkDataMap& theLabelLinkData) +{ + MESSAGE("YACSGui_Module::displayGraph"); + YACSGui_Graph* aGraph = 0; + + QxGraph_Canvas* aCanvas = getCanvas(); + if ( !aCanvas ) + return aGraph; + + aGraph = new YACSGui_Graph( this, aCanvas, theGraph ); + aGraph->show(); + + // Update node geometry + // TODO: not optimal, graph is redrawn twice - + // before and after node geometry is applied - to be improved... + bool needToUpdate = false; + if ( thePrsData.size() ) + { + for ( YACSGui_Loader::PrsDataMap::const_iterator it = thePrsData.begin(); it != thePrsData.end(); it++ ) + { + YACSPrs_ElementaryNode* anItem = aGraph->getItem( (*it).first ); + YACSGui_Loader::PrsData aData = (*it).second; + + if ( !anItem ) + continue; + + YACSPrs_BlocNode* aBloc = dynamic_cast(anItem); + if ( aBloc ) + { + aBloc->resize( (int)aData.width, (int)aData.height ); + } + + anItem->setIsCheckAreaNeeded(false); + anItem->move( aData.x, aData.y ); + anItem->setIsCheckAreaNeeded(true); + anItem->setZ( aData.z ); + } + needToUpdate = true; + } + + // Update port links presentations + if ( thePortLinkData.size() ) + { + for ( YACSGui_Loader::PortLinkDataMap::const_iterator it = thePortLinkData.begin(); it != thePortLinkData.end(); it++ ) + { + // (*it).first.first is an output port engine + // (*it).first.second is an input port engine + YACSPrs_ElementaryNode* aFromNodePrs = aGraph->getItem( (*it).first.first->getNode() ); + if ( !aFromNodePrs ) continue; + + std::list aLinksPrs = aFromNodePrs->getPortPrs( (*it).first.first )->getLinks(); + for ( std::list::iterator itL = aLinksPrs.begin(); itL != aLinksPrs.end(); itL++ ) + { + if ( YACSPrs_PortLink* aPortLink = dynamic_cast( *itL ) ) + { + if ( aPortLink->getInputPort()->getEngine() == (*it).first.second ) + { + aPortLink->setPoints((*it).second); + aPortLink->merge(); + } + } + } + } + needToUpdate = true; + } + + // Update label links presentations + if ( theLabelLinkData.size() ) + { + for ( YACSGui_Loader::LabelLinkDataMap::const_iterator it = theLabelLinkData.begin(); it != theLabelLinkData.end(); it++ ) + { + YACSPrs_ElementaryNode* aSlaveNodePrs = aGraph->getItem( (*it).first ); + if ( !aSlaveNodePrs ) continue; + + if ( YACSPrs_LabelLink* aLinkPrs = aSlaveNodePrs->getLabelLink() ) + { + aLinkPrs->setPoints((*it).second); + aLinkPrs->merge(); + } + } + needToUpdate = true; + } + + if ( needToUpdate ) aCanvas->update(); +} + +//! Returns the presentation of a given calculation graph. +/*! + */ +YACSGui_Graph* YACSGui_Module::getGraph( YACS::ENGINE::Proc* theGraph ) +{ + MESSAGE("YACSGui_Module::getGraph"); + YACSGui_Graph* aGraph = 0; + // TODO - find a graph in all viewers + // ... + // TEMPORARY solution: + if ( activeGraph() && activeGraph()->getProc() == theGraph ) + { + aGraph = activeGraph(); + } + + return aGraph; +} + +//! Returns the presentation of a the calculation graph corresponding to the active view. +/*! + */ +YACSGui_Graph* YACSGui_Module::activeGraph() +{ + MESSAGE("YACSGui_Module::activeGraph"); + YACSGui_Graph* aGraph = 0; + QxGraph_Canvas* aCanvas = getCanvas(); + if ( aCanvas ) + // Assume that there's the one and only prs per a canvas + aGraph = dynamic_cast( aCanvas->getPrs() ); + return aGraph; +} + +//! Returns the graph viewer instance +/*! + */ +QxGraph_Viewer* YACSGui_Module::getViewer() +{ + MESSAGE("YACSGui_Module::getViewer"); + QxGraph_Viewer* aViewer = 0; + QxGraph_ViewManager* aVM = + dynamic_cast( getApp()->getViewManager( QxGraph_Viewer::Type(), true ) ); + if ( aVM ) + aViewer = dynamic_cast( aVM->getViewModel() ); + return aViewer; +} + +//! Returns the canvas for graph drawing +/*! + */ +QxGraph_Canvas* YACSGui_Module::getCanvas() +{ + MESSAGE("YACSGui_Module::getCanvas"); + QxGraph_Canvas* aCanvas = 0; + QxGraph_Viewer* aViewer = getViewer(); + if ( aViewer ) + aCanvas = aViewer->getCanvas(); + return aCanvas; +} + +void YACSGui_Module::createElementaryNodePrs() +{ + MESSAGE("YACSGui_Module::createElementaryNodePrs --- NOT YET IMPLEMENTED!"); + /* if ( myGraph ) + { + YACS::ENGINE::Node* aNode = 0; // temporary solution for test + YACSPrs_ElementaryNode* anElemNode = + new YACSPrs_ElementaryNode(SUIT_Session::session()->resourceMgr(), myGraph->getCanvas(), aNode); + myGraph->getCanvas()->getPrs()->addItem(anElemNode); // add item for the current display mode + anElemNode->show(); + myGraph->getCanvas()->update(); + }*/ +} + +//! Create new instance of data model and return it. +/*! + */ +CAM_DataModel* YACSGui_Module::createDataModel() +{ + MESSAGE("YACSGui_Module::createDataModel"); + return new YACSGui_DataModel( this ); +} + +//! Retuns data model. +/*! + */ +YACSGui_DataModel* YACSGui_Module::getDataModel() const +{ + MESSAGE("YACSGui_Module::getDataModel"); + YACSGui_DataModel* aModel = dynamic_cast( dataModel() ); + return aModel; +} + +//! Load dataflow from file. +/*! + * \param setEditable - define if the dataflow wiil be editable. + */ +void YACSGui_Module::ImportDataflowFromFile(const bool setEditable, bool fromSuperv) +{ + MESSAGE("YACSGui_Module::ImportDataflowFromFile"); + QString caption; + if (fromSuperv) + { + if (setEditable) + caption = QString(tr("TLT_MODIFY_SUPERV_DATAFLOW")); + else + caption = QString(tr("TLT_IMPORT_SUPERV_DATAFLOW")); + } + else + { + if (setEditable) + caption = QString(tr("TLT_MODIFY_DATAFLOW")); + else + caption = QString(tr("TLT_IMPORT_DATAFLOW")); + } + QString aFileName = SUIT_FileDlg::getFileName( application()->desktop(), "", "*.xml", caption, true ); + + if (aFileName.isEmpty()) + return; + QString tmpFileName = aFileName; + + if (fromSuperv) + { + YACSGui_ORB::YACSGui_Gen_ptr engineRef = InitYACSGuiGen(getApp()); + try + { + tmpFileName = engineRef->convertSupervFile(aFileName); + } + catch(...) + { + std::cerr<<"Unexpected exception in convertSupervFile " <desktop(), + tr("WARNING"), + tr("Unexpected exception in convertSupervFile"), + tr("BUT_OK")); + return; + } + } + + //TD: Here check if the study already contains a graph imported from the same file + + YACSGui_Loader aLoader; + + try + { + Proc* aProc = 0; + if (!tmpFileName.isEmpty()) + aProc = aLoader.load(tmpFileName); + + //TD: Check the result of file loading + if (!aProc) + { + SUIT_MessageBox::error1(getApp()->desktop(), + tr("ERROR"), + tr("MSG_IMPORT_FILE_ERROR"), + tr("BUT_OK")); + return; + } + + aProc->setName(QFileInfo(aFileName).fileName ()); + + SUIT_ViewManager* aVM = getApp()->createViewManager( QxGraph_Viewer::Type() ); + + // set caption for graph's view window + QxGraph_ViewWindow* aVW = dynamic_cast( aVM->getActiveView() ); + if ( aVW ) aVW->setCaption(QFileInfo(aFileName).fileName ()); + + YACSGui_DataModel* aModel = getDataModel(); + if (aModel) + aModel->add(aProc, setEditable); + // TD: add graph to study. + + int w, h; + const YACSGui_Loader::PrsDataMap& aPrsData = aLoader.getPrsData( aProc, w, h ); + const YACSGui_Loader::PortLinkDataMap& aPortLinkData = aLoader.getPortLinkData( aProc ); + const YACSGui_Loader::LabelLinkDataMap& aLabelLinkData = aLoader.getLabelLinkData( aProc ); + if ( aVW ) + { + if ( w > 0 && h > 0 ) + aVW->getViewModel()->getCanvas()->resize( w, h ); + displayGraph( aProc, aPrsData, aPortLinkData, aLabelLinkData ); + } + } + catch (YACS::Exception& ex) + { + std::cerr<<"YACSGui_Module::importDataflow: " <setGraph(activeGraph()); + myExecutors[theProc] = anExecutor; + } + + return anExecutor; +} + +//! Returns executor for active graph or nul if no active graph +/*! + */ +YACSGui_Executor* YACSGui_Module::findExecutor() +{ + MESSAGE("YACSGui_Module::findExecutor"); + YACSGui_Graph* aGraph = activeGraph(); + YACSGui_Executor* anExecutor = 0; + Proc* aProc = 0; + if (aGraph) + aProc = aGraph->getProc(); + + if (!aGraph || !aProc) + { + SUIT_MessageBox::warn1(getApp()->desktop(), + tr("WARNING"), + tr("MSG_NO_DATAFLOW_LOADED"), + tr("BUT_OK")); + return 0; + } + + anExecutor = getExecutor(aProc); + return anExecutor; +} + +YACSGui_RunMode* YACSGui_Module::getRunMode(YACSGui_Executor* executor) +{ + RunModeMap::iterator anIterator = _runModeMap.find(executor); + YACSGui_RunMode* aRunMode = 0; + if (anIterator != _runModeMap.end()) + aRunMode = _runModeMap[executor]; + //SCRUTE(aRunMode); + return aRunMode; +} diff --git a/src/gui/YACSGui_Module.h b/src/gui/YACSGui_Module.h new file mode 100644 index 000000000..9b06798ff --- /dev/null +++ b/src/gui/YACSGui_Module.h @@ -0,0 +1,149 @@ +// Copyright (C) 2003 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 YACSGui_Module_HeaderFile +#define YACSGui_Module_HeaderFile + +#include +#include +#include CORBA_CLIENT_HEADER(yacsgui) + +#include + +#include + +#include + +class SUIT_ViewWindow; +class SUIT_ViewManager; +class YACSGui_DataModel; +class YACSGui_Graph; +class YACSGui_Executor; +class QxGraph_Viewer; +class QxGraph_Canvas; +class YACSGui_RunMode; + +class SalomeApp_Application; +class YACSGui_Module : public SalomeApp_Module +{ + Q_OBJECT + +public: + enum { // Menu "File" + NewDataflowId, ModifyDataflowId, ImportDataflowId, ExportDataflowId, + ModifySupervDataflowId, ImportSupervDataflowId, + + // Menu "Supervisor" + AddNodeId, + RunDataflowId, RemoteRunDataflowId, KillDataflowId, SuspendResumeDataflowId, + ToggleStopOnErrorId, FilterNextStepsId, + AddDataflowInStudyId, ChangeInformationsId, SaveDataflowStateId, ReloadDataflowId, + RebuildLinksId, + + // View mode section of "Dataflow" toolbar + FullViewId, ControlViewId, TableViewId + }; + +public: + YACSGui_Module(); + ~YACSGui_Module(); + + virtual void initialize( CAM_Application* ); + + QString engineIOR() const; + static YACSGui_ORB::YACSGui_Gen_ptr InitYACSGuiGen( SalomeApp_Application* ); + + YACSGui_DataModel* getDataModel() const; + + virtual void windows( QMap& ) const; + virtual void viewManagers( QStringList& ) const; + + YACSGui_Graph* displayGraph( YACS::ENGINE::Proc*, + const YACSGui_Loader::PrsDataMap&, + const YACSGui_Loader::PortLinkDataMap&, + const YACSGui_Loader::LabelLinkDataMap&); + YACSGui_Graph* getGraph( YACS::ENGINE::Proc* ); + YACSGui_Graph* activeGraph(); + + QxGraph_Viewer* getViewer(); + QxGraph_Canvas* getCanvas(); + void updateViewer(); + + QString iconName() const {return tr("YACS_MODULE_ICON");} + + YACSGui_RunMode* getRunMode(YACSGui_Executor* executor); + +public slots: + virtual bool activateModule( SUIT_Study* ); + virtual bool deactivateModule( SUIT_Study* ); + +protected: + virtual CAM_DataModel* createDataModel(); + void createGraph( SUIT_ViewManager* ); + +private slots: + void onNewDataflow(); + void onImportDataflow(); + void onModifyDataflow(); + void onImportSupervDataflow(); + void onModifySupervDataflow(); + void onExportDataflow(); + + void onAddNode(); + + void onReloadDataflow(); + void onRebuildLinks(); + + void onRunDataflow(); + void onKillDataflow(); + void onSuspendResumeDataflow(); + void onRemoteRunDataflow(); + void onFilterNextSteps(); + void onSaveDataflowState(); + void onToggleStopOnError(); + + void onAddDataflowInStudy(); + void onChangeInformations(); + + void onFullView(); + void onControlView(); + void onTableView(); + +private: + void createActions(); + void createMenus(); + + void ImportDataflowFromFile(const bool setEditable, bool fromSuperv = false); + + void createElementaryNodePrs(); // for test presentations + + YACSGui_Executor* getExecutor( YACS::ENGINE::Proc* ); + YACSGui_Executor* findExecutor(); + +private: + typedef std::map ExecutorMap; + typedef std::map RunModeMap; + + ExecutorMap myExecutors; + RunModeMap _runModeMap; + YACSGui_RunMode* _myRunMode; +}; + +#endif diff --git a/src/gui/YACSGui_Node.cxx b/src/gui/YACSGui_Node.cxx new file mode 100644 index 000000000..4e2bc5e2e --- /dev/null +++ b/src/gui/YACSGui_Node.cxx @@ -0,0 +1,399 @@ +// Copyright (C) 2003 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 +// + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +/*! + * =========================== YACSGui_Node =========================== + !*/ + +//! Constructor +/*! +*/ +YACSGui_Node::YACSGui_Node(YACSGui_Graph* theGraph) : myGraph(theGraph) +{ +} + +//! Destructor +/*! +*/ +YACSGui_Node::~YACSGui_Node() +{ +} + +//! Returns the resource manager object +/*! + */ +SUIT_ResourceMgr* YACSGui_Node::resMgr() const +{ + return SUIT_Session::session()->resourceMgr(); +} + +//! Updates a node presentation +/*! + * New graphic items should be created with a null canvas pointer. + * They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide(). + */ +void YACSGui_Node::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem ) +{ + if ( !myGraph ) + return; + + if ( theItem ) + { + // TODO - Here any parameters of exisiting items should be updated + // ... + theItem->update(); + } +} + +/*! + * =========================== YACSGui_ServiceNode =========================== + !*/ + +//! Constructor +/*! +*/ +YACSGui_ServiceNode::YACSGui_ServiceNode(YACSGui_Graph* theGraph) : YACSGui_Node(theGraph) +{ +} + +//! Destructor +/*! +*/ +YACSGui_ServiceNode::~YACSGui_ServiceNode() +{ +} + +//! Updates a node presentation +/*! + * New graphic items should be created with a null canvas pointer. + * They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide(). + */ +void YACSGui_ServiceNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem ) +{ + if ( !graph() ) + return; + + if ( !theItem ) { + theItem = new YACSPrs_ServiceNode( resMgr(), 0, theEngine); + graph()->registerStatusObserverWithNode(theEngine); + } + else + { + // TODO - Here any parameters of exisiting items should be updated + // ... + theItem->update(); + } +} + +/*! + * =========================== YACSGui_InlineNode =========================== + !*/ + +//! Constructor +/*! +*/ +YACSGui_InlineNode::YACSGui_InlineNode(YACSGui_Graph* theGraph) : YACSGui_Node(theGraph) +{ +} + +//! Destructor +/*! +*/ +YACSGui_InlineNode::~YACSGui_InlineNode() +{ +} + +//! Updates a node presentation +/*! + * New graphic items should be created with a null canvas pointer. + * They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide(). + */ +void YACSGui_InlineNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem ) +{ + if ( !graph() ) + return; + + if ( !theItem ) { + theItem = new YACSPrs_InlineNode( resMgr(), 0, theEngine); + graph()->registerStatusObserverWithNode(theEngine); + } + else + { + // TODO - Here any parameters of exisiting items should be updated + // ... + theItem->update(); + } +} + +/*! + * =========================== YACSGui_IfNode =========================== + !*/ + +//! Constructor +/*! +*/ +YACSGui_IfNode::YACSGui_IfNode(YACSGui_Graph* theGraph) : YACSGui_Node(theGraph) +{ +} + +//! Destructor +/*! +*/ +YACSGui_IfNode::~YACSGui_IfNode() +{ +} + +//! Updates a node presentation +/*! + * New graphic items should be created with a null canvas pointer. + * They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide(). + */ +void YACSGui_IfNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem ) +{ + if ( !graph() ) + return; + + if ( !theItem ) { + theItem = new YACSPrs_IfNode( resMgr(), 0, theEngine); + graph()->registerStatusObserverWithNode(theEngine); + } + else + { + // TODO - Here any parameters of exisiting items should be updated + // ... + theItem->update(); + } +} + +/*! + * =========================== YACSGui_SwitchNode =========================== + !*/ + +//! Constructor +/*! +*/ +YACSGui_SwitchNode::YACSGui_SwitchNode(YACSGui_Graph* theGraph) : YACSGui_Node(theGraph) +{ +} + +//! Destructor +/*! +*/ +YACSGui_SwitchNode::~YACSGui_SwitchNode() +{ +} + +//! Updates a node presentation +/*! + * New graphic items should be created with a null canvas pointer. + * They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide(). + */ +void YACSGui_SwitchNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem ) +{ + if ( !graph() ) + return; + + if ( !theItem ) { + theItem = new YACSPrs_SwitchNode( resMgr(), 0, theEngine); + graph()->registerStatusObserverWithNode(theEngine); + } + else + { + // TODO - Here any parameters of exisiting items should be updated + // ... + theItem->update(); + } +} + +/*! + * =========================== YACSGui_LoopNode =========================== + !*/ + +//! Constructor +/*! +*/ +YACSGui_LoopNode::YACSGui_LoopNode(YACSGui_Graph* theGraph) : YACSGui_Node(theGraph) +{ +} + +//! Destructor +/*! +*/ +YACSGui_LoopNode::~YACSGui_LoopNode() +{ +} + +//! Updates a node presentation +/*! + * New graphic items should be created with a null canvas pointer. + * They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide(). + */ +void YACSGui_LoopNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem ) +{ + if ( !graph() ) + return; + + if ( !theItem ) { + theItem = new YACSPrs_LoopNode( resMgr(), 0, theEngine); + graph()->registerStatusObserverWithNode(theEngine); + } + else + { + // TODO - Here any parameters of exisiting items should be updated + // ... + theItem->update(); + } +} + +/*! + * =========================== YACSGui_ForEachLoopNode =========================== + !*/ + +//! Constructor +/*! +*/ +YACSGui_ForEachLoopNode::YACSGui_ForEachLoopNode(YACSGui_Graph* theGraph) : YACSGui_Node(theGraph) +{ +} + +//! Destructor +/*! +*/ +YACSGui_ForEachLoopNode::~YACSGui_ForEachLoopNode() +{ +} + +//! Updates a node presentation +/*! + * New graphic items should be created with a null canvas pointer. + * They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide(). + */ +void YACSGui_ForEachLoopNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem ) +{ + if ( !graph() ) + return; + + if ( !theItem ) { + theItem = new YACSPrs_ForEachLoopNode( resMgr(), 0, theEngine); + graph()->registerStatusObserverWithNode(theEngine); + } + else + { + // TODO - Here any parameters of exisiting items should be updated + // ... + theItem->update(); + } +} + +/*! + * =========================== YACSGui_BlocNode =========================== + !*/ + +//! Constructor +/*! +*/ +YACSGui_BlocNode::YACSGui_BlocNode(YACSGui_Graph* theGraph) : YACSGui_Node(theGraph) +{ +} + +//! Destructor +/*! +*/ +YACSGui_BlocNode::~YACSGui_BlocNode() +{ +} + +//! Updates a node presentation +/*! + * New graphic items should be created with a null canvas pointer. + * They can be added to a canvas by QxGraph_Prs::show() and removed from it by hide(). + */ +void YACSGui_BlocNode::update(YACS::ENGINE::Node* theEngine, YACSPrs_ElementaryNode*& theItem ) +{ + if ( !graph() ) + return; + + if ( !theItem ) + { + YACSPrs_BlocNode* aBlocPrs = new YACSPrs_BlocNode( resMgr(), 0, theEngine, + YACSPrs_BlocNode::Expanded, level(theEngine) ); + YACS::ENGINE::Bloc* aBloc = dynamic_cast( theEngine ); + if ( aBloc ) + { + std::set aNodePrsSet; + std::set aNodeSet; + graph()->getAllBlocChildren(aBloc, aNodeSet); + for ( std::set::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ ) + { + if ( !graph()->getItem( *it ) ) graph()->update( *it ); + aNodePrsSet.insert( graph()->getItem( *it ) ); + } + aBlocPrs->setChildren( aNodePrsSet ); + + theItem = aBlocPrs; + + graph()->registerStatusObserverWithNode(theEngine); + } + } + else + { + // TODO - Here any parameters of exisiting items should be updated + // ... + theItem->update(); + } +} + +//! Returns a nesting level of Bloc node +int YACSGui_BlocNode::level(YACS::ENGINE::Node* theEngine) +{ + //YACS::ENGINE::Bloc* aBloc = dynamic_cast( theEngine ); + //if ( !aBloc ) return -1; + + int aLevel = 3; + YACS::ENGINE::ComposedNode* aFather = theEngine->getFather(); + while ( !dynamic_cast( aFather ) ) + { + if ( dynamic_cast( aFather ) ) aLevel += 4; + aFather = aFather->getFather(); + } + return aLevel; +} diff --git a/src/gui/YACSGui_Node.h b/src/gui/YACSGui_Node.h new file mode 100644 index 000000000..21d6d876c --- /dev/null +++ b/src/gui/YACSGui_Node.h @@ -0,0 +1,152 @@ +// Copyright (C) 2003 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 YACSGui_Node_HeaderFile +#define YACSGui_Node_HeaderFile + +#include + +#include + +class SUIT_ResourceMgr; + +/*! Interface of a driver that creates specific graphic items for some type of + * graph nodes. It also updates any parameters of existing graphic items + * before they are redrawn by the viewer. + * Drivers for each kind of node should be derived from YACSGui_Node, + * with their own implementation of update() method (it should become + * a pure virtual function in the final version). + */ +class YACSGui_Node +{ + public: + YACSGui_Node(YACSGui_Graph*); + virtual ~YACSGui_Node(); + + virtual void update(YACS::ENGINE::Node*, YACSPrs_ElementaryNode*&); + +protected: + YACSGui_Graph* graph() const { return myGraph; } + SUIT_ResourceMgr* resMgr() const; + +private: + YACSGui_Graph* myGraph; +}; + +/*! Interface of a driver that creates specific graphic items for Service + * graph nodes. It also updates any parameters of existing graphic items + * before they are redrawn by the viewer. + */ +class YACSGui_ServiceNode : public YACSGui_Node +{ + public: + YACSGui_ServiceNode(YACSGui_Graph*); + virtual ~YACSGui_ServiceNode(); + + virtual void update(YACS::ENGINE::Node*, YACSPrs_ElementaryNode*&); + +}; + +/*! Interface of a driver that creates specific graphic items for Inline + * graph nodes. It also updates any parameters of existing graphic items + * before they are redrawn by the viewer. + */ +class YACSGui_InlineNode : public YACSGui_Node +{ + public: + YACSGui_InlineNode(YACSGui_Graph*); + virtual ~YACSGui_InlineNode(); + + virtual void update(YACS::ENGINE::Node*, YACSPrs_ElementaryNode*&); + +}; + +/*! Interface of a driver that creates specific graphic items for If + * graph nodes. It also updates any parameters of existing graphic items + * before they are redrawn by the viewer. + */ +class YACSGui_IfNode : public YACSGui_Node +{ + public: + YACSGui_IfNode(YACSGui_Graph*); + virtual ~YACSGui_IfNode(); + + virtual void update(YACS::ENGINE::Node*, YACSPrs_ElementaryNode*&); + +}; + +/*! Interface of a driver that creates specific graphic items for Switch + * graph nodes. It also updates any parameters of existing graphic items + * before they are redrawn by the viewer. + */ +class YACSGui_SwitchNode : public YACSGui_Node +{ + public: + YACSGui_SwitchNode(YACSGui_Graph*); + virtual ~YACSGui_SwitchNode(); + + virtual void update(YACS::ENGINE::Node*, YACSPrs_ElementaryNode*&); + +}; + +/*! Interface of a driver that creates specific graphic items for ForLoop and WhileLoop + * graph nodes. It also updates any parameters of existing graphic items + * before they are redrawn by the viewer. + */ +class YACSGui_LoopNode : public YACSGui_Node +{ + public: + YACSGui_LoopNode(YACSGui_Graph*); + virtual ~YACSGui_LoopNode(); + + virtual void update(YACS::ENGINE::Node*, YACSPrs_ElementaryNode*&); + +}; + +/*! Interface of a driver that creates specific graphic items for ForEachLoop + * graph nodes. It also updates any parameters of existing graphic items + * before they are redrawn by the viewer. + */ +class YACSGui_ForEachLoopNode : public YACSGui_Node +{ + public: + YACSGui_ForEachLoopNode(YACSGui_Graph*); + virtual ~YACSGui_ForEachLoopNode(); + + virtual void update(YACS::ENGINE::Node*, YACSPrs_ElementaryNode*&); + +}; + +/*! Interface of a driver that creates specific graphic items for Bloc + * graph nodes. It also updates any parameters of existing graphic items + * before they are redrawn by the viewer. + */ +class YACSGui_BlocNode : public YACSGui_Node +{ + public: + YACSGui_BlocNode(YACSGui_Graph*); + virtual ~YACSGui_BlocNode(); + + virtual void update(YACS::ENGINE::Node*, YACSPrs_ElementaryNode*&); + + int level(YACS::ENGINE::Node* theEngine); +}; + +#endif diff --git a/src/gui/YACSGui_Observer.cxx b/src/gui/YACSGui_Observer.cxx new file mode 100644 index 000000000..9f8839bc6 --- /dev/null +++ b/src/gui/YACSGui_Observer.cxx @@ -0,0 +1,291 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 +// + +#include "YACSGui_Observer.h" + +#include "YACSGui_Graph.h" +#include "YACSGui_Module.h" +#include "YACSGui_Executor.h" +#include "YACSPrs_ElementaryNode.h" +#include "YACSGui_RunMode.h" + +#include "SALOME_Event.hxx" + +#include +#include + +#include + +#include +#include +#include +#include "utilities.h" + +using namespace YACS::ENGINE; +using namespace std; + +YACSEvent::YACSEvent(std::pair aYACSEvent) + : QCustomEvent(YACS_EVENT), _event(aYACSEvent) +{ +} + + +YACSGui_Observer::YACSGui_Observer(YACSGui_Graph* theGraph): + Observer(), + myGraph(theGraph) +{ +} + +void YACSGui_Observer::notifyObserver(YACS::ENGINE::Node* object, const std::string& event) +{ + //MESSAGE("YACSGui_Observer::notifyObserver(YACS::ENGINE::Node* object, const std::string& event)"); + if (event == "status") + { + if ( myGraph && !myGraph->getItem(object) ) + { + if ( dynamic_cast( object->getFather() ) + && + myGraph->getItem(object->getFather()) ) + { + // transmit event to ForEachLoop node + ProcessVoidEvent( new TVoidMemFunEvent( myGraph->getItem(object->getFather()), &YACSPrs_ElementaryNode::update ) ); + + // transmit event from the last clone node to original loop body node + if ( object == (dynamic_cast( object->getFather() ))->getNodes().back() ) + { + std::set aChildren = dynamic_cast( object->getFather() )->edGetDirectDescendants(); + for(std::set::iterator iter=aChildren.begin();iter!=aChildren.end();iter++) + if ( myGraph->getItem(*iter) ) + ProcessVoidEvent( new TVoidMemFun1ArgEvent( myGraph->getItem(*iter), + &YACSPrs_ElementaryNode::updateForEachLoopBody, + object ) ); + } + } + } + else if ( myGraph && myGraph->getItem(object) ) + { + if ( dynamic_cast( object ) + && + object->getState() == YACS::TOACTIVATE ) + { + std::vector aCloneNodes = dynamic_cast(object)->getNodes(); + for(std::vector::iterator iter=aCloneNodes.begin();iter!=aCloneNodes.end();iter++) + myGraph->registerStatusObserverWithNode(*iter); + } + else + ProcessVoidEvent( new TVoidMemFunEvent( myGraph->getItem(object), &YACSPrs_ElementaryNode::update ) ); + } + } +} + +void YACSGui_Observer::notifyObserver(const int theID, const std::string& theEvent) +{ + //MESSAGE("YACSGui_Observer::notifyObserver(const int theID, const std::string& theEvent)"); + // Get node by its id + YACS::ENGINE::Node* aNode = myGraph->getNodeById(theID); + + // Call notifyObserver() for the node + if (aNode) + notifyObserver(aNode, theEvent); +} + +void YACSGui_Observer::notifyObserver(const std::string& theName, const std::string& theEvent) +{ + //MESSAGE("YACSGui_Observer::notifyObserver(const std::string& theName, const std::string& theEvent)"); + // Get node by its name + YACS::ENGINE::Node* aNode = myGraph->getNodeByName(theName); + + // Call notifyObserver() for the node + if (aNode) + notifyObserver(aNode, theEvent); +} + +/*! + * set node state in local (GUI) graph. + * setState emit a local event to the local dispatcher for gui events + */ +void YACSGui_Observer::setNodeState(const int theID, const int theState) +{ + //MESSAGE("YACSGui_Observer::setNodeState(const int theID, const int theState)"); + // Get node by its id + YACS::ENGINE::Node* aNode = myGraph->getNodeById(theID); + + // Set state + if (aNode) + aNode->setState(YACS::StatesForNode(theState)); +} + +/*! + * set node state in local (GUI) graph. + * setState emit a local event to the local dispatcher for gui events + */ +void YACSGui_Observer::setNodeState(const std::string& theName, const int theState) +{ + //MESSAGE("YACSGui_Observer::setNodeState " << theName << " " << theState); + // Get node by its name + YACS::ENGINE::Node* aNode = 0; + + if (theName != "proc") + aNode = myGraph->getNodeByName(theName); + else + aNode = myGraph->getProc(); + + // Set state + if (aNode) + aNode->setState(YACS::StatesForNode(theState)); +} + + + + +Observer_i::Observer_i(YACS::ENGINE::Proc* guiProc, + YACSGui_Module* guiMod, + YACSGui_Executor* guiExec) +{ + //MESSAGE("Observer_i::Observer_i"); + _guiProc = guiProc; + _guiMod = guiMod; + _guiExec = guiExec; + _engineProc = YACSGui_ORB::ProcExec::_nil(); + myImpl = 0; +} + +Observer_i::~Observer_i() +{ +} + +void Observer_i::setConversion() +{ + //MESSAGE("Observer_i::setConversion"); + assert(!CORBA::is_nil(_engineProc)); + YACSGui_ORB::stringArray_var engineNames; + YACSGui_ORB::longArray_var engineIds; + //MESSAGE("---"); + _engineProc->getIds(engineIds.out(), engineNames.out()); + int iLength = engineIds->length(); + int nLength = engineNames->length(); + if (nLength < iLength) iLength = nLength; + for(int i=0; igetChildByName(aName)->getNumId(); + //MESSAGE("---"); + _guiToEngineMap[iGui] = iEng; + _engineToGuiMap[iEng] = iGui; + } + else + { + int iGui = _guiProc->getNumId(); + _guiToEngineMap[iGui] = iEng; + _engineToGuiMap[iEng] = iGui; + } + } +} + +//! process YACS events in main thread (see postEvent) +bool Observer_i::event(QEvent *e) +{ + //MESSAGE("Observer_i::event"); + if (e->type() == YACS_EVENT) + { + YACSEvent *ye = (YACSEvent*)e; + pair myEvent = ye->getYACSEvent(); + int numid = myEvent.first; + string event = myEvent.second; + + if (event == "executor") // --- Executor notification: state + { + //MESSAGE("Observer_i::run executor"); + int execState = _engineProc->getExecutorState(); + YACSGui_RunMode* theRunMode = _guiMod->getRunMode(_guiExec); + if (theRunMode) + { + theRunMode->onNotifyStatus(execState); + list nextSteps; + if ((execState == YACS::WAITINGTASKS) || (execState == YACS::PAUSED)) + { + YACSGui_ORB::stringArray_var nstp = _engineProc->getTasksToLoad(); + for (CORBA::ULong i=0; ilength(); i++) + nextSteps.push_back(nstp[i].in()); + } + theRunMode->onNotifyNextSteps(nextSteps); + } + } + else // --- Node notification + { + if (!myImpl) + return true; + if (_engineToGuiMap.count(numid) == 0) + return true; + int iGui = _engineToGuiMap[numid]; + + if (YACS::ENGINE::Node::idMap.count(iGui) == 0) + return true; + YACS::ENGINE::Node* aNode= YACS::ENGINE::Node::idMap[iGui]; + + string aName = _guiProc->getChildName(aNode); + if (aName == "") + return true; + + if (event == "status") // --- Node notification: status + { + //MESSAGE("Observer_i::run status"); + int aState = _engineProc->getNodeState(numid); + if (aState < 0) + return true; + YACSGui_RunMode* theRunMode = _guiMod->getRunMode(_guiExec); + if (theRunMode) + theRunMode->onNotifyNodeStatus(iGui, aState); + myImpl->setNodeState(aName, aState); + } + } + return true; + } + MESSAGE("--- Wrong event ---"); + return false; +} + +//! CORBA servant implementation +/*! + * post event for treatment by main thread and to avoid deadlocks + * in SALOME Engine with CORBA callbacks. + */ +void Observer_i::notifyObserver(CORBA::Long numid, const char* event) +{ + //MESSAGE("Observer_i::notifyObserver " << numid << " " << event ); + pair myEvent(numid, event); + YACSEvent* evt = new YACSEvent(myEvent); + QApplication::postEvent(this, evt); // Qt will delete it when done +} + +void Observer_i::SetImpl(YACSGui_Observer* theImpl) +{ + //MESSAGE("Observer_i::SetImpl"); + myImpl = theImpl; +} + +void Observer_i::SetRemoteProc(YACSGui_ORB::ProcExec_ptr engineProc) +{ + _engineProc = YACSGui_ORB::ProcExec::_duplicate(engineProc); +} diff --git a/src/gui/YACSGui_Observer.h b/src/gui/YACSGui_Observer.h new file mode 100644 index 000000000..cfbca2d07 --- /dev/null +++ b/src/gui/YACSGui_Observer.h @@ -0,0 +1,95 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSGui_Observer_HeaderFile +#define YACSGui_Observer_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class YACSGui_Graph; +class YACSGui_Module; +class YACSGui_Executor; +class YACS::ENGINE::Node; + +#define YACS_EVENT QEvent::Type( QEvent::User + 7983 ) + +class YACSEvent : public QCustomEvent +{ + public: + YACSEvent(std::pair aYACSEvent); + std::pair getYACSEvent() const { return _event; }; + private: + std::pair _event; +}; + + +class YACSGui_Observer : public YACS::ENGINE::Observer +{ + public: + YACSGui_Observer(YACSGui_Graph* theGraph); + + virtual void notifyObserver(YACS::ENGINE::Node* object,const std::string& event); + + void notifyObserver(const int theID, const std::string& theEvent); + void notifyObserver(const std::string& theName, const std::string& theEvent); + + void setNodeState(const int theID, const int theState); + void setNodeState(const std::string& theName, const int theState); + + private: + YACSGui_Graph* myGraph; +}; + + +class Observer_i : public POA_YACSGui_ORB::Observer, + public PortableServer::RefCountServantBase, + public QObject +{ + public: + Observer_i(YACS::ENGINE::Proc* guiProc, + YACSGui_Module* guiMod, + YACSGui_Executor* guiExec); + virtual ~Observer_i(); + void notifyObserver(CORBA::Long numid, const char* event); + void setConversion(); + void SetImpl(YACSGui_Observer* theImpl); + void SetRemoteProc(YACSGui_ORB::ProcExec_ptr engineProc); + int getEngineId(int guiId) { return _guiToEngineMap[guiId]; }; + protected: + virtual bool event(QEvent *e); + private: + YACSGui_Module* _guiMod; + YACSGui_Executor* _guiExec; + YACS::ENGINE::Proc* _guiProc; + YACSGui_ORB::ProcExec_var _engineProc; + YACSGui_Observer* myImpl; + std::map _guiToEngineMap; + std::map _engineToGuiMap; +}; + + +#endif diff --git a/src/gui/YACSGui_RunMode.cxx b/src/gui/YACSGui_RunMode.cxx new file mode 100644 index 000000000..af72d2bb2 --- /dev/null +++ b/src/gui/YACSGui_RunMode.cxx @@ -0,0 +1,389 @@ + +#include "YACSGui_RunMode.h" +#include "YACSGui_Executor.h" +#include "Executor.hxx" +#include "Proc.hxx" +#include "ComposedNode.hxx" +#include "ElementaryNode.hxx" + +#include +#include +#include +#include + +#include +#include +#include "utilities.h" + +using namespace std; +using namespace YACS::ENGINE; + + + +ComposedNodeViewItem::ComposedNodeViewItem(QListView *parent, QString label) + : QListViewItem(parent, label) +{ + _cf = Qt::black; +} + +ComposedNodeViewItem::ComposedNodeViewItem(QListViewItem *parent, QString label) + : QListViewItem(parent, label) +{ + _cf = Qt::black; +} + +void ComposedNodeViewItem::paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ) +{ + //MESSAGE("ComposedNodeViewItem::paintCell " << column); + QColorGroup _cg( cg ); + QColor c = _cg.text(); + if (column == 1) _cg.setColor( QColorGroup::Text, _cf ); + QListViewItem::paintCell( p, _cg, column, width, alignment ); + if (column == 1) _cg.setColor( QColorGroup::Text, c ); +} + +void ComposedNodeViewItem::setState(int state) +{ + //MESSAGE("ComposedNodeViewItem::setState"); + _state = state; + switch (_state) + { + case YACS::UNDEFINED: _cf=Qt::lightGray; setText(1,"UNDEFINED"); repaint(); break; + case YACS::INITED: _cf=Qt::gray; setText(1,"INITED"); repaint(); break; + case YACS::TOLOAD: _cf=Qt::darkYellow; setText(1,"TOLOAD"); repaint(); break; + case YACS::LOADED: _cf=Qt::darkMagenta; setText(1,"LOADED"); repaint(); break; + case YACS::TOACTIVATE: _cf=Qt::darkCyan; setText(1,"TOACTIVATE"); repaint(); break; + case YACS::ACTIVATED: _cf=Qt::darkBlue; setText(1,"ACTIVATED"); repaint(); break; + case YACS::DESACTIVATED: _cf=Qt::gray; setText(1,"DESACTIVATED"); repaint(); break; + case YACS::DONE: _cf=Qt::darkGreen; setText(1,"DONE"); repaint(); break; + case YACS::SUSPENDED: _cf=Qt::gray; setText(1,"SUSPENDED"); repaint(); break; + case YACS::LOADFAILED: _cf.setHsv(320,255,255); setText(1,"LOADFAILED"); repaint(); break; + case YACS::EXECFAILED: _cf.setHsv( 20,255,255); setText(1,"EXECFAILED"); repaint(); break; + case YACS::PAUSE: _cf.setHsv(180,255,255); setText(1,"PAUSE"); repaint(); break; + case YACS::INTERNALERR: _cf.setHsv(340,255,255); setText(1,"INTERNALERR"); repaint(); break; + case YACS::DISABLED: _cf.setHsv( 40,255,255); setText(1,"DISABLED"); repaint(); break; + case YACS::FAILED: _cf.setHsv( 20,255,255); setText(1,"FAILED"); repaint(); break; + case YACS::ERROR: _cf.setHsv( 0,255,255); setText(1,"ERROR"); repaint(); break; + default: _cf=Qt::lightGray; repaint(); + } +} + + +NodeViewItem::NodeViewItem(QListView *parent, + const QString &text, + Type tt, + YACS::ENGINE::ElementaryNode *node) + : QCheckListItem(parent, text, tt) +{ + _cf = Qt::green; + _node = node; +} + +NodeViewItem::NodeViewItem(QListViewItem *parent, + const QString &text, + Type tt, + YACS::ENGINE::ElementaryNode *node) + : QCheckListItem(parent, text, tt) +{ + _cf = Qt::green; + _node = node; +} + +void NodeViewItem::paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ) +{ + QColorGroup _cg( cg ); + QColor c = _cg.text(); + if (column == 1) _cg.setColor( QColorGroup::Text, _cf ); + QCheckListItem::paintCell( p, _cg, column, width, alignment ); + if (column == 1) _cg.setColor( QColorGroup::Text, c ); +} + +void NodeViewItem::setState(int state) +{ + //MESSAGE("NodeViewItem::setState"); + _state = state; + switch (_state) + { + case YACS::UNDEFINED: _cf=Qt::lightGray; setText(1,"UNDEFINED"); repaint(); break; + case YACS::INITED: _cf=Qt::gray; setText(1,"INITED"); repaint(); break; + case YACS::TOLOAD: _cf=Qt::darkYellow; setText(1,"TOLOAD"); repaint(); break; + case YACS::LOADED: _cf=Qt::darkMagenta; setText(1,"LOADED"); repaint(); break; + case YACS::TOACTIVATE: _cf=Qt::darkCyan; setText(1,"TOACTIVATE"); repaint(); break; + case YACS::ACTIVATED: _cf=Qt::darkBlue; setText(1,"ACTIVATED"); repaint(); break; + case YACS::DESACTIVATED: _cf=Qt::gray; setText(1,"DESACTIVATED"); repaint(); break; + case YACS::DONE: _cf=Qt::darkGreen; setText(1,"DONE"); repaint(); break; + case YACS::SUSPENDED: _cf=Qt::gray; setText(1,"SUSPENDED"); repaint(); break; + case YACS::LOADFAILED: _cf.setHsv(320,255,255); setText(1,"LOADFAILED"); repaint(); break; + case YACS::EXECFAILED: _cf.setHsv( 20,255,255); setText(1,"EXECFAILED"); repaint(); break; + case YACS::PAUSE: _cf.setHsv(180,255,255); setText(1,"PAUSE"); repaint(); break; + case YACS::INTERNALERR: _cf.setHsv(340,255,255); setText(1,"INTERNALERR"); repaint(); break; + case YACS::DISABLED: _cf.setHsv( 40,255,255); setText(1,"DISABLED"); repaint(); break; + case YACS::FAILED: _cf.setHsv( 20,255,255); setText(1,"FAILED"); repaint(); break; + case YACS::ERROR: _cf.setHsv( 0,255,255); setText(1,"ERROR"); repaint(); break; + default: _cf=Qt::lightGray; repaint(); + } +} + + +YACSGui_RunMode::YACSGui_RunMode( YACSGui_Executor* guiExec, + QWidget* parent, + const char* name, + bool modal, + WFlags fl) + : runMode(parent, name, modal, fl) +{ + _guiExec = guiExec; + assert(_guiExec); + onNotifyStatus(YACS::NOTYETINITIALIZED); + resetTreeNode(); + listView_nextSteps->clear(); +} + +void YACSGui_RunMode::resetTreeNode() +{ + //MESSAGE("YACSGui_RunMode::resetTreeNode"); + _proc = _guiExec->getProc(); + assert(_proc); + + listView_breakpoints->clear(); + listView_breakpoints->addColumn( "state", 100); + listView_breakpoints->setRootIsDecorated( TRUE ); + + rb_modeContinue->setChecked(true); + + ComposedNodeViewItem* item = new ComposedNodeViewItem(listView_breakpoints, + "root" ); + _mapListViewItem[_proc->getNumId()] = item; + addTreeNode(item, (ComposedNode*)(_proc)); + listView_breakpoints->setOpen(item, true); + //listView_breakpoints->setResizeMode(QListView::LastColumn); + //resize(sizeHint().width(), height()); +} + +YACSGui_RunMode::~YACSGui_RunMode() +{ + qWarning("YACSGui_RunMode::~YACSGui_RunMode"); +} + +void YACSGui_RunMode::addTreeNode(ComposedNodeViewItem *parent, + YACS::ENGINE::ComposedNode* father) +{ + set setOfNode= father->edGetDirectDescendants(); + for(set::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++) + { + if (ElementaryNode* elemNode = dynamic_cast (*iter) ) + { + NodeViewItem* item = new NodeViewItem(parent, + (*iter)->getQualifiedName(), + NodeViewItem::CheckBox, + elemNode); + _mapListViewItem[(*iter)->getNumId()] = item; + } + else + { + ComposedNodeViewItem* item = new ComposedNodeViewItem(parent, + (*iter)->getQualifiedName()); + _mapListViewItem[(*iter)->getNumId()] = item; + addTreeNode(item, (ComposedNode*)(*iter)); + } + } +} + +void YACSGui_RunMode::onResume() +{ + qWarning("YACSGui_RunMode::onResume"); + if (_guiExec->checkEndOfDataFlow(false)) // --- finished or not started + { + //resetTreeNode(); + _guiExec->runDataflow(true); // --- remote run only + } + else // --- in progress (suspended or running) + _guiExec->resumeDataflow(); +} + +void YACSGui_RunMode::onPause() +{ + qWarning("YACSGui_RunMode::onPause"); + if (! _guiExec->checkEndOfDataFlow(false)) // --- in progress (suspended or running) + _guiExec->suspendDataflow(); +} + +void YACSGui_RunMode::onStop() +{ + qWarning("YACSGui_RunMode::onStop"); + _guiExec->killDataflow(); + //close(); +} + +void YACSGui_RunMode::onModeContinue() +{ + qWarning("YACSGui_RunMode::onModeContinue"); + _guiExec->setContinueMode(); +// QListViewItemIterator it( listView_breakpoints ); +// for ( ; it.current(); ++it ) +// if (NodeViewItem* nodeit = dynamic_cast (*it)) +// nodeit->setEnabled(false); +} + +void YACSGui_RunMode::onModeStepByStep() +{ + qWarning("YACSGui_RunMode::onModeStepByStep"); + _guiExec->setStepByStepMode(); +} + +void YACSGui_RunMode::onModeBreakpoints() +{ + qWarning("YACSGui_RunMode::onModeBreakpoints"); + _guiExec->setBreakpointMode(); +} + +void YACSGui_RunMode::onDismiss() +{ + qWarning("YACSGui_RunMode::onDismiss"); + done(0); +} + +void YACSGui_RunMode::onStopOnError() +{ + qWarning("YACSGui_RunMode::onStopOnError"); + _guiExec->setStopOnError(chk_saveState->isChecked()); +} + +void YACSGui_RunMode::onSaveState() +{ + qWarning("YACSGui_RunMode::onSaveState"); + _saveState = chk_saveState->isChecked(); +} + +void YACSGui_RunMode::onAllNextToRun() +{ + qWarning("YACSGui_RunMode::onAllNextToRun"); + list nextStepList; + QListViewItemIterator it(listView_nextSteps); +// for ( ; it.current(); ++it ) + while(it.current()) + { + ((QCheckListItem*)it.current())->setOn(true); + string nodeName = it.current()->text(0); + MESSAGE(nodeName); + nextStepList.push_back(nodeName); + ++it; + } + _guiExec->setNextStepList(nextStepList); +} + +void YACSGui_RunMode::onRemoveAllNextToRun() +{ + qWarning("YACSGui_RunMode::onRemoveAllNextToRun"); + list nextStepList; + QListViewItemIterator it(listView_nextSteps); + while(it.current()) + { + ((QCheckListItem*)it.current())->setOn(false); + ++it; + } + _guiExec->setNextStepList(nextStepList); +} + +void YACSGui_RunMode::onBreakpointClicked(QListViewItem *item) +{ + qWarning("YACSGui_RunMode::onBreakpointClicked"); + NodeViewItem* elemNodeItem = dynamic_cast(item); + if (elemNodeItem) + { + MESSAGE("click on node " << elemNodeItem->getNode()->getQualifiedName()); + if (elemNodeItem->isOn()) + { + if (rb_modeContinue->isChecked()) + { + onModeBreakpoints(); + rb_modeBreakpoint->setChecked(true); + } + _breakpointSet.insert(elemNodeItem->getNode()->getNumId()); + } + else + _breakpointSet.erase(elemNodeItem->getNode()->getNumId()); + list breakpointList; + for (set::iterator pos = _breakpointSet.begin(); pos != _breakpointSet.end(); ++pos) + { + string nodeName =_proc->getChildName(((NodeViewItem*)(_mapListViewItem[*pos]))->getNode()); + MESSAGE(nodeName); + breakpointList.push_back(nodeName); + } + _guiExec->setBreakpointList(breakpointList); + } +} + +void YACSGui_RunMode::onNextStepClicked(QListViewItem *item) +{ + qWarning("YACSGui_RunMode::onNextStepClicked"); + list nextStepList; + MESSAGE("click on node " << item->text(0)); + QListViewItemIterator it(listView_nextSteps); + for ( ; it.current(); ++it ) + if (((QCheckListItem*)it.current())->isOn()) + { + string nodeName = it.current()->text(0); + MESSAGE(nodeName); + nextStepList.push_back(nodeName); + } + _guiExec->setNextStepList(nextStepList); +} + +void YACSGui_RunMode::onNotifyStatus(int status) +{ + QString theStatus; + QColor wbg; + switch (status) + { + case YACS::NOTYETINITIALIZED: wbg.setHsv( 45, 50, 255); theStatus = "Not Yet Initialized"; break; + case YACS::INITIALISED: wbg.setHsv( 90, 50, 255); theStatus = "Initialized"; break; + case YACS::RUNNING: wbg.setHsv(135, 50, 255); theStatus = "Running"; break; + case YACS::WAITINGTASKS: wbg.setHsv(180, 50, 255); theStatus = "Waiting Tasks"; break; + case YACS::PAUSED: wbg.setHsv(225, 50, 255); theStatus = "Paused"; break; + case YACS::FINISHED: wbg.setHsv(270, 50, 255); theStatus = "Finished"; break; + case YACS::STOPPED: wbg.setHsv(315, 50, 255); theStatus = "Stopped"; break; + default: wbg.setHsv(360, 50, 255); theStatus = "Status Unknown"; + + } + lab_status->setBackgroundColor(wbg); + lab_status->setText(theStatus); +} + +void YACSGui_RunMode::onNotifyNextSteps(std::list nextSteps) +{ + listView_nextSteps->clear(); + _mapNextSteps.clear(); + listView_nextSteps->setRootIsDecorated( TRUE ); + while (! nextSteps.empty()) + { + QCheckListItem *item = new QCheckListItem(listView_nextSteps, + nextSteps.front().c_str(), + QCheckListItem::CheckBox ); + _mapNextSteps[item] = nextSteps.front(); + item->setOn(true); + nextSteps.pop_front(); + } +} + +void YACSGui_RunMode::onNotifyNodeStatus(int nodeId, int status) +{ + //MESSAGE("YACSGui_RunMode::onNotifyNodeStatus " << nodeId << " " << status ); + QListViewItem* it = _mapListViewItem[nodeId]; + if (!it) return; + NodeViewItem* itn = dynamic_cast(it); + if (itn) + { + itn->setState(status); + return; + } + ComposedNodeViewItem* itc = dynamic_cast(it); + if (itc) + { + itc->setState(status); + return; + } + return; +} diff --git a/src/gui/YACSGui_RunMode.h b/src/gui/YACSGui_RunMode.h new file mode 100644 index 000000000..0c255f940 --- /dev/null +++ b/src/gui/YACSGui_RunMode.h @@ -0,0 +1,97 @@ +#ifndef _MYRUNMODE_HXX_ +#define _MYRUNMODE_HXX_ + +#include "runmode.h" +#include "ComposedNode.hxx" +#include "Proc.hxx" +#include "define.hxx" + +#include +#include +#include +#include + +class YACSGui_Executor; +class YACS::ENGINE::ElementaryNode; + +class ComposedNodeViewItem: public QListViewItem +{ + public: + ComposedNodeViewItem(QListView *parent, QString label); + ComposedNodeViewItem(QListViewItem *parent, QString label); + void setState(int state); + virtual void paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ); + + protected: + int _state; + QColor _cf; +}; + +class NodeViewItem: public QCheckListItem +{ + public: + NodeViewItem(QListView *parent, + const QString &text, + Type tt = RadioButtonController, + YACS::ENGINE::ElementaryNode *node = 0); + NodeViewItem(QListViewItem *parent, + const QString &text, + Type tt = RadioButtonController, + YACS::ENGINE::ElementaryNode *node = 0); + void setState(int state); + virtual void paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ); + YACS::ENGINE::ElementaryNode* getNode() { return _node;}; + + protected: + int _state; + QColor _cf; + YACS::ENGINE::ElementaryNode *_node; +}; + +class YACSGui_RunMode : public runMode +{ + Q_OBJECT + +public: + YACSGui_RunMode(YACSGui_Executor* guiExec, + QWidget* parent = 0, + const char* name = 0, + bool modal = FALSE, + WFlags fl = 0 ); + ~YACSGui_RunMode(); + + public slots: + virtual void onResume(); + virtual void onPause(); + virtual void onStop(); + virtual void onModeContinue(); + virtual void onModeStepByStep(); + virtual void onModeBreakpoints(); + virtual void onDismiss(); + virtual void onStopOnError(); + virtual void onSaveState(); + virtual void onAllNextToRun(); + virtual void onRemoveAllNextToRun(); + virtual void onBreakpointClicked(QListViewItem *item); + virtual void onNextStepClicked(QListViewItem *item); + + virtual void onNotifyStatus(int status); + virtual void onNotifyNodeStatus(int nodeId, int status); + virtual void onNotifyNextSteps(std::list nextSteps); + + protected: + void resetTreeNode(); + void addTreeNode(ComposedNodeViewItem *parent, + YACS::ENGINE::ComposedNode* father); + + YACSGui_Executor* _guiExec; + YACS::ENGINE::Proc* _proc; + bool _saveState; + std::map _mapListViewItem; + std::map _mapNextSteps; + std::set _breakpointSet; +}; + +#endif diff --git a/src/gui/YACSGui_Swig.cxx b/src/gui/YACSGui_Swig.cxx new file mode 100644 index 000000000..358cb7a6e --- /dev/null +++ b/src/gui/YACSGui_Swig.cxx @@ -0,0 +1,90 @@ +// Copyright (C) 2003 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 +// + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "SALOME_Event.hxx" + +using namespace YACS::ENGINE; + +YACSGui_Swig::YACSGui_Swig() +{ +} + +YACSGui_Swig::~YACSGui_Swig() +{ +} + +void YACSGui_Swig::displayGraph(YACS::ENGINE::Proc* theProc) +{ + // create presentation for theProc ( note: process this GUI update only in the main GUI thread with help of SALOME_Event ) + ProcessVoidEvent( new TVoidMemFun1ArgEvent( this, + &YACSGui_Swig::createGraphPresentation, + theProc ) ); +} + +//! Creates the view window and presentation of a the calculation graph. +/*! + * Used if graph is imported from old XML file format. + * Called from YACSGui_Swig::displayGraph(YACS::ENGINE::Proc* theProc) method + * with help of SALOME_Event. + * + * \param theProc - engine Proc filled by the content of the XML file. + */ +void YACSGui_Swig::createGraphPresentation( YACS::ENGINE::Proc* theProc ) +{ + // get YACSGui module + CAM_Application* anApp = ( CAM_Application* )(SUIT_Session::session()->activeApplication()); + YACSGui_Module* aModule = dynamic_cast( anApp->module( anApp->moduleTitle( "YACSGui" ) ) ); + if ( !aModule ) return; + + // create view window for presentation of theProc + SUIT_ViewManager* aVM = aModule->getApp()->createViewManager( QxGraph_Viewer::Type() ); + + // set caption for graph's view window + QxGraph_ViewWindow* aVW = dynamic_cast( aVM->getActiveView() ); + if ( aVW ) aVW->setCaption(theProc->getName().c_str()); + + // add theProc to data model as not editable graph + YACSGui_DataModel* aModel = aModule->getDataModel(); + if (aModel) + aModel->add(theProc, false); + + // create presentation for theProc (i.e. YACSGui_Graph, presentations of graph's nodes ...) and display it + if ( aVW ) + { + YACSGui_Loader::PrsDataMap aPrsData; + YACSGui_Loader::PortLinkDataMap aPortLinkData; + YACSGui_Loader::LabelLinkDataMap aLabelLinkData; + aModule->displayGraph( theProc, aPrsData, aPortLinkData, aLabelLinkData ); + } +} diff --git a/src/gui/YACSGui_Swig.h b/src/gui/YACSGui_Swig.h new file mode 100644 index 000000000..7d721c12f --- /dev/null +++ b/src/gui/YACSGui_Swig.h @@ -0,0 +1,36 @@ +// Copyright (C) 2003 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 YACSGui_Swig_HeaderFile +#define YACSGui_Swig_HeaderFile + +#include + +class YACSGui_Swig +{ +public: + YACSGui_Swig(); + ~YACSGui_Swig(); + + void displayGraph(YACS::ENGINE::Proc* theProc); + void createGraphPresentation( YACS::ENGINE::Proc* theProc ); +}; + +#endif diff --git a/src/gui/YACSGui_Swig.i b/src/gui/YACSGui_Swig.i new file mode 100644 index 000000000..825106cb2 --- /dev/null +++ b/src/gui/YACSGui_Swig.i @@ -0,0 +1,43 @@ +// Copyright (C) 2003 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 +// + +%define DOCSTRING +"YACSGui_Swig docstring +All is needed to create and display a calculation schema from proc +pointer in Python console." +%enddef + +%module(docstring=DOCSTRING) YACSGui_Swig + +%{ +#include "YACSGui_Swig.h" +#include "Proc.hxx" + +using namespace YACS::ENGINE; +%} + +class YACSGui_Swig +{ + public: + YACSGui_Swig(); + ~YACSGui_Swig(); + + void displayGraph(YACS::ENGINE::Proc* theProc); +}; diff --git a/src/gui/YACSGui_XMLDriver.cxx b/src/gui/YACSGui_XMLDriver.cxx new file mode 100644 index 000000000..c225dfbe7 --- /dev/null +++ b/src/gui/YACSGui_XMLDriver.cxx @@ -0,0 +1,263 @@ +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +using namespace YACS::ENGINE; +using namespace std; + +static canvastype_parser canvas_parser; +static presentationtype_parser presentation_parser; +static pointtype_parser point_parser; +static prslinktype_parser prslink_parser; + +void prslinktype_parser::onStart(const XML_Char* el, const XML_Char** attr) +{ + std::cerr << "prslinktype_parser::onStart: " << el << std::endl; + std::string element(el); + parser* pp=&main_parser; + if(element == "point") pp = &point_parser; + SetUserDataAndPush(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); +} + +YACSGui_VisitorSaveSchema::YACSGui_VisitorSaveSchema(YACSGui_Module* module, + ComposedNode *root) + : VisitorSaveSchema(root), myModule(module) +{ +} + +YACSGui_VisitorSaveSchema::~YACSGui_VisitorSaveSchema() +{ +} + +void YACSGui_VisitorSaveSchema::visitProc(Proc *node) +{ + this->VisitorSaveSchema::visitProc(node); + writePresentation(node); + writeLinks(node); +} + +void YACSGui_VisitorSaveSchema::writePresentation(Proc *proc) +{ + YACSGui_Graph* aGraph = myModule->getGraph(proc); + if ( !aGraph || !aGraph->getCanvas() ) + return; + + int depth = 1; + + _out << indent(depth) << "getCanvas()->width() << "\""; + _out << " height=\"" << aGraph->getCanvas()->height() << "\""; + _out << "/>" << endl; + + set nodeSet = getAllNodes(proc); + + for (set::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter) + { + Node* aNode = *iter; + YACSPrs_ElementaryNode* aPrs = aGraph->getItem( aNode ); + if ( !aPrs ) + continue; + + _out << indent(depth) << "getChildName( aNode ) << "\""; + _out << " x=\"" << aPrs->x() << "\""; + _out << " y=\"" << aPrs->y() << "\""; + _out << " z=\"" << aPrs->z() << "\""; + _out << " width=\"" << aPrs->width() << "\""; + _out << " height=\""<< aPrs->height() << "\""; + _out << "/>" << endl; + } +} + +void YACSGui_VisitorSaveSchema::writeLinks(YACS::ENGINE::Proc *proc) +{ + YACSGui_Graph* aGraph = myModule->getGraph(proc); + if ( !aGraph || !aGraph->getCanvas() ) + return; + + int depth = 1; + + set nodeSet = getAllNodes(proc); + + for (set::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter) + { + Node* aNode = *iter; + YACSPrs_ElementaryNode* aPrs = aGraph->getItem( aNode ); + if ( !aPrs ) + continue; + + QPtrList aPorts = aPrs->getPortList(); + for (YACSPrs_Port* aPort = aPorts.first(); aPort; aPort = aPorts.next()) + { + YACSPrs_InOutPort* anIOPort; + if ( ( anIOPort = dynamic_cast( aPort ) ) && !anIOPort->isInput() + || + dynamic_cast( aPort ) ) + { // this port is an output port => iterates on its links + list aLinks = aPort->getLinks(); + for(list::iterator itL = aLinks.begin(); itL != aLinks.end(); itL++) + { + _out << indent(depth) << "( *itL ) ) { + _out << " fromnode=\"" << proc->getChildName( aNode ) << "\""; + _out << " fromport=\"" << aPort->getName() << "\""; + _out << " tonode=\"" << proc->getChildName( aPL->getInputPort()->getEngine()->getNode() ) << "\""; + _out << " toport=\"" << aPL->getInputPort()->getName() << "\""; + } + else if ( YACSPrs_LabelLink* aLL = dynamic_cast( *itL ) ) { + _out << " tonode=\"" << proc->getChildName( aLL->getSlaveNode()->getEngine() ) << "\""; + } + + _out << ">" << endl; + + list aPoints = (*itL)->getPoints(); + for(list::iterator itP = aPoints.begin(); itP != aPoints.end(); itP++) { + _out << indent(depth+1) << "" << endl; + } + + _out << indent(depth) << "" << endl; + } + } + } + } +} + +YACSGui_Loader::YACSGui_Loader() + : YACSLoader() +{ + _defaultParsersMap.clear(); + + presentation_parser.collector_ = this; + prslink_parser.collector_ = this; + + _defaultParsersMap.insert(make_pair("canvas",&canvas_parser)); + _defaultParsersMap.insert(make_pair("presentation",&presentation_parser)); + _defaultParsersMap.insert(make_pair("point",&point_parser)); + _defaultParsersMap.insert(make_pair("prslink",&prslink_parser)); +} + +YACSGui_Loader::~YACSGui_Loader() +{ +} + +const YACSGui_Loader::PrsDataMap& YACSGui_Loader::getPrsData(Proc* proc, int& width, int& height) +{ + myPrsMap.clear(); + + if ( _defaultParsersMap.empty() + || + !_defaultParsersMap["canvas"] ) return myPrsMap; + + // get information from canvastype_parser + width = ((canvastype_parser*)_defaultParsersMap["canvas"])->width_; + height = ((canvastype_parser*)_defaultParsersMap["canvas"])->height_; + + for ( InputMap::iterator it = myInputMap.begin(); it != myInputMap.end(); it++ ) + { + Node* aNode = proc->getChildByName( (*it).first ); + myPrsMap[aNode] = (*it).second; + } + + return myPrsMap; +} + +const YACSGui_Loader::PortLinkDataMap& YACSGui_Loader::getPortLinkData(YACS::ENGINE::Proc* proc) +{ + myPortLinkMap.clear(); + + for ( InputPLList::iterator it = myInputPLList.begin(); it != myInputPLList.end(); it++ ) + { + Node* aFromNode = proc->getChildByName((*it).fromnode); + Port* aFromPort = 0; + if ( (*it).fromport == "Gate" ) + aFromPort = aFromNode->getOutGate(); + else + aFromPort = (Port*)(aFromNode->getOutPort((*it).fromport)); + + Node* aToNode = proc->getChildByName((*it).tonode); + Port* aToPort; + if ( (*it).toport == "Gate" ) + aToPort = aToNode->getInGate(); + else + aToPort = (Port*)(aToNode->getInPort((*it).toport)); + + std::pair aPPair(aFromPort,aToPort); + myPortLinkMap[aPPair] = (*it).points; + } + + return myPortLinkMap; +} + +const YACSGui_Loader::LabelLinkDataMap& YACSGui_Loader::getLabelLinkData(YACS::ENGINE::Proc* proc) +{ + myLabelLinkMap.clear(); + + for ( InputLLList::iterator it = myInputLLList.begin(); it != myInputLLList.end(); it++ ) + { + Node* aSlaveNode = proc->getChildByName((*it).slavenode); + myLabelLinkMap[aSlaveNode] = (*it).points; + } + + return myLabelLinkMap; +} + +void YACSGui_Loader::process(std::string theElement, bool theNewLink) +{ + if(theElement == "presentation") + { + if ( _defaultParsersMap["presentation"] ) + { + presentationtype_parser* aP = (presentationtype_parser*)_defaultParsersMap["presentation"]; + myInputMap[aP->name_] = PrsData(aP->x_,aP->y_,aP->z_,aP->width_,aP->height_); + } + } + else if(theElement == "prslink") + { + if ( _defaultParsersMap["prslink"] ) + { + prslinktype_parser* aP = (prslinktype_parser*)_defaultParsersMap["prslink"]; + if ( aP->type() == "portlink" ) + { + if ( theNewLink ) { + PortLinkData aPLData(aP->fromnode_,aP->fromport_,aP->tonode_,aP->toport_); + //aPLData.fillPoints(aP->points_); + myInputPLList.push_back(aPLData); + } + else if ( !myInputPLList.empty() ) + myInputPLList.back().appendPoint(aP->points_.back()); + } + else if ( aP->type() == "labellink" ) + { + if ( theNewLink ) { + LabelLinkData aLLData(aP->tonode_); + //aLLData.fillPoints(aP->points_); + myInputLLList.push_back(aLLData); + } + else if ( !myInputLLList.empty() ) + myInputLLList.back().appendPoint(aP->points_.back()); + } + } + } +} diff --git a/src/gui/YACSGui_XMLDriver.h b/src/gui/YACSGui_XMLDriver.h new file mode 100644 index 000000000..270ef4759 --- /dev/null +++ b/src/gui/YACSGui_XMLDriver.h @@ -0,0 +1,401 @@ +#ifndef __YACSGUI_XML_DRIVER_H__ +#define __YACSGUI_XML_DRIVER_H__ + +#include +#include +#include +#include + +#include + +class YACSGui_Module; + +/*! + * Class that extends engine XML wirter capabilities by + * adding information about node presentations to the output file. + */ +class YACSGui_VisitorSaveSchema : public YACS::ENGINE::VisitorSaveSchema +{ +public: + YACSGui_VisitorSaveSchema(YACSGui_Module* module, YACS::ENGINE::ComposedNode *root); + virtual ~YACSGui_VisitorSaveSchema(); + + virtual void visitProc(YACS::ENGINE::Proc *node); + +private: + void writePresentation(YACS::ENGINE::Proc *proc); + void writeLinks(YACS::ENGINE::Proc *proc); + +private: + YACSGui_Module* myModule; +}; + +/*! + * Class that extends engine XML loader. It can process the presentation data + * not hanled by the base class. + */ +class YACSGui_Loader : public YACS::YACSLoader +{ +public: + struct PrsData + { + float x, y, z; + float width, height; + + PrsData() { x = y = z = 0.; width = height = 1.; } + PrsData(float theX, float theY, float theZ, + float theWidth, float theHeight) + { + x = theX; + y = theY; + z = theZ; + width = theWidth; + height = theHeight; + } + }; + + typedef std::map PrsDataMap; + + struct LinkData + { + std::list points; + + LinkData() { points = std::list(0); } + void appendPoint(QPoint thePoint) + { + points.push_back( thePoint ); + } + void fillPoints(std::list theList) + { + points.clear(); + for (std::list::iterator it = theList.begin(); it != theList.end(); ++it) + points.push_back( *it ); + } + }; + + struct PortLinkData : LinkData + { + std::string fromnode, fromport, tonode, toport; + + PortLinkData():LinkData() { fromnode = fromport = tonode = toport = ""; } + PortLinkData(std::string theFromnode, std::string theFromport, + std::string theTonode, std::string theToport):LinkData() + { + fromnode = theFromnode; + fromport = theFromport; + tonode = theTonode; + toport = theToport; + } + }; + + struct LabelLinkData : LinkData + { + std::string slavenode; + + LabelLinkData():LinkData() { slavenode = ""; } + LabelLinkData(std::string theSlavenode):LinkData() + { + slavenode = theSlavenode; + } + }; + + + typedef std::map< std::pair, std::list > PortLinkDataMap; + typedef std::map< YACS::ENGINE::Node*, std::list > LabelLinkDataMap; + +public: + YACSGui_Loader(); + virtual ~YACSGui_Loader(); + + const PrsDataMap& getPrsData(YACS::ENGINE::Proc* proc, int&, int&); + const PortLinkDataMap& getPortLinkData(YACS::ENGINE::Proc* proc); + const LabelLinkDataMap& getLabelLinkData(YACS::ENGINE::Proc* proc); + + void process(std::string theElement, bool theNewLink = false); + +private: + typedef std::map InputMap; + + typedef std::list InputPLList; + typedef std::list InputLLList; + + InputMap myInputMap; + PrsDataMap myPrsMap; + + InputPLList myInputPLList; + PortLinkDataMap myPortLinkMap; + + InputLLList myInputLLList; + LabelLinkDataMap myLabelLinkMap; +}; + +/*! + * Struct for parse element from XML file. + */ +struct canvastype_parser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::cerr << "canvastype_parser::onStart: " << el << std::endl; + std::string element(el); + parser* pp=&main_parser; + SetUserDataAndPush(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + + virtual void buildAttr(const XML_Char** attr) + { + required("width",attr); + required("height",attr); + for (int i = 0; attr[i]; i += 2) + { + std::cerr << attr[i] << "=" << attr[i + 1] << std::endl; + if(std::string(attr[i]) == "width") width(attr[i+1]); + if(std::string(attr[i]) == "height") height(attr[i+1]); + } + } + + virtual void pre () + { + width_ = height_ = 1; + } + + virtual void width(const std::string& width) + { + width_ = QString( width ).toInt(); + } + + virtual void height(const std::string& height) + { + height_ = QString( height ).toInt(); + } + + int width_, height_; +}; + +/*! + * Struct for parse element from XML file. + */ +struct presentationtype_parser: parser +{ + presentationtype_parser():parser() + { + collector_ = 0; + } + + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::cerr << "presentationtype_parser::onStart: " << el << std::endl; + std::string element(el); + parser* pp=&main_parser; + SetUserDataAndPush(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + + virtual void buildAttr(const XML_Char** attr) + { + required("name",attr); + required("x",attr); + required("y",attr); + required("z",attr); + required("width",attr); + required("height",attr); + for (int i = 0; attr[i]; i += 2) + { + std::cerr << attr[i] << "=" << attr[i + 1] << std::endl; + if(std::string(attr[i]) == "name") name(attr[i+1]); + if(std::string(attr[i]) == "x") x(attr[i+1]); + if(std::string(attr[i]) == "y") y(attr[i+1]); + if(std::string(attr[i]) == "z") z(attr[i+1]); + if(std::string(attr[i]) == "width") width(attr[i+1]); + if(std::string(attr[i]) == "height") height(attr[i+1]); + } + + if ( collector_ ) + collector_->process("presentation"); + } + + virtual void pre () + { + name_ = ""; + x_ = y_ = z_ = 0.; + width_ = height_ = 1; + } + + virtual void name(const std::string& name) + { + name_ = name; + } + + virtual void x(const std::string& x) + { + x_ = QString( x ).toFloat(); + } + + virtual void y(const std::string& y) + { + y_ = QString( y ).toFloat(); + } + + virtual void z(const std::string& z) + { + z_ = QString( z ).toFloat(); + } + + virtual void width(const std::string& width) + { + width_ = QString( width ).toFloat(); + } + + virtual void height(const std::string& height) + { + height_ = QString( height ).toFloat(); + } + + std::string name_; + float x_, y_, z_; + float width_, height_; + + YACSGui_Loader* collector_; +}; + +/*! + * Struct for parse element from XML file. + */ +struct pointtype_parser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::cerr << "pointtype_parser::onStart: " << el << std::endl; + std::string element(el); + parser* pp=&main_parser; + SetUserDataAndPush(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + + virtual void buildAttr(const XML_Char** attr) + { + required("x",attr); + required("y",attr); + for (int i = 0; attr[i]; i += 2) + { + std::cerr << attr[i] << "=" << attr[i + 1] << std::endl; + if(std::string(attr[i]) == "x") x(attr[i+1]); + if(std::string(attr[i]) == "y") y(attr[i+1]); + } + } + + virtual QPoint post() + { + QPoint aP(x_,y_); + return aP; + } + + virtual void pre () + { + x_ = y_ = 0; + } + + virtual void x(const std::string& x) + { + x_ = QString( x ).toInt(); + } + + virtual void y(const std::string& y) + { + y_ = QString( y ).toInt(); + } + + int x_, y_; +}; + +/*! + * Struct for parse element from XML file. + */ +struct prslinktype_parser: parser +{ + prslinktype_parser():parser() + { + collector_ = 0; + } + + virtual void onStart(const XML_Char* el, const XML_Char** attr); + + virtual void onEnd(const char *el,parser* child) + { + std::cerr << "prslinktype_parser::onEnd: " << el << std::endl; + std::string element(el); + if(element == "point") point(((pointtype_parser*)child)->post()); + } + + virtual void buildAttr(const XML_Char** attr) + { + required("tonode",attr); + for (int i = 0; attr[i]; i += 2) + { + std::cerr << attr[i] << "=" << attr[i + 1] << std::endl; + if(std::string(attr[i]) == "fromnode") fromnode(attr[i+1]); + if(std::string(attr[i]) == "fromport") fromport(attr[i+1]); + if(std::string(attr[i]) == "tonode") tonode(attr[i+1]); + if(std::string(attr[i]) == "toport") toport(attr[i+1]); + } + + if ( collector_ ) + collector_->process("prslink", true); + } + + virtual void point(const QPoint& thePoint) + { + points_.push_back(thePoint); + if ( collector_ ) + collector_->process("prslink"); + } + + virtual void pre () + { + fromnode_ = fromport_ = tonode_ = toport_ = ""; + } + + virtual void fromnode(const std::string& fromnode) + { + fromnode_ = fromnode; + } + + virtual void fromport(const std::string& fromport) + { + fromport_ = fromport; + } + + virtual void tonode(const std::string& tonode) + { + tonode_ = tonode; + } + + virtual void toport(const std::string& toport) + { + toport_ = toport; + } + + std::string type() + { + std::string aType = ""; + if ( fromnode_ != "" && fromport_ != "" && tonode_ != "" && toport_ != "" ) + aType = "portlink"; + else if ( fromnode_ == "" && fromport_ == "" && tonode_ != "" && toport_ == "" ) + aType = "labellink"; + return aType; + } + + std::string fromnode_, fromport_, tonode_, toport_; + std::list points_; + + YACSGui_Loader* collector_; +}; + +#endif diff --git a/src/gui/legendre7.xml b/src/gui/legendre7.xml new file mode 100644 index 000000000..e93d8c319 --- /dev/null +++ b/src/gui/legendre7.xml @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + iter1 iter2 + + iter1 Pn + iter2 Pnm1 + + + iter1 n + iter2 n + + + iter2 Pn + iter1 Pnm1 + + + iter2 n + iter1 n + + + + deuxIter.iter2 Pn + deuxIter.iter2 Pnm2 + + + deuxIter.iter1 Pn + deuxIter.iter1 Pnm2 + + + + + + + + + + + + + + iter_1 loopIter + iter_0 loopIter + iter_0 iter_1 + + iter_1 Pn + loopIter.deuxIter.iter1 Pnm1 + + + iter_1 Pn + loopIter.deuxIter.iter2 Pnm2 + + + iter_1 n + loopIter.deuxIter.iter1 n + + + iter_0 Pn + loopIter.deuxIter.iter1 Pnm2 + + + init poly_7 + init Legendre + Legendre poly_7 + + init x + Legendre.loopIter.deuxIter.iter1 x + + + init x + Legendre.iter_1 x + + + init x + Legendre.loopIter.deuxIter.iter2 x + + + init x + poly_7 x + + + init nsteps + Legendre.loopIter nsteps + + + poly_7x + 0.5 + + + Legendre.loopIternsteps + 3 + + + Legendre.iter_1x + 0.5 + + + Legendre.loopIter.deuxIter.iter1Pnm1 + 0.223145 + + + Legendre.loopIter.deuxIter.iter1Pnm2 + 0.323242 + + + Legendre.loopIter.deuxIter.iter1x + 0.5 + + + Legendre.loopIter.deuxIter.iter1n + 8 + + + Legendre.loopIter.deuxIter.iter2Pnm1 + 0.323242 + + + Legendre.loopIter.deuxIter.iter2Pnm2 + 0.223145 + + + Legendre.loopIter.deuxIter.iter2x + 0.5 + + + Legendre.loopIter.deuxIter.iter2n + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/gui/resources/ModuleYacs.png b/src/gui/resources/ModuleYacs.png new file mode 100644 index 0000000000000000000000000000000000000000..951cb352f120812c091b651ec998adc462ba151e GIT binary patch literal 1288 zcmbVLJxsz-5H5rPnlRBAH7RQw)44H`MT1d@Ax1hmxiK?0(a5HQ%*^aA8eADVm@Y0I z=-dtIT1*`9BM0zc&Bnvv_AeAFmZ9 z_fe}JJG*-sFL(5vnayU%{O`#Lnr++5eBbv0Zb&W2DC+fkoZo7-i1u~+&Qtl$p;#{3 zraE5K@Ap+zZ8n=66tPH2&ruY4p4aVm9mk>SQmJH`CYGbo2(9syuIrnWEz8n0Z8#j# zUKAjOO{M2$V?hvzYG1dAhQN*jFrh5TGzO}3T^Gvjb{o|Mioh@oq*i#Y*Xv1=U{rXx z=QxgmQ%WlHX%7YivAyst;xG&+lSxWnw!P9ADT9VSIaw+LU1tolLI34)84YtXz&|`= z`%0yPH>Xj&XnUP!)TIQ8i9mWDU)=M=&g-2xOti;w9!oN+c>=LG%njtUXWa1lQU0Fu zR-T~)0+{#!Qu@GC2rXsXXm5F{K(=aoI-TMUrF6i=-6#|aq{ag?eDR+S#&2`1cG{>u IpWJkQ0Qhjkm;e9( literal 0 HcmV?d00001 diff --git a/src/gui/resources/SalomeApp.xml b/src/gui/resources/SalomeApp.xml new file mode 100644 index 000000000..0ad6c8958 --- /dev/null +++ b/src/gui/resources/SalomeApp.xml @@ -0,0 +1,12 @@ + +
+ + + +
+
+ + + +
+
diff --git a/src/gui/resources/YACSGuiCatalog.xml.in b/src/gui/resources/YACSGuiCatalog.xml.in new file mode 100644 index 000000000..edd2eea9e --- /dev/null +++ b/src/gui/resources/YACSGuiCatalog.xml.in @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + YACSGui + YACSGui TUI + Data + P. RASCLE + @VERSION@ + EDF - RD + 1 + ModuleYacs.png + 'linux' ~ OS + + + + diff --git a/src/gui/resources/YACSGui_images.po b/src/gui/resources/YACSGui_images.po new file mode 100755 index 000000000..eba036cfc --- /dev/null +++ b/src/gui/resources/YACSGui_images.po @@ -0,0 +1,83 @@ +#### YACS module root icon #### +msgid "YACS_MODULE_ICON" +msgstr "ModuleYacs.png" + +#### Icons for YACS module menus and toolbars #### + +msgid "ICON_ADD_DATAFLOW_IN_STUDY" +msgstr "add_in_study.png" + +msgid "ICON_ADD_NODE" +msgstr "add_node.png" + +msgid "ICON_CHANGE_INFORMATIONS" +msgstr "change_informations.png" + +msgid "ICON_CONTROL_VIEW" +msgstr "control_view.png" + +msgid "ICON_EXPORT_DATAFLOW" +msgstr "export_dataflow.png" + +msgid "ICON_FILTERNEXTSTEPS" +msgstr "filter_next_steps.png" + +msgid "ICON_FILTER_NOTIFICATION" +msgstr "filter_notification.png" + +msgid "ICON_FULL_VIEW" +msgstr "full_view.png" + +msgid "ICON_IMPORT_DATAFLOW" +msgstr "import_dataflow.png" + +msgid "ICON_IMPORT_SUPERV_DATAFLOW" +msgstr "import_superv_dataflow.png" + +msgid "ICON_INSERT_FILE" +msgstr "insert_file.png" + +msgid "ICON_KILL_DATAFLOW" +msgstr "kill.png" + +msgid "ICON_BREAKPOINT_DATAFLOW" +msgstr "mode_breakpoint.png" + +msgid "ICON_CONTINUE_DATAFLOW" +msgstr "mode_continue.png" + +msgid "ICON_MODIFY_DATAFLOW" +msgstr "modify_dataflow.png" + +msgid "ICON_MODIFY_SUPERV_DATAFLOW" +msgstr "modify_superv_dataflow.png" + +msgid "ICON_NEW_DATAFLOW" +msgstr "new_dataflow.png" + +msgid "ICON_REBUILD_LINKS" +msgstr "rebuild_links.png" + +msgid "ICON_RELOAD_DATAFLOW" +msgstr "reload.png" + +msgid "ICON_REMOTE_RUN_DATAFLOW" +msgstr "remote_run.png" + +msgid "ICON_RUN_DATAFLOW" +msgstr "run.png" + +msgid "ICON_SAVEDATAFLOWSTATE" +msgstr "save_dataflow_state.png" + +msgid "ICON_STEPBYSTEP_DATAFLOW" +msgstr "step_by_step.png" + +msgid "ICON_SUSPEND_RESUME_DATAFLOW" +msgstr "suspend_resume.png" + +msgid "ICON_TABLE_VIEW" +msgstr "table_view.png" + +msgid "ICON_TOGGLESTOPONERROR" +msgstr "toggle_stop_on_error.png" diff --git a/src/gui/resources/YACSGui_msg_en.po b/src/gui/resources/YACSGui_msg_en.po new file mode 100755 index 000000000..7ebbfe674 --- /dev/null +++ b/src/gui/resources/YACSGui_msg_en.po @@ -0,0 +1,325 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2007-03-12 16:44+0300\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + + +#### YACSGui module menus and toolbars #### + +msgid "MEN_FILE" +msgstr "File" + +msgid "TOOLBAR_DATAFLOW" +msgstr "Dataflow" + +msgid "TOOLBAR_EXECUTION" +msgstr "Execution" + +msgid "TOOLBAR_EXECUTIONMODE" +msgstr "Execution Mode" + +msgid "MEN_NEW_DATAFLOW" +msgstr "New dataflow" + +msgid "TOP_NEW_DATAFLOW" +msgstr "New dataflow" + +msgid "STB_NEW_DATAFLOW" +msgstr "Create new dataflow" + +msgid "MEN_MODIFY_DATAFLOW" +msgstr "Modify dataflow" + +msgid "TOP_MODIFY_DATAFLOW" +msgstr "Modify dataflow" + +msgid "STB_MODIFY_DATAFLOW" +msgstr "Modify dataflow" + +msgid "MEN_IMPORT_DATAFLOW" +msgstr "Import dataflow" + +msgid "TOP_IMPORT_DATAFLOW" +msgstr "Import dataflow" + +msgid "STB_IMPORT_DATAFLOW" +msgstr "Import dataflow" + +msgid "MEN_MODIFY_SUPERV_DATAFLOW" +msgstr "Modify SUPERV dataflow" + +msgid "TOP_MODIFY_SUPERV_DATAFLOW" +msgstr "Modify SUPERV dataflow" + +msgid "STB_MODIFY_SUPERV_DATAFLOW" +msgstr "Modify SUPERV dataflow" + +msgid "MEN_IMPORT_SUPERV_DATAFLOW" +msgstr "Import SUPERV dataflow" + +msgid "TOP_IMPORT_SUPERV_DATAFLOW" +msgstr "Import SUPERV dataflow" + +msgid "STB_IMPORT_SUPERV_DATAFLOW" +msgstr "Import SUPERV dataflow" + +msgid "MEN_EXPORT_DATAFLOW" +msgstr "Export dataflow" + +msgid "TOP_EXPORT_DATAFLOW" +msgstr "Export dataflow" + +msgid "STB_EXPORT_DATAFLOW" +msgstr "Export dataflow" + +msgid "MEN_SUPERVISOR" +msgstr "Supervisor" + +msgid "MEN_RELOAD_DATAFLOW" +msgstr "Reload" + +msgid "TOP_RELOAD_DATAFLOW" +msgstr "Reload" + +msgid "STB_RELOAD_DATAFLOW" +msgstr "Reload dataflow" + +msgid "MEN_REBUILD_LINKS" +msgstr "Rebuild links" + +msgid "TOP_REBUILD_LINKS" +msgstr "Rebuild links" + +msgid "STB_REBUILD_LINKS" +msgstr "Rebuild dataflow links" + +msgid "MEN_ADD_NODE" +msgstr "Add Node to Dataflow" + +msgid "TOP_ADD_NODE" +msgstr "Add Node to Dataflow" + +msgid "STB_ADD_NODE" +msgstr "Add Node to Dataflow" + +msgid "MEN_INSERT_FILE" +msgstr "Insert File" + +msgid "TOP_INSERT_FILE" +msgstr "Insert File" + +msgid "STB_INSERT_FILE" +msgstr "Insert File" + +msgid "MEN_RUN_DATAFLOW" +msgstr "Local Run" + +msgid "TOP_RUN_DATAFLOW" +msgstr "Local Run" + +msgid "STB_RUN_DATAFLOW" +msgstr "Local Run of Dataflow without control" + +msgid "MEN_REMOTE_RUN_DATAFLOW" +msgstr "Remote Run - Direct" + +msgid "TOP_REMOTE_RUN_DATAFLOW" +msgstr "Remote Run - Direct" + +msgid "STB_REMOTE_RUN_DATAFLOW" +msgstr "Remote Run of Dataflow without control" + +msgid "MEN_KILL_DATAFLOW" +msgstr "Stop Dataflow" + +msgid "TOP_KILL_DATAFLOW" +msgstr "Stop Dataflow" + +msgid "STB_KILL_DATAFLOW" +msgstr "Stop Dataflow as soon as possible..." + +msgid "MEN_STEPBYSTEP_DATAFLOW" +msgstr "Step by Step Mode" + +msgid "TOP_STEPBYSTEP_DATAFLOW" +msgstr "Step by Step Exec Mode" + +msgid "STB_STEPBYSTEP_DATAFLOW" +msgstr "Step by Step Execution Mode" + +msgid "MEN_CONTINUE_DATAFLOW" +msgstr "continue Mode" + +msgid "TOP_CONTINUE_DATAFLOW" +msgstr "continue Mode" + +msgid "STB_CONTINUE_DATAFLOW" +msgstr "continue Mode" + +msgid "MEN_BREAKPOINT_DATAFLOW" +msgstr "breakpoint Mode" + +msgid "TOP_BREAKPOINT_DATAFLOW" +msgstr "breakpoint Mode" + +msgid "STB_BREAKPOINT_DATAFLOW" +msgstr "breakpoint Mode" + +msgid "MEN_FILTERNEXTSTEPS" +msgstr "Filter Next Steps" + +msgid "TOP_FILTERNEXTSTEPS" +msgstr "Filter Next Steps" + +msgid "STB_FILTERNEXTSTEPS" +msgstr "Filter Next Steps" + +msgid "MEN_SAVEDATAFLOWSTATE" +msgstr "Save Dataflow state" + +msgid "TOP_SAVEDATAFLOWSTATE" +msgstr "Save Dataflow state" + +msgid "STB_SAVEDATAFLOWSTATE" +msgstr "Save Dataflow state" + +msgid "MEN_TOGGLESTOPONERROR" +msgstr "Toggle stop on error" + +msgid "TOP_TOGGLESTOPONERROR" +msgstr "Toggle stop on error" + +msgid "STB_TOGGLESTOPONERROR" +msgstr "Toggle stop on error" + +msgid "MEN_SUSPEND_RESUME_DATAFLOW" +msgstr "Remote Run - Control" + +msgid "TOP_SUSPEND_RESUME_DATAFLOW" +msgstr "Remote Run - Control" + +msgid "STB_SUSPEND_RESUME_DATAFLOW" +msgstr "Remote Run of Dataflow with execution control" + +msgid "MEN_FILTER_NOTIFICATION" +msgstr "Filter Notification ..." + +msgid "TOP_FILTER_NOTIFICATION" +msgstr "Filter Notification ..." + +msgid "STB_FILTER_NOTIFICATION" +msgstr "Filter Notification ..." + +msgid "MEN_ADD_DATAFLOW_IN_STUDY" +msgstr "Add In Study" + +msgid "TOP_ADD_DATAFLOW_IN_STUDY" +msgstr "Add Dataflow In Study" + +msgid "STB_ADD_DATAFLOW_IN_STUDY" +msgstr "Add Dataflow In Study" + +msgid "MEN_CHANGE_INFORMATIONS" +msgstr "Change Informations ..." + +msgid "TOP_CHANGE_INFORMATIONS" +msgstr "Change Informations ..." + +msgid "STB_CHANGE_INFORMATIONS" +msgstr "Change Informations ..." + +msgid "MEN_FULL_VIEW" +msgstr "Full View" + +msgid "TOP_FULL_VIEW" +msgstr "Full View" + +msgid "STB_FULL_VIEW" +msgstr "Full View" + +msgid "MEN_CONTROL_VIEW" +msgstr "Control View" + +msgid "TOP_CONTROL_VIEW" +msgstr "Control View" + +msgid "STB_CONTROL_VIEW" +msgstr "Control View" + +msgid "MEN_TABLE_VIEW" +msgstr "Table View" + +msgid "TOP_TABLE_VIEW" +msgstr "Table View" + +msgid "STB_TABLE_VIEW" +msgstr "Table View" + + +#### YACSGui module dialog titles #### + +msgid "TLT_MODIFY_DATAFLOW" +msgstr "Modify Dataflow" + +msgid "TLT_IMPORT_DATAFLOW" +msgstr "Import Dataflow" + +msgid "TLT_MODIFY_SUPERV_DATAFLOW" +msgstr "Modify SUPERV Dataflow" + +msgid "TLT_IMPORT_SUPERV_DATAFLOW" +msgstr "Import SUPERV Dataflow" + +msgid "TLT_EXPORT_DATAFLOW" +msgstr "Export Dataflow" + +#### YACSGui module message boxes #### + +msgid "ERROR" +msgstr "Error" + +msgid "WARNING" +msgstr "Warning" + +msgid "BUT_OK" +msgstr "Ok" + +msgid "MSG_NO_DATAFLOW_SELECTED" +msgstr "No dataflow has been selected." + +msgid "MSG_IMPORT_FILE_ERROR" +msgstr "The file is incorrect." + +msgid "MSG_DATAFLOW_NOT_EDITABLE" +msgstr "Current dataflow is not editable." + +msgid "MSG_NO_DATAFLOW_LOADED" +msgstr "No dataflow for execution is selected." + +msgid "MSG_NO_DATAFLOW_TO_RUN" +msgstr "No dataflow for execution is selected." + +msgid "MSG_NO_DATAFLOW_TO_KILL" +msgstr "No dataflow to kill is selected." + +msgid "MSG_NO_DATAFLOW_TO_SUSPEND_RESUME" +msgstr "No dataflow to suspend/resume is selected." + +msgid "MSG_NO_DATAFLOW_TO_SUSPEND_RESUME" +msgstr "No dataflow to suspend/resume is selected." + +msgid "MSG_DATAFLOW_IS_NOT_RUNNING" +msgstr "The dataflow is not running." + + + diff --git a/src/gui/resources/add_in_study.png b/src/gui/resources/add_in_study.png new file mode 100644 index 0000000000000000000000000000000000000000..268889f57704da6a7cd61e1709a77b5c968cfabf GIT binary patch literal 667 zcmV;M0%ZM(P)d>0xFd@qGSL70w_sD zK~xyit(3n@96=PvKf4^r4Hf~fu~?7T90=RVHVXEZ(JGCVkm6doA`l^vBBWhnlm9`m z5CjVw5w`R|*h=IOQ!IMq_IB4}-b@OAAA{$VjWHksB519NEelw2zMXV+?(35o;OD&y(jlX_}Jfxt&P4*X!{iiZI3? zB81b^{1)MRy^e@rt;N-vo0}W1uC7RugtfJ`a>~2AyG|U(c5iQwgM$N-qM$3nU@*Y< z{eR}iF=?8TW!dX@SwzT0xE%s992XZCtgo+AtyU-RvQmnd=5f8naiRb_T0h&of zK~xyit(2i}+dve?f1V6-^rQ~tXuybbFdA4DnMEq7oKjQM{VkR>X14a=E16?;i=<^E1D8&1L;% zaF)1!IF4fgs;W9g-fT9EMx%?3=j8i7X_``175n|(y2co%D2lUP{~`nk!;sx>M_HD* zT5Fpm$saMh5CY8SbD}7ss;Xn;AP4~Xe0Rs|!xI3HZ!Z_?$F~;%(liA?DTS00XE+?% z^?J>CJm$yyd#4S5yT5N{IGfFoQu4_dqOg<6_hr_{^W!ags{U81YFJRk{vwgi1 P00000NkvXXu0mjfvGC>| literal 0 HcmV?d00001 diff --git a/src/gui/resources/change_informations.png b/src/gui/resources/change_informations.png new file mode 100644 index 0000000000000000000000000000000000000000..ada93ffc3e8b2bf5fa0aec67d4c3c682defc2889 GIT binary patch literal 978 zcmV;@11d>2r!bnvy=b;17Ar* zK~xyit&~qln`a!yKhK-I?`!l;-k3$>->J<(8R)>nRyM(I7YFNxbYqom#oe3Rx~#0^z<}dub1KBVMazqL@k{-jl;>wNx89cn~NVrug4e5yn56;pKrcxm+Xbzcq07 z>}#acX@n4{s*2b97fN{^XliOoUb-|!B5{+p))bd7H}PWUF85RQ3=IuaS64?am!nuL zV%s+I?=X%zTv%9;*RNk=bTrDuH*av}jDezTf?VUak|WYwWpi_ro}M05RYg@*gb)ZJ z#4(3^dwX(X;u>FnHHc+Zx$@Z@`TQTiBMSKpzb4A$^BR#zgwD=R+S}VPO%qMi{@MAn zz+^H>G-~kO_v@JEtDHaIMJQy0{GI!$DjSczly?2Jwzd)qg=lJOA`l210UjB7U|>Lu zkAE(GJ|9=Fe#(zO3zl1xTuX=%fv9v#57HOJ|Bvrh!cUc zv$Kr61;`}#)-2-jT{0ORMPz9Vrr3Dg!r0h{1Ofp(9?xO_YKCH2mbC3{6p`T0QiZkk z3W-FSot+Bx^%_r}_Axm43cbC(0630=>$-S6p4vda-!IOcdq;lp&KYt6W}QMynJEhb=0V3V}d?P$-11>j)tZ z6aII~HSb}eP>|_#n$^`+QmGV{Wnr2o9UUEXcX!j))d>3jydz;B5c^0cuG^ zK~xyit&}lu!Y~kppGzitc4j{jBAbWc` zC8flAy$0($ver5nW00n4Yt48(?gy-4&N*0XVXZ}3mKSwNl5_*lVO3Ruh~S)S1S+M# zMx)VH;yFx8i8ziyL?EJzS|P*%IGBB0B!6F@F`v&tMDX52N(rSDIOptI0}%ks244r& zKEF>u0ISssN+~2s(hCNld*q@hptbG=0|2(&Zo^`+z;3r|eB{k$17l2YU?hZqQmQd2 zgg};MNYfO?n7}z_UDjhn6w0z}R1LsUlswN-f9y8vEtg9~oO3oD4qHd?-UsI#ilR8W z00000NkvXXu0mjf{ZPj2 literal 0 HcmV?d00001 diff --git a/src/gui/resources/export_dataflow.png b/src/gui/resources/export_dataflow.png new file mode 100644 index 0000000000000000000000000000000000000000..53f9af9f7b719412dc206db1bc63922313366780 GIT binary patch literal 1131 zcmV-x1eE)UP)d>9WBNPIavSz1Nccq zK~xyit&~q_Ty+q~KfkxT+3d@1Ub5!jHciYXX-!)rZD^q$JSapE!BbI-1_UWmj1mJq zn1!MhL}(H9q^R_y^kmb3l=>%xq|`LqZgw}x{(0~H-g|lDA+{*$LFg9- zhGFJ2Gcb%25gw)t94S|H~dY$B!SEgS!T0{@i;aUw$U?$wiS5-j~YBDVaPpB8F0O z`SN8E5ekKZoH}(%3WdTyniv2R6BFY6_6ygh&v2l3CpZqc4%F+U0*|wY_Ve8{Px0!} zqpYl~$n5Ma-`uOQvwx5a7cTtmOrlq=T#>IXUE=21Gho}`dtle0T7}9cHz+qZ`{Z4hP=tJ84Y{*IP%g4nUL#mvBUmpIRyPpeBXn#wzx|wJ6K@e68yjQh;}3ar zcRw3mz`E~I)*eOeao2Tuv?)RH;xwUl2&)xBr$*>FL|Yy~#bRtZHR?b9z>^0@=1j^h_?5ZxI(b)f$97qDT#DKwstk6TCI-;l(n5cKKbB>I?_(ZXd(9_dHQ&SU` zWs%S4Iehpqu~-blFvw&w3=Iu!1A`!ta=FaH!UDNmj_cR2Qz#UOMx!K?NqT#GNu^Sl zrb%~qHvLq1IyyS&>+9PFiio(bOQBF;X=#atg#~WkzRkwQ23l(( zkqD+~($&>PHk&1z&5};1`ExrA!@#mET3cJU-04b2E#B=N}-fee*kEHGUngVQuzP?002ovPDHLkV1l8v6Jh`W literal 0 HcmV?d00001 diff --git a/src/gui/resources/filter_next_steps.png b/src/gui/resources/filter_next_steps.png new file mode 100644 index 0000000000000000000000000000000000000000..bff8da3d60c8a9ecc311bcb7a9a861c7a73984be GIT binary patch literal 1168 zcmX9;4NOy46u$kn*cOWl6dUN9#+57uYEfCnTw6g08xSaDwi(Jxi>MJ-qH6?Xw!9LR zplA@WWh5fmkQw=r0a}C73WXZ1iV7kS5dRCVR9Ysb(!1B}Cg*-RC%N~0_k3S&d3xIS z%$4g_0sxrFNr_S%L;OLb;(K35emo8V1xfNF0MOU?g8*vl*m#k=Pm(GD;Cf|=H{(2> zBg!OcDgebB0nq9I@IV~x0H_53%%A{#qX!^VRh47ei65mVCrYvk#}tbYibx`nNQYrW z5^Z#JRKVYTtC~P{FDzJ^o14{9_|kS%(s0YxQ?PB?x;WnP>x9+|7C zsCZXiUT%*?2kv%*Ry3ZS>f4;ZN&^Lg!69(;jvGSWs!R3DO9V~Ff%g~dY6`b zH#$3)RVeDrNl17ldb9vt^YcEg==f*&YTzs!uvnURZe=4{gvpTcm6E{C< zMy|=BQmKTqcKdQ@P>|TXgu)nkkzY~9zJ*w7*{e-84h=~?qMnhG5=`V z%wo4}j znxX|n4x{7w2ixy)$lq|^-o4Xq;Z{C^IH9SOgx($+8hTc$xQ4{yO!M2Cnj&>oRnnz_ zvs~C~!YFi8bXG=&rcHKeGBSo>!pT7MFe!6jTYdL>{%QaFtoQD1VskjLpm$3^ zb>Arp&YE)Nlp%JXk3=CHz6x+%FE=*!zj*)NitgWUec^C?7xstU_3j~@o9bDWHh?qr z!Z(AV1wwLISCQ*2OifLNafim-8e8oa@I@5)LM6s(ddEYYj~y_@I=GEb=+@-vSAb*6@u8l&F7|(R>xT9EUbz8+1Dz& z{t|W^c;dSx(nQovmj2bCC(wZ*fF+hOPY}>{A}=BR1i@J7m@vZDY~wt4?LAXUX627u z|3vQ|6wq?>@_za3{S@Sicjc3+Y7>hbG%%E z7?cLc<#Gl;D#`}j(MjR))<4@eAD_NUDd?gk3xq<9F8GxpT!Uy$WC2v7Xpsrw^BIrt zGllG|Y>a_BcdZrOxSdKOv(j`D_G<+y>0|y7gm+$Xaj;&oI!|C_rB7E@O7e(g)*hWi z9|8-x9pIF_y&qO!pnvsKY2MY|tLwA< z*Xuz|kZhB67{f4zsp0T){~3d>0VcPty^H_=0t!h) zK~xyi<6Hpg&kG!>KCM2j?{J1@#0 z#l%@ek(DK7fsDu~C?hH<5+jLP7ZEJbY#YUD=Js_V6xMW!yX(0;aDE)lbKWC}qDUem zA;C#FC3&vjrKz(8D3jyGk%@-9VaR#e$%zsc8nTJ*Ao}Se;1^*_$aMiHgtM*+-IZGq|)ngQB~4`POo8!Ea^8W zu$0@LClnZR>24of(4?$Pm2vviP3jvfXF3o?kzg<=dcEF7&9XwFK&ey;!vFUlCLH_; Xw6>-Yn1_pd00000NkvXXu0mjf2Few= literal 0 HcmV?d00001 diff --git a/src/gui/resources/full_view.png b/src/gui/resources/full_view.png new file mode 100644 index 0000000000000000000000000000000000000000..cccbbf108454b95fa29c4f0df008078792609c88 GIT binary patch literal 643 zcmV-}0(||6P)d>3IK*w;kp0-0uV_= zK~xyirBpqr+E5rh*B62$a|%L*T*N^FF2Nvg5D64qx_0Z}TZ&7eP{gIXgYXuY4sB-N zCUs~jI6kPeNrwzqNU4x4E(toA+d+-izo+e4?#-9`oqYG?J0Ibk;~E%-aWY{v8W92i zfOflm5Nowsm`o--wHu7%82s|HZT8twF&@mbN~IIn&rC} z$zBvi;<_#mf?%Ee`lK9Z|8gA1NTpJ69ES%%07X&I?RGI33}D;#X~O%PpDU4n{MuFs zpx^KFOeTZ*d=5oXKq-aq`=FE_C8Lyrlu9K&y1m82a0mc+Wtw;x4$(=cq3b#f!+>EJ zpp-(ABoajt_kAB>7#j|_gKuTs^UO dyW*Jj{s27x<&PdJ_pJZ`002ovPDHLkV1n`G76bqQ literal 0 HcmV?d00001 diff --git a/src/gui/resources/import_dataflow.png b/src/gui/resources/import_dataflow.png new file mode 100644 index 0000000000000000000000000000000000000000..693bab0006f44da96dec50108b66030433bb45ff GIT binary patch literal 1107 zcmV-Z1g!gsP)d>9RnKPG?oAW1K>$S zK~xyit&>Y=TxA@^fA=wuJGnF087G-3w27gq51LqQq+PpkuOjXQsYDYBC7@jdq_o&> z6oLgw6-Bxzv{1F+N{Fc46ogi5T~x;;)iljyCYkr0+~?fCi_suh7eWsl`1td2zVknP zM-dSoBvc+S9=M=>zhS*zm!+j8a=9F1V`IwyQWTLLE-Wm_#KeT8Q-+KW56kXcR!q~B z0bFv>ugnY#Zs?xZN%v|N0y6 zu2y*d@;Brj-H#{G458M8S_na7i?F^$xVcX4*bC^bR*Q6}L)dPE?<1az=epEAkE-Kx zVflB)Klp;pk^QVW(CR@@s}gLi5!5O~ofhJ|M2?M!ppTA@vb1uCM+OY+FvJc*n!ZoN z^C>$HPdsGt)tj#{eD-tH)BwT8U4o4@!p#k$ZW{?h6kP{Rr`PMDoIZV8O6Nc2wa3P2 z`94iApb_{qT#t(Dvgvr-tk<~{sXTn-EszLr`8M9lZ6pj(Gz~SDgk+Naii=XK)nq82 z=gc!tF`&n2cph7>$Cl^P@O|1|h}#P(J1!d$WS)DGU}F`%^b@I6idZa$s;cO^&gA4| z{~ylJ&&xY=bG$SUCX>Ws zF><+Fzsu9p(*!}l+}s@dGHKGWe#N_Ck8Ti9aa@YKck|@ly=a=o`uaNKhYwRM7AX`8 zWHK2Ni3Fx;_8o>{DD`@sQmMqbbLY5m;|A4g6002ovPDHLkV1gz#35@^% literal 0 HcmV?d00001 diff --git a/src/gui/resources/import_superv_dataflow.png b/src/gui/resources/import_superv_dataflow.png new file mode 100644 index 0000000000000000000000000000000000000000..b77d1b3d81e132771dbae1197296d46b39871972 GIT binary patch literal 1746 zcmb`IT}&KR6vzLw-yiJa0?S8JKvHUI09!?^@eKuA(nxAUOnfjl7!0IIgK0@5Q7lRy z8Y9}oK(zHEkwg-(COq_oXv+)L1hn=AvjVk%d@Stl%c*oSB<@ zfAc@*+;ivB$+lymz`g*0Q0wvLQ{+py`8;(0@KR-noTuZ&v1amgY0po+OU~bO{FQS+ zu$Y^G&#so!p!a<1i!I)HPcYp0&|BLRKhnb2TAQ2NpNR|lKrE8ZVr1qB7Hx3`xi z5(%32@7xDH{{!pp?q-LcsAXd_AG2G^1p8k8icMxNv(Z1_W-pv+WP(FrV`F1%eSMwv z_xIa=H>h3Zo}M1In7o5`K0OPInNX2~X30>Q2+>L*Z;F_`5yO?2r{M{P@bu|3Xo|Qo zFfj1HbhxIbrr5;fH~9MJ50GP7fax&Et1J!GN+V}V(8(|U6o)@th_3M|Y_6_gcKj+j zJ3E;m2;k=T`$18{Da-POrZ*0wy1ooL%MmC8g_KE_h#Xm#?E1w!nE5h}&hKs_TK_mS zj}I%ViF=_kEEbgFw_qu5Yc8m>(-5N3C>xyVK%_JX3&sxAlu50Otg2x8%I~=O$tF&Y z|A3-L>Yz~{hz5`_$;j)eZ5TIfWhAh?3M(hu1$Ncc)ZpI2U4$R@LzPJ(nIh()rt(Ow z=TPxzA$~dcDylAj3r8SGpcNZtY;C|&(qM)G!A0BI>4IsR5C#Va+4a~Lc=q*LC{iAV zs6!%HE~P=*B(+-_?%qx!x#2)@$9XE61#NL2+R{A1bO=r-9Bv=r^Px^qA@B_wEiFOY z#Uls?-H-{C-PVxWrmzW&w1J#zAhWJQOakGSQ>1ViuGp^#1Ojlo-EcS@aFNQ!#zxrt zaA;_V^}pYTBkfgid7MzTRAdsG9lm8Tm^#Dusti}&3t7v9%TZQV zhHy9xuh$D|(;bC|VK6!n5R1hyGBSd>xjDq+aXSn?sk*w_R>Bu@KqL~e7xQ-xUAn$rrRc*-9(vl5cUS5VMiqJI8R>i>;6&0wgtVBskiJdd=6Dq{1KP>tVxQu531&eam%S>AJ3zQt~3Db{ns)t&z=U+27yq9lI%)%goQu z%TlR?VHo0n3&Sv!VHnEpz5huF^ppz=3q64E`{Z&td0JYp)v+?x#lmj+zAxwI=A`So za%*d=ue2vD7K;FQp4U6?#`8SNgu-=QSt^yzopYg3 z;KuFSES7$tR=Lk_pMA>I)D$BlBM2cd41=YmB_<{Mk!s$#Lo!NCEyz9{hS_dj7x zzD8@rBJI70A44mKmW1}>2CS@5C=|{YuCK52!6(;wv-BhB@jQWqKSQWTP!FMV{E+aE zhlEEDsDJntwOWn7LV(rPRi?iDmZNN*N(&xE(5WBNsaELJYs8I5$dfj4>o25~93CD% zY3O<0nTBy3v-r_Fy!_R7C_^vNsotkktq>kniT{3#3`2yf!hlK?MeOeGJ}W%^h80EO z`qDLSUV8)U>c=2sf_rxfe!q(hJBWb+ltCSIoqRse-rn9>;c4l~$qDUto6qmuV)*s9 z36CD2R_eQsVo*+}zw`XJ_Z!rePQo z1Oc{fGdnv=KA*=lO>|vHQ4|zKdGg2?MF@east6%SrBc|oO(v5;(==37?QI?vz%Y#G o{^d=J07?|WikK&1I$T8 zK~xyijnrRgTU8vu@$b30t67r%&6*~)4S|LJweDdL8#3tAd=aLUiiJUuvBJ7O?yYZS z8x#goEE@>Q@NqIwe3OE8Q|L>})D|W)OkJl4z8#ive5>+C?i@167 zrhL4-%omp~G1}XUdw7Uznz+Rxj%iXa6sYHNJkRBrHw@mpc8%rbWt39th0z4p*4E_x z3m5qI$`xL3Z^yN5T+_rU6mW}0T-&BzEK)BNaPoNyr4k>Au(-O){QNvVpHH=bQ&Us& zcD2g8LqkZpO#hubJUxHDQK4<)R;x(4%;@eeKWZA52wT9XV`FS=Y!Cb0`}gm2aBx7iT15lc-ri=!=flb6aI#tI z2M6q&IMD=7IZkuFrW8e>;DMdM&dv_$bQ;^X8=zqrbRHfyF~_oya+#lWoul!CQv3}q zU=6S=i*!1TWmyfdv$GSkP@rZQIQcwosf1gpv{VLgPNWHCz2`pQ_xmvngHox~0EdT% zd19J4*(|kuo~mtgs#a@4-@j}#W<}WZpgdpz9UUE%N+rtWas!;6p5~i+oty}1;PjDZ z|57RTfX|Mgt0EYH4Lk!9i3GJ;4aadB;N;|_>N$6g?|?M$iTCn~Qlx+pDK4uK@zg&CPKK_{%%aqEb8qegl35Qo!%PX{E5ekC6g~M@9$)0)#># z{C@vSaAszPnX6Y>@fK#iYM%qU-bQ)A@vx^r&)^{AcTeo-<=mQSDQ3YJDUG{*)$&-wZjuH-s>F@6+8jaH4-roARsZ=VG$z)hxU+3=K zyF7gGfFPiGm6d@=G)g=kCl-s*+uKVrnPg&Of{~FCqS0t8=(?`hwoN9JA(cw;`0-=5 zwze<~1J`v41Ol|RwQ>CTae8`sh{xj$4Gob@CW*yjtw#pXG))Bp0qN`OL(?>Z!61=H zgmgNMX_`2WgRbj@LLs8jD1(E83=9kqi9`qngZO+t^$&v&T4OGeQ&9i_002ovPDHLk FV1l$5{vH4T literal 0 HcmV?d00001 diff --git a/src/gui/resources/mode_breakpoint.png b/src/gui/resources/mode_breakpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..8836ce0bf44961597f02728f343eb200889b0103 GIT binary patch literal 818 zcmV-21I_%2P)ptWsoJqoc0sfxAP zxI_rO=%HX!QjCe41Sv@lNr*~Lq8^Ggp0pHi(NmgB1%rq}#267mNL>HT%Fte z>}EX({lV}Kzt8);@B9YdzVuZ^(Mf;)n0ph{f;xA#&_*)Y;4?K*jvrZrlzJ(gb-V!C@Ou( zJk)$xP5*e0ed55$zF1(Jd-l{ChGCe@7o+ib+?0;ve4LwJcWtfIcFY2n<%8qB)`z83qme)m`Qpz-x zQqsoOXK0;x~?geQqsd?cJ2|6=N`RN;`sVHgf{5-v4;y+&a$vLkB5g+N*akoVr3NX zDkT)0{G~TodbPCjVSPLjiG(Q~$1%Ns#Tz$lE-A}oo{@R}jQILGbQan>PX*r}J~T8k zdhVw@7eyU^KdGe`~%qbHeL!LCV|OPQmu6xKxQFBM^`#%O*Idv zlF949#D9s)x`gu8(UlHT%hGGWgb+gKdtsO>PF$ul2T&lrSs;x7zS(!EkdMmxgJ`Wk w19k%UfWHcpYOQwz4ZL~#2)JEl;Qvwm1Nkx`_?O+B;{X5v07*qoM6N<$f^vF}xBvhE literal 0 HcmV?d00001 diff --git a/src/gui/resources/mode_continue.png b/src/gui/resources/mode_continue.png new file mode 100644 index 0000000000000000000000000000000000000000..8a592c0a747bf31c54a55279b46ee0895669fe99 GIT binary patch literal 308 zcmV-40n7f0P)*l0go`APfYTihtp!FE4Ws zfdr@xB<-cXSc+yR1_S(cQK=vlgi@(b831_Me*h#4X2BI>i+>>Z#U;2bN8X7gNMIr$ z&9@kdZYH`rbzI#cq;x`=IAsKvJV0TK^C>)n0wC=(5!s#hs5xXx$9ZPvEz*Vr0s;RRwRFaC1#OX0Qo`_QkN(du-6y@;{*B=yO7>9?1SRX%v2?f2B5_Jhk!!LR^P5RT9|1-Jm?=!l_G$TuS&Ha6QqRSW z9Hr&sn#5>xj9z24B|)ol#uBI1c&*AB7e)Pos9ltGH2X{c*e#16%)wnflZRZXG)w+k=44_4cVVXF0EKkFVE-YtPo-<4Cy@xx~{_c55M@R_*{;>)7N{DS%=c}*{K)yZoeDZFnn?WZ1e79vQu-V_&xV_ z_-<`Exv&UA>H638`Rd1?9O=2?x>oG|4GW8lpxcGjbGJR7xaGz+EVA#3mc^@ZUOIYv zyMOcUemwa~_!%r^Wjy~|vzv{LHt#^JUjao;=w?= z_Lca~)6WdP@#*Ym!q|(~dhq7s$6q@ZJuq~Dc$rF#jy?%I_&>Su=kKLf{g>2f?~E86 K8c_BnC;tLB5zb-& literal 0 HcmV?d00001 diff --git a/src/gui/resources/modify_superv_dataflow.png b/src/gui/resources/modify_superv_dataflow.png new file mode 100644 index 0000000000000000000000000000000000000000..c6c7c115ca58d0081920d636423a3fcfb0aeb99b GIT binary patch literal 2084 zcmbW2e{2**6vw}NJNx7A+H0@0MWJewR&ogyh0@p{#a|_~fb}F7wFwA6-y@h-sH&v!3HdK?RHvRnB1LW*` zYwF(uoVnbDuS>e$rb(r#_J#GzZ?eWK z``L$x`63A77sL}fDk>||3#@}+FbI#wW1UKm`}+EjNF>ttHa~{J;cpaehsRfr_xcVZ znM|e^EM$-Y))9xFVr|Aj6JG3FhE?rr?h9@Wh!khgsi)vgMSJkA7g%$29gaNtDI`hC z2%5_=SF=V8Ign$>(T5CMaOXKAm+l+N*stsM&4T{9HKp>DFr{+?= zx3|}5Zf-VGo7&K?0saZFm<*li2tW#j0G z9Y%%mH0G-@KQ1E#f1Ti;O&^LuVa0oYJgHWl;K3Htv-WCe36re@&~1OYW~*5P#9 zNfd4_MwFzuIx<9$0UMp<(yVfPXB>kkxEgjrf=!em!mK&w8mkl>%(ph-9PG$*qM@}B zXF9tuN!g;7FB%Vt)=dus&;^Jc>NjyX%+aI1NE zakmdzRKuw+P7oj$7l-@^`*a8)6-Ul>puP1Y=yDt`I7t?+D3wP`5lVsid{WaiIP{`ARQHj1vp8?-11&5l=+))t_ znTSA(Qyh%Spe#a*=veG2!ivpnak8-k{&Sbi^;NH|hA0aV8T}MU?YSZb)deJ|7nD3m z8cJ~3BqS#VjE{|C;#LU5-9y;4>m`UQo#<*ij{Ic>$WdGbmGS4m?{kB>6dbJT0_doi zS(3Dq?hm+NciJ&^Hwu^A3Hu!f-fwF&qvoln&Zgd+Qt*g%BZ2;{TFxM&@+co4LKOtI7O+;8$POfsyT;P`kda K`kUu=wEhbxKtXnd`d)%gE6jqs`l{ttcs s1sK+B{m$sjq4iwn^d^O+U;dxa-)&IA&~$oPF3=kcp00i_>zopr0M+VqdH?_b literal 0 HcmV?d00001 diff --git a/src/gui/resources/rebuild_links.png b/src/gui/resources/rebuild_links.png new file mode 100644 index 0000000000000000000000000000000000000000..e4647aa04e42cc64dd5de39a24722bbefc92ca11 GIT binary patch literal 746 zcmVWFU8GbZ8({Xk{QrNlj4iWF>9@00K@)L_t&-)1{QZYZO5g z$3J%$kBj+H2v=kyL?KBLP_A4s#eq!%gOLVm_^OdQ7m#BqGm!@Ta-wAOn-saM%t2G)T>w;qO}2WN#9wAMSl z3cEO^^;QEYg&`#eYPjJwuLDF;G=5m8yt`AY%~XKhIHuyn-8lYhc$=JT$ cR(F8nFVJ=7D^5Ot3;+NC07*qoM6N<$f@lahhX4Qo literal 0 HcmV?d00001 diff --git a/src/gui/resources/reload.png b/src/gui/resources/reload.png new file mode 100644 index 0000000000000000000000000000000000000000..e89ff132b14d0fdc03c1a0fdce8f24b2bbd33e35 GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAd3?%E9GuQzsp#Yx{*Z=?jGgvS%R5CE^WnlOZ z6lM7L`qLC3#aI&L7tG-B>_!@hljQC0!qCAg>jC6&7I;J!Gca%qgD@k*tT_@uLG}_) zUsv|)%)Gq30@t40bN~uPdb&7zopr0O0;Yv;Y7A literal 0 HcmV?d00001 diff --git a/src/gui/resources/remote_run.png b/src/gui/resources/remote_run.png new file mode 100644 index 0000000000000000000000000000000000000000..f95908e3fbea37ca5fcb4a7679a2e0bf37866022 GIT binary patch literal 427 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VTavfC3&Vd9T(EcfWS|IVfk$L9 z0|U1(2s1Lwnj--eWH0gbb!ETK%FeAJ?YnhnBm)DZg{O;Sh{WZkQ+@r881S^t&)z*N zD?*|7$Sg}n_Xg>L|H>O$V`snGsNi{d%Vl{%&7k@>`epOxa(KSs6;!-(z~IEZ++v_Z zk{f1!771|C*g83?jwkuRrG0a6Pj>N{ow-WN)9GqN-S!`Gw|83!yI+#)vJ7-vz!oBy z%R7lFfr+VMw(*>XD;rn~OfLy6xA*(d6i^qbl=|o z(>-0T-wU&>ZyScNALFTD3o8q$ z`}F6Xp-bF@O!UI^46^syeF<9s?)vK~u~(-l@^DvM7O~E-+#TIMfBpNr+7HCf%wgf3 TT2fU63|0nDS3j3^P6d=6e$wn_)q`<187M^ zK~xyijg`+&TvZguKWE;(!wd)o`Xho}7+u(vannS18cSk{md5A;YfSwIx-f3L(zx-* z!Wh$tmJrj%g-xn;(M@fm#WY&9rU-$t19T`bv~&gr=Dm6MK8_27GSGzH^*NuMd%ov; zj;Ja-JrPj?gL)@B#hOQf4a}dRI6jLtR^1NJ)YfD%w!Y-RkU}UG%J{^yJwB}utx!bt z)Y#WFwl!jmRqve`W0k}MLNPam2@E2lswyI)H>Un(I)96_No(w5ssD0d*xlAnxx7eU z{uE-Y_RaK>GAT-h63_R%$Sb`^SuRu%5xqV+L@uA>k4wMf68E6$&7xRi^~~gVtb{AL zxJoSpQBy_eV7E1S6s#Zvg<*$p^$PeF!#B%ucE*kbVu*xbm zB2Iqz{zgyhfNOJRA#r5W83-XQmcfg^a^>t*CWj{o0>hIB_Oqv>lQ0TtAWie*`yj9z z`RZdaBBJA^9ILEiO+s$+4puBxSEVpqU~+f@^=lQ_Myp5OKEnNf?-Tlv$J(3u_{)!I zYi~yo(k88jz>*uzF*`TQ=-4RTN4p6_kHO--#{>_$Vgf^^JF1hE+;;%Z!hY zBaz?|hfyC(+N9Mb4jWkB=zWtFw}KBHFZUecsRK`A8m-#E@NJ==xv4pv^Tdgxn4jab zlb>P(i%T4;Dh6PEC`Cl?-kvAb>`0NKb#E)r?mx&^$6kO|p)fVi;zSt|u#six`Va(m zBY&I9>kjz&#$_tid9q|ERTe2$A}X#z>|^jsv$QZfKg-}xSGO&UZC<`PHB7lQN3B+4 zDXbuXiySF0#6BhpSDC(3prvCM$3J+Nt=>;(GLfI4|BJI6?|O$@fBwTvVF7%N z+H!@3k$YVG{ulb+JI(w|k>-vTdQQBC-2~m_Wy@%Ol;185a^c*Cjqei}4jp@m&S#$B z$Is8RT#iuhM2yu}PaK9w>bB4ZaI@O$ldr0>r*p3!?0Sx|k!iyJVQcYg+bBtVo&D;1 z82ebZdeb&F(bUn7F-o#!AA0Y$#ml3d0As9XcW0>-mv%e>{{cVm)#sy#@ml}@002ov JPDHLkV1mDe&A9*o literal 0 HcmV?d00001 diff --git a/src/gui/resources/sample.png b/src/gui/resources/sample.png new file mode 100644 index 0000000000000000000000000000000000000000..71e30a1a21aff362fd096a7a17c6703b7268e84d GIT binary patch literal 1623 zcmV-d2B`UoP)X>G_9Qo35rBe4@i}ItxzQ_q$UKT zxP)dGio7Z7g9#OZpVKtum_>FE$VPIsR%yUUmh%UCY)=Fg;Run9aN`L$nI61j*7n-F zP9kXE#n$ZX?0YlceBYa4<#HMSXAFF30tbZ>q|@26XN6y%wY4>Na60`XkN^NEt`-^R z9K6muo~g5{sBBcAsTzCy`(qIr4jn4VUg#+x8jT775JF(`!lc(KJj&*>Qvkp@AI#>m zZ#n1q&jC$d5~6`as2fVFRBt`^ZFL{ZtOFj5Fa)Dofx7GRntmY0`dnkEdx00873usaz5OaQVB-Efe7@U}ABpvvF|=LI}X)84=0fibMF6e8xFvnyUG3 z*nZGcK)GCIm5mBG=crX{xN-A_XrJ+RkkSy~wHb*>$Q1wpw-~<=-IoA|5CcI-!lr57 zHw@!yGMU8k@^Ul#NQB42jbDVDZ9CgL;GB>1I$!ttM$iy-zyLIbGe0xud|b{b(^QS8 z&GaAuKmqiGj@*OXF;eJNcr0A+IauqM1M!*ouGe!R1Q=^9RJ(v{SFRlokA*9N1+?R^ zeNlUe3L!dH)s5s2Np|2mkb97WrfT=one_KW1YYIM(e#8aDjSs}q|jR;^0gJD5J17d z-9BDm0q&xssTu%Wozv%9RwJEBGXUV6kASe*UUa-bL;wdgUHef8fy})OJM+~U5D|t( zh7cKvj640-y~gTm1$=ywEH=;+`m4;ZnJ+;2(_M7D5E>3ik-tbrM1&z4LS!UzGCUUc z-1riQdZ3ZTCYek^Pv}q7S#@t`d&loJM59q5gg{}X@F`>(Xb5@c_wJzzFio@hKbcH^ zmbsT<6H^mn>($nH5FvKeeqG}=Is4;5YCigXH`*H zDV%c0@nL1NzOzt}qGK4wplOt+E8Z53B+2n;uVdX7mS8dd)HE_-` z8X1LtT^EjpK0!o(cUz6V1h{>XbdpZNS%=H8IU+Ep&+S-wYZ$;@VWsdfuk%rLRuzn~ zmQ!AQCf+TZ2@vjrV<9vg^4!dU1vtKFfOGzbp3uK!jKMGrIqTzI?^t>3bbKbh4d5>; zZ+%S)ZA$Whe>QV|zXi2g6F2(W#H7$CdO|-f$@}&vTDS66B%8}#iO}bc-l;}Ib-g?7CNv1pmErqyfBGuE^CoO3jknO?e$u< zhSYpY*j2j@G^%HNij>5yytQRl?TB18pnDi~vC#bq@H%X3sul)f)>Iwa>i};k4w;tJ58*bu5Gz2JsmA4eT zYVSJlHaBcf0kjVRevtP;srl4hSqrSZ^|@WO_q>QlMj|JP=vinuve#_A8)40U)wd1}5g4_p5NF(MDA9uV@ zM~FBUdfi=|2E@CPw8!@RXay6{Po{7YKT1R|yOsWK=!di$T?O=;DI$@`2_kwP8VVi| zK~#90)s#Jt97Pa@pV^%?cRujP1;{dz0|F2Mf`5RJkO&ZnKL9ZiB6SAQMFjiM3R!5ydQ{YN&3aap#{o^P|Og&0_WO&o@3_0Mr}dx}F}q z^vbnMP;u?*KA(Q^4a+8Q;kjKt`{ez{(tUs97JuHl{lT|i{Q~ge8R3+aE(+DKiJQM4 za{0n}>U#3TZ7-S*2i)_!Bj_fPVS8283-4dt$vAf^EQ+Wx zsd~b<-*}a)&tGK!(zA~hbuTQNmgS7X zY|3Q!9J5KqY&zj61X2=m_D2yLJI~B`=grq}cR~sB_L%kJJ3BQg3Q5v- zVHwCwm8vT2?bV2YD%5qMu3IqLD zArT!Pq1mh&tdQ-*F(lUOKygRaaL?rYa5w9tyNyEqLb9DW#6$=QykKUO;<)#{&+{w5*pzD-+4>C00000NkvXXu0mjf(rkxD literal 0 HcmV?d00001 diff --git a/src/gui/resources/step_by_step.png b/src/gui/resources/step_by_step.png new file mode 100644 index 0000000000000000000000000000000000000000..1088baff57cca623bee0cc8138ca33c9d29a6e34 GIT binary patch literal 896 zcmV-`1AqL9P)no(ehk(n}x^njR9GTX1?v z2qd(}Kq2(dQ+q2REh#;;*Iq&~Ar?L)2e(*}v#D6^+L5eycXnr|7birHEF?1UF7t-p zy!YmPZ-B|x8vwo_q6QHuBH9CR6@Z1;Sj$B87h~)hV@y3aB3cDdKX_Oh188#2&vMRJ zIOhWZr4-UM?Mf-rNx>Rp?6hs$-{`vT648KDN||R__5eU{5-?+oot&AOx$HQOJM2KO z*LxzR{29QrNx)UxwpYsKa$VQ;f%J(8dwY9`h91~4}lVZqeOJvG)yuO#mi<_P(i+;Dv>S#Y&}ezgDY3DTR%Vjm<`*aZ1y) zr&*T$3*ZER3qY&JWFVf;BeJNs@B1dlg2H-87Po@H5yh<*U@ z84(p;>XLT=TssIpv?Bm~v_Bg(085OqKNw?*b3R~1qyQ|A({2jDqkRJrE$O;`Ti5lY z2bHIkf)L_fnx^5TlCGPkdEIs0V~nvEu>A{>rfCw#@vi{>n*?m?y8dOkT>hj`D7@m# z^Bnztzagdk5x_)4$OZ7JrfKHX)YL1`FbvyCl3W3>HMa5qR2X9)NGaEoBst-EUdeS` z7={7PIlA3$CkTS;LWo-c^0AZ$fSacI`SkSkPnKm>k|bGax7)s97_cl0oleJZHk)6^ zas2(T5{!!2tJP{3>-GAg<2cJgh_&6_-QR=|?*~C}F9?E*LWnzu4WCgpo-P)PZ_Uro z!!V4J<2c{0uCAVGwOSto=m1E@`NxJuEG)}9QYaLbq9{tjFuWZ_(Jui00U*cyApZwg WusY^h8IBeJ0000d>04Le8yjuVO15-&v zK~xyit<+6OBUb>x@&7nZf|}Xc1Wm+`l7m4du400R!q&^S6cz$qwopW@?9p?P77C@; z9@Z`%)=N(!h2o`%)Wwsa(1Yl~#ZsdfJyFH@9grIs#LI}pk$Hm94%ZvVg$YzmVzh-P~j88nT z#!{&iU#cpf4-8PazNYKdD>mQ0B^HYzNs?6i4P6%u19Tk#+qUa$Vq$`C-@L&!3{*+t z>qLT?nHfr@60Ylt+MwfrVQ^V00Z=R!>ns+FG4$jKKW%P;M{q3xGnQP-px5`=nASzFS|%DwXhi9^b^{%+1Y_&*yO*r*?;KxlF;f0VtJ9 zb#``kMl>4b)9255xwVCG9G-S|vbV9p($W%!VN?Y@58Lx7d)_~Nr_PGSB97xQIXTG> z+uNL*Ci!xiFQQTA=jX}i^Ho71aD~9DzB%`pBuS*xX`-r%D+HI8#h*7fghC-ME-tEq zwoSpdF&u~gHDF<3ftQH{r>03p*ZJ+_grT7!ve|4U=-M`ymPMgz@qMubEDODA@m=#gj~{1d`2Nu&j&z+r@_By0xL|a26j_#$ zWw{c(DVMpjteV%mYdbqTJnig6QxyI(O@28#;(0J^S=d>3o*`-(7^xz0bof) zK~xyit&^c{!!Qtr|40SP(OP9!T7%$dAWsmDweL_|9BI||0>#07g{rt9Uk<*>(GVzXuUvxm@BN#>l0XQ7&1Qp86}`-2v49X_*kK&U z&{~6tKtz_q%jE*CwZRw_b{!s%N6TRo=kpm=Rk;WIo}YGw0E`RTuRQ4=r7VSAe~B6=+0?67q@9Fwrup;D@M z#vXFmI8sWXEX!W_VTVm6eKFRd(em|rt*fdUoG~E;eBXDr{0qVlzrzV!9ee-)002ov JPDHLkV1lzs$IJi# literal 0 HcmV?d00001 diff --git a/src/gui/resources/toggle_stop_on_error.png b/src/gui/resources/toggle_stop_on_error.png new file mode 100644 index 0000000000000000000000000000000000000000..a25f75776eca0c5c02fa6e2838fdec18138a12e8 GIT binary patch literal 981 zcmV;`11kK9P)L z)Xh&^RT#(d?{n^*JKULJm^ZjHmtkI7#?~rK#cEqv)QUSzjJj~+-E^r7lUn1VF6_b> zO-y4+`~%cP-TJb3VMElEYosxT(1t<_fm&WFuMYPf7etV#9cZ8AEY5RsKKbQI&JnFO z&C2)065(yFnFod*`&0+b?wET(4H14$*ZQiVM&BJDc@B7{**(=XE_jK~TDj1BqQ$MB zu+3!qN#B#F9|-n6iHgVv`M%S!;J0rGZ(OEuwBHut(t{>`HFdBak8CcYmnPA(qr{U* zY00`3-;(Gy8&lPjX^L&t?xFYY8U4N2Ri;L=u&Cz>X76{ebiE(YT1b z=X=t!XIO*_?TfvCRqBPhYh7kACF{5AF#uzVI*Q< zbhx{cwZ#k$6{7T%q9`T1Q@bTlg4~_NsdTj{VF*A*Ug5=Kbo~)*2Bp0S7REjr(+CKnUE?S}*?v1X~wqOZ=lg00000NkvXXu0mjf DGhNYr literal 0 HcmV?d00001 diff --git a/src/gui/runmode.ui b/src/gui/runmode.ui new file mode 100644 index 000000000..3782ab355 --- /dev/null +++ b/src/gui/runmode.ui @@ -0,0 +1,636 @@ + +runMode + + + runMode + + + + 0 + 0 + 395 + 509 + + + + + 5 + 5 + 0 + 0 + + + + run mode + + + true + + + + + + + unnamed + + + + layout11 + + + + unnamed + + + + layout10 + + + + unnamed + + + + layout8 + + + + unnamed + + + + buttonGroup1 + + + execution mode + + + + rb_modeContinue + + + + 10 + 20 + 121 + 23 + + + + without stop + + + Select execution without stop + + + + + rb_modeBreakpoint + + + + 10 + 40 + 121 + 23 + + + + breakpoints + + + Select execution with Breakpoints + + + + + rb_modeStepByStep + + + + 10 + 60 + 121 + 23 + + + + step by step + + + Select execution step by step + + + + + + buttonGroup5 + + + ... + + + + chk_saveState + + + + 10 + 40 + 107 + 23 + + + + save state + + + automatic save state on end + + + + + chk_stopOnError + + + + 10 + 20 + 130 + 23 + + + + stop on error + + + stop execution on first node in error + + + + + + + + layout9 + + + + unnamed + + + + frame3 + + + StyledPanel + + + Raised + + + + unnamed + + + + layout8 + + + + unnamed + + + + textLabel1 + + + graph status + + + AlignCenter + + + + + lab_status + + + Panel + + + Sunken + + + ready + + + AlignCenter + + + current execution status + + + + + + + + + layout4 + + + + unnamed + + + + spacer4 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + pushButton_start + + + Start/Resume + + + Start or resume execution + + + + + spacer5 + + + Horizontal + + + Expanding + + + + 21 + 20 + + + + + + + + layout3 + + + + unnamed + + + + spacer2 + + + Horizontal + + + Expanding + + + + 16 + 20 + + + + + + pushButton_pause + + + Pause + + + pause execution as soon as possible + + + + + spacer3 + + + Horizontal + + + Expanding + + + + 21 + 20 + + + + + + + + + + + + tabWidget_nodes + + + nodes status and selection + + + + tab + + + Nodes - breakpoints + + + + unnamed + + + + + Nodes + + + true + + + true + + + + + New Item + + + + + + + listView_breakpoints + + + Tree node view - select breakpoints + + + + + + + tab + + + next to run + + + + unnamed + + + + + Nodes + + + true + + + true + + + + + New Item + + + + + + + listView_nextSteps + + + + 7 + 7 + 0 + 0 + + + + list next steps - select steps to execute + + + + + + + + layout18 + + + + unnamed + + + + pushButton_stop + + + Stop + + + stop execution + + + + + spacer6 + + + Horizontal + + + Expanding + + + + 110 + 20 + + + + + + toolButton_all + + + --> + + + select all nodes to run + + + + + toolButton_remove + + + <-- + + + remove all nodes from run list + + + + + spacer7 + + + Horizontal + + + Expanding + + + + 120 + 20 + + + + + + pushButton_dismiss + + + dismiss + + + quit dialog, no effect on execution + + + + + + + + + + + chk_saveState + clicked() + runMode + onSaveState() + + + chk_stopOnError + clicked() + runMode + onStopOnError() + + + pushButton_dismiss + clicked() + runMode + onDismiss() + + + pushButton_pause + clicked() + runMode + onPause() + + + pushButton_start + clicked() + runMode + onResume() + + + pushButton_stop + clicked() + runMode + onStop() + + + toolButton_all + clicked() + runMode + onAllNextToRun() + + + rb_modeBreakpoint + clicked() + runMode + onModeBreakpoints() + + + rb_modeContinue + clicked() + runMode + onModeContinue() + + + rb_modeStepByStep + clicked() + runMode + onModeStepByStep() + + + toolButton_remove + clicked() + runMode + onRemoveAllNextToRun() + + + listView_breakpoints + clicked(QListViewItem*) + runMode + onBreakpointClicked(QListViewItem*) + + + listView_nextSteps + clicked(QListViewItem*) + runMode + onNextStepClicked(QListViewItem*) + + + + onResume() + onPause() + onStop() + onModeContinue() + onModeStepByStep() + onModeBreakpoints() + onDismiss() + onStopOnError() + onSaveState() + onAllNextToRun() + onRemoveAllNextToRun() + onBreakpointClicked(QListViewItem *item) + onNextStepClicked(QListViewItem *item) + + + diff --git a/src/gui/yacsguiloader.py b/src/gui/yacsguiloader.py new file mode 100644 index 000000000..2075e357b --- /dev/null +++ b/src/gui/yacsguiloader.py @@ -0,0 +1,22 @@ +from salomeloader import * + +from YACSGui_Swig import * + +import glob +import string + +def load(filename): + + SALOMERuntime.RuntimeSALOME_setRuntime() + + loader=SalomeLoader() + p=loader.load(filename) + + name_list = string.split(filename,"/") + name = name_list[len(name_list)-1] + p.setName(name) + + gui_swig = YACSGui_Swig() + gui_swig.displayGraph(p) + + pass diff --git a/src/lineconn2d/LineConn2d.cxx b/src/lineconn2d/LineConn2d.cxx new file mode 100755 index 000000000..b97e5369f --- /dev/null +++ b/src/lineconn2d/LineConn2d.cxx @@ -0,0 +1,66 @@ +// File: LineConn2d.cpp +// Created: 04.08.05 22:28:20 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#include + +#include +#include + +//======================================================================= +//function : Orientation +//purpose : +//======================================================================= + +LineConn2d::Orient LineConn2d::Orientation (const gp_XY& theDir) +{ + const Standard_Real aConf = Precision::Confusion(); + Orient aResult = Indefinite; + if (IsSmall (theDir.Y())) { + if (theDir.X() > aConf) + aResult = E; + else if (theDir.X() < - aConf) + aResult = W; + } else if (IsSmall (theDir.X())) { + if (theDir.Y() > aConf) + aResult = N; + else if (theDir.Y() < - aConf) + aResult = S; + } + return aResult; +} + +//======================================================================= +//function : IsIntersect +//purpose : Detect intersection between two Objects +//======================================================================= + +Standard_Boolean LineConn2d::IsIntersect (const LineConn2d_Object& anObj1, + const LineConn2d_Object& anObj2) +{ + Standard_Boolean aResult (Standard_False); + ((LineConn2d_Object&)anObj1).Update(); + ((LineConn2d_Object&)anObj2).Update(); + if (anObj1.Box().IsOut (anObj2.Box()) == Standard_False) { + LineConn2d_SegmentIterator anIter1 (anObj1); + for (; anIter1.More(); anIter1.Next()) { + const LineConn2d_Segment& aSeg1 = anIter1.Value(); + LineConn2d_SegmentIterator anIter2 (anObj2); + for (; anIter2.More(); anIter2.Next()) { + const LineConn2d_Segment& aSeg2 = anIter2.Value(); + Standard_Real anIntAlpha[2]; + if (aSeg1.IsIntersect (aSeg2, anIntAlpha)) { + aResult = Standard_True; + break; + } + } + if (anIter2.More()) + break; + } + } + return aResult; +} + + diff --git a/src/lineconn2d/LineConn2d.h b/src/lineconn2d/LineConn2d.h new file mode 100755 index 000000000..346b6e0e4 --- /dev/null +++ b/src/lineconn2d/LineConn2d.h @@ -0,0 +1,88 @@ +// File: LineConn2d.h +// Created: 04.08.05 22:26:39 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_HeaderFile +#define LineConn2d_HeaderFile + +#include + +class LineConn2d_Object; +class gp_XY; + +#ifdef __sparc +#define LineConn2d_FABS(x) ((x) < 0.? -(x) : (x)) +#else +#include +#define LineConn2d_FABS(x) ::fabs(x) +#endif + +/// Utilities +// + +class LineConn2d +{ + public: + + /** + * One of 4 possible orientations. + */ + typedef enum { + Indefinite = -1, ///< non-initialized + E = 0, ///< east + N = 1, ///< north + W = 2, ///< west + S = 3, ///< south + Indefinite1 = 4 + } Orient; + + // ---------- PUBLIC METHODS ---------- + + /** + * Test the value if it is small (absolute value is tested). + */ + inline static Standard_Boolean IsSmall (const Standard_Real theVal) + { return LineConn2d_FABS (theVal) < Precision::Confusion(); } + + /** + * Test the value for inclusion in the given interval. + * To ensure the inclusion the interval is extended by Confusion value. + * @param theVal + * the given Real value + * @param theLow + * lower bound of the interval + * @param theUp + * upper bound of the interval + * @return + * True if theVal is inside the interval inclusive. + */ + inline static Standard_Boolean IsInside (const Standard_Real theVal, + const Standard_Real theLow, + const Standard_Real theUp) + { return (theVal > theLow - Precision::Confusion() && + theVal < theUp + Precision::Confusion()); } + + /** + * Return the orientatation of the given axis. + * LineConn2d_Port can be used as subclass of the axis + */ + Standard_EXPORT static Orient Orientation (const gp_XY& aDir); + + /** + * Test intersection of two Objects. + */ + Standard_EXPORT static Standard_Boolean IsIntersect + (const LineConn2d_Object& anObj1, + const LineConn2d_Object& anObj2); + + + private: + // ---------- PRIVATE METHODS ---------- + /// Empty constructor + LineConn2d () {} + +}; + +#endif diff --git a/src/lineconn2d/LineConn2d.vcproj b/src/lineconn2d/LineConn2d.vcproj new file mode 100755 index 000000000..392a1ae2f --- /dev/null +++ b/src/lineconn2d/LineConn2d.vcproj @@ -0,0 +1,625 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/lineconn2d/LineConn2dAfx.h b/src/lineconn2d/LineConn2dAfx.h new file mode 100755 index 000000000..82513147f --- /dev/null +++ b/src/lineconn2d/LineConn2dAfx.h @@ -0,0 +1,34 @@ +// File: LineConn2d/LineConn2dAfx.h +// Created: automatically by GAWK 11.02.05 +// Author: Alexander GRIGORIEV +// Copyright: CEA 2004 + +// The purpose of this file is to create precompiled header + +#ifndef LineConn2dAfx_H +#define LineConn2dAfx_H + +#ifdef _MSC_VER + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif //_MSC_VER + +#endif + +#ifdef _MSC_VER +#pragma once +#endif + diff --git a/src/lineconn2d/LineConn2d_Box.cxx b/src/lineconn2d/LineConn2d_Box.cxx new file mode 100755 index 000000000..ca64aff3f --- /dev/null +++ b/src/lineconn2d/LineConn2d_Box.cxx @@ -0,0 +1,202 @@ +// File: LineConn2d_Box.cpp +// Created: 03.08.05 20:20:53 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#include + +#include +#include +#include +#include + +inline Standard_Boolean compareDist (const gp_XY& aHSize, const gp_XY& aDist) +{ + return (LineConn2d_FABS(aDist.X()) > aHSize.X() || + LineConn2d_FABS(aDist.Y()) > aHSize.Y()); +} + +//======================================================================= +//function : Enlarge +//purpose : +//======================================================================= + +void LineConn2d_Box::Enlarge (const Standard_Real aDiff) +{ + const Standard_Real aD = LineConn2d_FABS(aDiff); + myHSize = myHSize + gp_XY (aD, aD); +} + +//======================================================================= +//function : Limit +//purpose : limit the current box with the internals of theBox +//======================================================================= + +void LineConn2d_Box::Limit (const LineConn2d_Box& theBox) +{ + const gp_XY diffC = theBox.Center() - myCenter; + // check the condition IsOut + if (::compareDist (myHSize + theBox.HSize(), diffC) == Standard_False) { + const gp_XY diffH = theBox.HSize() - myHSize; + if (diffC.X() - diffH.X() > 0.) { + const Standard_Real aShift = 0.5 * (diffC.X() - diffH.X()); // positive + myCenter.SetX (myCenter.X() + aShift); + myHSize .SetX (myHSize.X() - aShift); + } else if (diffC.X() + diffH.X() < 0.) { + const Standard_Real aShift = 0.5 * (diffC.X() + diffH.X()); // negative + myCenter.SetX (myCenter.X() + aShift); + myHSize .SetX (myHSize.X() + aShift); + } + if (diffC.Y() - diffH.Y() > 0.) { + const Standard_Real aShift = 0.5 * (diffC.Y() - diffH.Y()); // positive + myCenter.SetY (myCenter.Y() + aShift); + myHSize .SetY (myHSize.Y() - aShift); + } else if (diffC.Y() + diffH.Y() < 0.) { + const Standard_Real aShift = 0.5 * (diffC.Y() + diffH.Y()); // negative + myCenter.SetY (myCenter.Y() + aShift); + myHSize .SetY (myHSize.Y() + aShift); + } + } +} + +//======================================================================= +//function : Add +//purpose : Update the box by a point +//======================================================================= + +void LineConn2d_Box::Add (const gp_XY& thePnt) { + if (myHSize.X() < -1e-5) { + myCenter = thePnt; + myHSize.SetCoord (0., 0.); + } else { + const gp_XY aDiff = thePnt - myCenter; + if (aDiff.X() > myHSize.X()) { + const Standard_Real aShift = (aDiff.X() - myHSize.X()) * 0.5; + myCenter.SetX (myCenter.X() + aShift); + myHSize.SetX (myHSize.X() + aShift); + } else if (aDiff.X() < -myHSize.X()) { + const Standard_Real aShift = (aDiff.X() + myHSize.X()) * 0.5; + myCenter.SetX (myCenter.X() + aShift); + myHSize.SetX (myHSize.X() - aShift); + } + if (aDiff.Y() > myHSize.Y()) { + const Standard_Real aShift = (aDiff.Y() - myHSize.Y()) * 0.5; + myCenter.SetY (myCenter.Y() + aShift); + myHSize.SetY (myHSize.Y() + aShift); + } else if (aDiff.Y() < -myHSize.Y()) { + const Standard_Real aShift = (aDiff.Y() + myHSize.Y()) * 0.5; + myCenter.SetY (myCenter.Y() + aShift); + myHSize.SetY (myHSize.Y() - aShift); + } + } +} + +//======================================================================= +//function : IsOut +//purpose : Intersection Box - Point +//======================================================================= + +Standard_Boolean LineConn2d_Box::IsOut (const gp_XY& thePnt) const +{ + return ::compareDist (myHSize, thePnt - myCenter); +} + +//======================================================================= +//function : IsOut +//purpose : Intersection Box - Box +//======================================================================= + +Standard_Boolean LineConn2d_Box::IsOut (const LineConn2d_Box& theBox) const +{ + return ::compareDist (myHSize + theBox.HSize(), theBox.Center() - myCenter); +} + +//======================================================================= +//function : IsOut +//purpose : Intersection Box - Object +//======================================================================= + +Standard_Boolean LineConn2d_Box::IsOut (const LineConn2d_Object& theObj) const +{ + Standard_Boolean aResult (Standard_True); + LineConn2d_SegmentIterator anIter (theObj); + for (; anIter.More(); anIter.Next()) + if (IsOut (anIter.Value()) == Standard_False) { + aResult = Standard_False; + break; + } + return aResult; +} + +//======================================================================= +//function : IsOut +//purpose : Intersection Box - Segment +//======================================================================= + +Standard_Boolean LineConn2d_Box::IsOut (const LineConn2d_Segment& theSeg) const +{ + Standard_Boolean aResult (Standard_True); + // Intersect the line containing the segment. + const Standard_Real aProd[3] = { + theSeg.Delta() ^ (myCenter - theSeg.Origin()), + theSeg.Delta().X() * myHSize.Y(), + theSeg.Delta().Y() * myHSize.X() + }; + if (LineConn2d_FABS(aProd[0]) < (LineConn2d_FABS(aProd[1]) + + LineConn2d_FABS(aProd[2]))) + { + // Intersection with line detected; check the segment as bounding box + const gp_XY aHSeg (0.5 * theSeg.Delta().X(), + 0.5 * theSeg.Delta().Y()); + const gp_XY aHSegAbs (LineConn2d_FABS(aHSeg.X()), + LineConn2d_FABS(aHSeg.Y())); + aResult = ::compareDist (myHSize + aHSegAbs, + theSeg.Origin() + aHSeg - myCenter); + } + return aResult; +} + +//======================================================================= +//function : Intersect +//purpose : +//======================================================================= + +Standard_Integer LineConn2d_Box::Intersect + (Standard_Real outInter[2], + const LineConn2d_Segment& theSeg) const +{ + Standard_Integer nInter (0); + Standard_Real anAlpha[2]; + // Four sides of the box rectangle + const gp_XY aSegDelta[4] = { + gp_XY (-2 * myHSize.X(), 0.), + gp_XY (0., -2 * myHSize.Y()), + gp_XY (2 * myHSize.X(), 0.), + gp_XY (0., 2 * myHSize.Y()) + }; + LineConn2d_Segment aSeg (gp_XY(0., 0.), myCenter + myHSize); + + // Intersect aSeg with all four sides of the box + for (Standard_Integer i = 0; i < 4; i++) { + aSeg.SetOrigin (aSeg.Extremity()); + aSeg.SetDelta (aSegDelta[i]); + if (theSeg.IsIntersect (aSeg, anAlpha)) { + outInter[nInter] = anAlpha[0]; + if (nInter++ > 0) { + // Check to exclude coincident intersection points + if (LineConn2d::IsSmall (outInter[0] - outInter[1])) + --nInter; + else { + if (outInter[0] > outInter[1]) { + const Standard_Real aTmp = outInter[0]; + outInter[0] = outInter[1]; + outInter[1] = aTmp; + } + break; + } + } + } + } + return nInter; +} diff --git a/src/lineconn2d/LineConn2d_Box.h b/src/lineconn2d/LineConn2d_Box.h new file mode 100755 index 000000000..8744a1eb2 --- /dev/null +++ b/src/lineconn2d/LineConn2d_Box.h @@ -0,0 +1,147 @@ +// File: LineConn2d_Box.h +// Created: 03.08.05 20:16:45 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_Box_HeaderFile +#define LineConn2d_Box_HeaderFile + +#include + +class LineConn2d_Segment; +class LineConn2d_Object; + +/// Simple class implementing 2D Bounding Box type +// + +class LineConn2d_Box +{ + public: + // ---------- PUBLIC METHODS ---------- + + /** + * Empty constructor + */ + inline LineConn2d_Box () + : myCenter (::RealLast(), ::RealLast()), + myHSize (-::RealLast(), -::RealLast()) + {} + + /** + * Constructor. + * @param theCenter + * Center of the created box + * @param theHSize + * Half-diagonal of the box, both X and Y should be non-negative + */ + inline LineConn2d_Box (const gp_XY& theCenter, + const gp_XY& theHSize) + : myCenter (theCenter), + myHSize (theHSize) {} + + /** + * Reset the box data. + */ + inline void Clear () + { + myCenter.SetCoord (::RealLast(), ::RealLast()); + myHSize .SetCoord (-::RealLast(), -::RealLast()); + } + + /** + * Update the box by a point. + */ + Standard_EXPORT void Add (const gp_XY& thePnt); + + /** + * Update the box by another box. + */ + inline void Add (const LineConn2d_Box& theBox) + { + Add (theBox.Center() - theBox.HSize()); + Add (theBox.Center() + theBox.HSize()); + } + + /** + * Query the box center. + */ + inline const gp_XY& Center () const + { return myCenter; } + + /** + * Query the box half-diagonal. + */ + inline const gp_XY& HSize () const + { return myHSize; } + + /** + * Query the square diagonal. + */ + inline Standard_Real SquareExtent () const + { return 4 * myHSize.SquareModulus(); } + + /* + * Extend the Box by the absolute value of aDiff. + */ + Standard_EXPORT void Enlarge (const Standard_Real theDiff); + + /** + * Limit the curent Box with the internals of theBox. + */ + Standard_EXPORT void Limit (const LineConn2d_Box& theBox); + + /** + * Check the given point for inclusion in the box. + * @return + * True if thePnt is outside the box. + */ + Standard_EXPORT Standard_Boolean IsOut(const gp_XY& thePnt) const; + + /** + * Check the given box for intersection with the current box. + * @return + * True if there is no intersection between the boxes. + */ + Standard_EXPORT Standard_Boolean IsOut(const LineConn2d_Box& theBox) const; + + /** + * Check the given box for intersection with an Object + * @return + * True if there is no intersection with the object theObj. + */ + Standard_EXPORT Standard_Boolean IsOut(const LineConn2d_Object& theObj) const; + + /** + * Check the given box for intersection with a segment + * @return + * True if there is no intersection with the segment aSeg. + */ + Standard_EXPORT Standard_Boolean IsOut(const LineConn2d_Segment& aSeg) const; + + /** + * Find intersection points between the boundary of the box and + * the given Segment. No intersection returned if the segment is entirely + * inside or outside the box. Therefore this method can not be used as + * replacement of the corresponding IsOut check. + * @param outInter + * Array of 2 output numbers. Contains the parameters ([0..1] inclusive) + * of intersection point(s). If 2 intersections are found, it is ensured + * that outInter[0] < outInter[1]. + * @param aSeg + * Segment for intersection. + * @return + * Number of intersections (0, 1 or 2). + */ + Standard_EXPORT Standard_Integer Intersect + (Standard_Real outInter[2], + const LineConn2d_Segment& aSeg) const; + + private: + // ---------- PRIVATE FIELDS ---------- + + gp_XY myCenter; + gp_XY myHSize; +}; + +#endif diff --git a/src/lineconn2d/LineConn2d_BoxTree.cxx b/src/lineconn2d/LineConn2d_BoxTree.cxx new file mode 100755 index 000000000..65131c38a --- /dev/null +++ b/src/lineconn2d/LineConn2d_BoxTree.cxx @@ -0,0 +1,47 @@ +// File: LineConn2d_BoxTree.cpp +// Created: 12.08.05 15:19:55 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#include + +#include +#include + +//======================================================================= +//function : LineConn2d_BoxTreeSelector +//purpose : Constructor +//======================================================================= + +LineConn2d_BoxTreeSelector::LineConn2d_BoxTreeSelector + (const LineConn2d_Segment& theSeg) +{ + myBox.Add (theSeg.Origin()); + myBox.Add (theSeg.Extremity()); +} + + +//======================================================================= +//function : Accept +//purpose : +//======================================================================= + +Standard_Boolean LineConn2d_BoxTreeSelector::Accept + (const LineConn2d_Object * const& theObj) +{ + myList.Append (theObj); + return Standard_True; +} + +//======================================================================= +//function : Reject +//purpose : +//======================================================================= + +Standard_Boolean LineConn2d_BoxTreeSelector::Reject + (const LineConn2d_Box& theBox) const +{ + return theBox.IsOut (myBox); +} + diff --git a/src/lineconn2d/LineConn2d_BoxTree.h b/src/lineconn2d/LineConn2d_BoxTree.h new file mode 100755 index 000000000..22f396987 --- /dev/null +++ b/src/lineconn2d/LineConn2d_BoxTree.h @@ -0,0 +1,66 @@ +// File: LineConn2d_BoxTree.h +// Created: 12.08.05 14:45:10 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_BoxTree_HeaderFile +#define LineConn2d_BoxTree_HeaderFile + +#include +#include +#include + +class LineConn2d_Object; + +/** + * Implementation of AABB-tree of bounding boxes for quick selection + * of entities. + */ + +typedef NCollection_UBTree + LineConn2d_BoxTree; + +/** + * Specialization of Selector class defined for NCollection_UBTree. + */ + +class LineConn2d_BoxTreeSelector : public LineConn2d_BoxTree::Selector +{ + public: + /** + * Constructor. Takes Box as parameter + */ + inline LineConn2d_BoxTreeSelector(const LineConn2d_Box& theBox) + : myBox (theBox) {} + + /** + * Constructor. Takes Segment as parameter + */ + Standard_EXPORT LineConn2d_BoxTreeSelector (const LineConn2d_Segment&); + + /** + * Query the list of elements. + */ + inline const NCollection_List& + GetObjects () const + { return myList; } + + /** + * Redefined from the base class + */ + Standard_EXPORT Standard_Boolean + Reject (const LineConn2d_Box& theBox) const; + + /** + * Redefined from the base class + */ + Standard_EXPORT Standard_Boolean + Accept (const LineConn2d_Object * const& theObj); + + protected: + NCollection_List myList; + LineConn2d_Box myBox; +}; + +#endif diff --git a/src/lineconn2d/LineConn2d_Connection.cxx b/src/lineconn2d/LineConn2d_Connection.cxx new file mode 100755 index 000000000..8f09c6e7b --- /dev/null +++ b/src/lineconn2d/LineConn2d_Connection.cxx @@ -0,0 +1,24 @@ +// File: LineConn2d_Connection.cpp +// Created: 03.08.05 21:55:54 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#include + +#include + +//======================================================================= +//function : LineConn2d_Connection() +//purpose : Constructor +//======================================================================= + +LineConn2d_Connection::LineConn2d_Connection + (const Handle(NCollection_BaseAllocator)& theAlloc, + const Standard_Integer thePort1, + const Standard_Integer thePort2) + : mySegments (theAlloc) +{ + myPort[0] = thePort1; + myPort[1] = thePort2; +} diff --git a/src/lineconn2d/LineConn2d_Connection.h b/src/lineconn2d/LineConn2d_Connection.h new file mode 100755 index 000000000..ac64d141f --- /dev/null +++ b/src/lineconn2d/LineConn2d_Connection.h @@ -0,0 +1,79 @@ +// File: LineConn2d_Connection.h +// Created: 03.08.05 21:52:02 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_Connection_HeaderFile +#define LineConn2d_Connection_HeaderFile + +#include +#include + +/// Definition of a relation between two Ports. + +class LineConn2d_Connection +{ + public: + typedef NCollection_List ::Iterator SegIterator; + + // ---------- PUBLIC METHODS ---------- + + /// Empty constructor + LineConn2d_Connection () {} + + /** + * Query the Port defined by the given index (0 or 1). + */ + inline Standard_Integer Port (const Standard_Integer i) const + { return myPort[i&0x1]; } + + /** + * Append the segment to the internal list of segments. + */ + inline void AddSegment (const LineConn2d_Segment& theSegment) + { mySegments.Append (theSegment); } + + /** + * Prepend the segment to the internal list of segments. + */ + inline void PrependSegment(const LineConn2d_Segment& theSegment) + { mySegments.Prepend (theSegment); } + + /** + * Clear all contained segments. + */ + inline void ClearSegments () + { mySegments.Clear(); } + + /** + * Query the number of contained segments. + */ + inline Standard_Integer NbSegments () const + { return mySegments.Extent(); } + + /** + * Query the list of contained segments. + */ + inline SegIterator SegmentIterator () const + { return SegIterator (mySegments); } + + protected: + // ---------- PROTECTED METHODS ---------- + + /// Constructor + Standard_EXPORT LineConn2d_Connection + (const Handle_NCollection_BaseAllocator& theAlloc, + const Standard_Integer thePort1, + const Standard_Integer thePort2); + + private: + // ---------- PRIVATE FIELDS ---------- + + Standard_Integer myPort[2]; + NCollection_List mySegments; + + friend class LineConn2d_Model; +}; + +#endif diff --git a/src/lineconn2d/LineConn2d_IntervalBuffer.cxx b/src/lineconn2d/LineConn2d_IntervalBuffer.cxx new file mode 100755 index 000000000..84c8d0a66 --- /dev/null +++ b/src/lineconn2d/LineConn2d_IntervalBuffer.cxx @@ -0,0 +1,243 @@ +// File: LineConn2d_IntervalBuffer.cpp +// Created: 21.02.05 15:54:12 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#include + +#include +#include +#include + +#include + +//======================================================================= +//function : Add +//purpose : adding one interval to the buffer +//======================================================================= + +void LineConn2d_IntervalBuffer::Add (const LineConn2d_ZInterval& theInterval) +{ + LineConn2d_ZInterval * anInt[2] = {0L, 0L}; // the inserted and the previous + + // Scan the collection and find the available interval that is greater than + // the given one, then insert the given one before the found interval. + NCollection_List::Iterator anIter (myIntervals); + for (; anIter.More(); anIter.Next()) { + const Standard_Real anXint = anIter.Value().myX[1]; + if (theInterval.myX[1] < anXint) { + anInt[0] = &myIntervals.InsertBefore (theInterval, anIter); + break; + } + anInt[1] = &anIter.ChangeValue(); + } + // The given interval is to be appended as the last one in the collection. + if (anInt[0] == 0L) { + if (myIntervals.IsEmpty() == Standard_False) + anInt[1] = (LineConn2d_ZInterval *) &myIntervals.Last(); + anInt[0] = &myIntervals.Append (theInterval); + } + // Now merge the added interval with all relevant ones already available. + if (anInt[1]) + Cut (anInt); // merge with the previous + for (; anIter.More() && anInt[0]; anIter.Next()) { + anInt[1] = &anIter.ChangeValue(); + anInt[0] = Cut (anInt); // merge with the next + } +} + +//======================================================================= +//function : Cut +//purpose : merge two intervals +//======================================================================= + +LineConn2d_ZInterval * LineConn2d_IntervalBuffer::Cut + (LineConn2d_ZInterval * theInt[2]) +{ + const Standard_Real aTol = Precision::Confusion(); + LineConn2d_ZInterval * aResult = 0L; + // test for intersection + if (theInt[0]->myX[1] - theInt[1]->myX[0] > aTol && + theInt[1]->myX[1] - theInt[0]->myX[0] > aTol) + { + Standard_Integer iLow = (theInt[0]->Z() < theInt[1]->Z()) ? 0 : 1; + LineConn2d_ZInterval& anIntLow = * theInt[iLow]; + LineConn2d_ZInterval& anIntUp = * theInt[1-iLow]; + // there is intersection, now find the intersection interval + Standard_Integer aTest = 0; + if (anIntUp.myX[0] > anIntLow.myX[0] + Precision::Confusion()) + aTest = 0x2; + if (anIntUp.myX[1] > anIntLow.myX[1] - Precision::Confusion()) + aTest |= 0x1; +// Now the value aTest is this: +// 00 IntUp |----------| +// IntLow |-----------| +// +// 11 IntUp |----------| +// IntLow |-----------| +// +// 10 IntUp |---| +// IntLow |--------------| +// +// 01 IntUp |--------------| +// IntLow |---| + + switch (aTest) { + case 0x0: + anIntLow.myX[0] = anIntUp.myX[1]; + if (iLow == 0) + aResult = theInt[0]; + break; + case 0x1: { + NCollection_List::Iterator anIter (myIntervals); + for (; anIter.More(); anIter.Next()) + if (anIntLow == anIter.Value()) { + myIntervals.Remove (anIter); + break; + } + if (iLow == 1) + aResult = theInt[0]; + break; + } + case 0x2: { + LineConn2d_ZInterval aNewInterval (anIntLow.Z(), + anIntLow.myX[0], anIntUp.myX[0]); + anIntLow.myX[0] = anIntUp.myX[1]; + aNewInterval.SetAttribute (anIntLow.Attribute()); + Add (aNewInterval); + break; + } + case 0x3: + anIntLow.myX[1] = anIntUp.myX[0]; + if (iLow == 1) + aResult = theInt[0]; + break; + } + } + return aResult; +} + +//======================================================================= +//function : GetPolyline +//purpose : +//======================================================================= + +void LineConn2d_IntervalBuffer::GetPolyline (LineConn2d_ListOfXY& outLine, + const Standard_Real theLim[2])const +{ + outLine.Clear(); + NCollection_List::Iterator anIter (myIntervals); + for (; anIter.More(); anIter.Next()) { + const LineConn2d_ZInterval& anInterval = anIter.Value(); + //const Standard_Real aZ = anInterval.Z(); + Standard_Real anX[2] = { anInterval.X(0), anInterval.X(1) }; + if (anX[0] < theLim[1] - Precision::Confusion() && + anX[1] > theLim[0] + Precision::Confusion()) + { + if (anX[0] < theLim[0]) anX[0] = theLim[0]; + if (anX[1] > theLim[1]) anX[1] = theLim[1]; + outLine.Append (gp_XY (anX[0], anInterval.Z())); + outLine.Append (gp_XY (anX[1], anInterval.Z())); + } + } +} + +//======================================================================= +//function : GetMinima +//purpose : +//======================================================================= + +void LineConn2d_IntervalBuffer::GetMinima (LineConn2d_ListOfReal& outList, + const Standard_Real theTol) const +{ + outList.Clear(); + if (myIntervals.Extent() < 2) + return; + //const Standard_Real aConf = Precision::Confusion(); + NCollection_List::Iterator anIter (myIntervals); + Standard_Real aZ[3] = {0., 0., 1.}; // the history of Z along the buffer + Standard_Integer aCount (0); + const LineConn2d_ZInterval * aPrevInt = 0L; + for (; anIter.More(); anIter.Next()) { + const LineConn2d_ZInterval& anInterval = anIter.Value(); + if (anInterval.X(1) - anInterval.X(0) < theTol) + continue; + if (aCount++ == 0) { + // Initialize the history buffer + aZ[1] = ::RealLast(); + aZ[2] = anInterval.Z(); + aPrevInt = &anInterval; + continue; + } else { + aZ[0] = aZ[1]; + aZ[1] = aZ[2]; + aZ[2] = anInterval.Z(); + } + if (aZ[1] < aZ[0] && aZ[1] < aZ[2]) + outList.Append ((aPrevInt->X(0) + aPrevInt->X(1)) * 0.5); + aPrevInt = &anInterval; + } + if (aZ[2] < aZ[1]) + outList.Append ((aPrevInt->X(0) + aPrevInt->X(1)) * 0.5); +} + +//======================================================================= +//function : Dump +//purpose : +//======================================================================= + +void LineConn2d_IntervalBuffer::Dump (Standard_OStream& theStream, + const Standard_Real theTol) const +{ + theStream << " === Dump of buffer ( " << myIntervals.Extent() + << " intervals)" << endl; + NCollection_List::Iterator anIter (myIntervals); + for (; anIter.More(); anIter.Next()) { + const LineConn2d_ZInterval& anInt = anIter.Value(); + char buf[120]; + sprintf (buf, "(%8.4f, %8.4f) Z = %.8g", + anInt.X(0), anInt.X(1), anInt.Z()); + theStream << buf << endl; + } + LineConn2d_ListOfReal lst; + GetMinima (lst, theTol); + LineConn2d_ListOfReal::Iterator anIter1 (lst); + if (anIter1.More()) { + theStream << "Minima:"; + for (; anIter1.More(); anIter1.Next()) + theStream << ' ' << anIter1.Value(); + theStream << endl; + } +} + +//======================================================================= +//function : CheckBuffer +//purpose : +//======================================================================= + +void LineConn2d_IntervalBuffer::CheckBuffer () { + // test the consistency of the buffer + LineConn2d_ZInterval * anInt[2] = {0L, 0L}; // the inserted and the previous + for (Standard_Boolean isKO = Standard_True; isKO;) { + isKO = Standard_False; + NCollection_List::Iterator anIter (myIntervals); + anInt[1] = (LineConn2d_ZInterval *) &anIter.Value(); + for (anIter.Next(); anIter.More(); anIter.Next()) { + if (anIter.Value().myX[1] < anInt[1]->myX[0] + Precision::Confusion()) { + LineConn2d_ZInterval aTmp = anIter.Value(); + myIntervals.Remove (anIter); + Add (aTmp); + isKO = Standard_True; + break; + } + if (anInt[1]->myX[1] > anIter.Value().myX[0] + Precision::Confusion()) { + anInt[0] = (LineConn2d_ZInterval *) &anIter.Value(); + Cut (anInt); + isKO = Standard_True; + break; + } + anInt[1] = (LineConn2d_ZInterval *) &anIter.Value(); + } + } +} diff --git a/src/lineconn2d/LineConn2d_IntervalBuffer.h b/src/lineconn2d/LineConn2d_IntervalBuffer.h new file mode 100755 index 000000000..0ff680677 --- /dev/null +++ b/src/lineconn2d/LineConn2d_IntervalBuffer.h @@ -0,0 +1,87 @@ +// File: LineConn2d_IntervalBuffer.hxx +// Created: 21.02.05 14:38:12 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_IntervalBuffer_HeaderFile +#define LineConn2d_IntervalBuffer_HeaderFile + +#include +#include +#include + +typedef NCollection_List LineConn2d_ListOfXY; +typedef NCollection_List LineConn2d_ListOfReal; + +/** + * Buffer to store an outline of horizontal segments (intervals) in XOZ, each + * inteval defining its Z coordinate and extremities X(0) and X(1). The result + * can be obtained as sequence of points to create a polyline. + */ + +class LineConn2d_IntervalBuffer +{ + public: + // ---------- PUBLIC METHODS ---------- + + /// Empty constructor + LineConn2d_IntervalBuffer (const Handle(NCollection_BaseAllocator)& A) + : myIntervals (A) {} + + /// Query if the buffer contains 1 or more intervals. + inline Standard_Boolean IsEmpty () const + { return myIntervals.IsEmpty(); } + + /// Add an interval + Standard_EXPORT void Add (const LineConn2d_ZInterval& theInterval); + + /// Extract polyline from the buffer, between X coordinates + /// theLim[0] and theLim[1] + Standard_EXPORT void GetPolyline (LineConn2d_ListOfXY& outLine, + const Standard_Real theLim[2]) const; + + /// Extract the list of local minima of the outline, with each minimum + /// being wider than theTol. + Standard_EXPORT void GetMinima (LineConn2d_ListOfReal& outList, + const Standard_Real theTol) const; + + Standard_EXPORT void Dump (Standard_OStream& theStream, + const Standard_Real)const; + + Standard_EXPORT void CheckBuffer(); + + private: + // ---------- PRIVATE (PROHIBITED) METHODS ---------- + + /// Copy constructor + LineConn2d_IntervalBuffer (const LineConn2d_IntervalBuffer& theOther); + + /// Assignment + LineConn2d_IntervalBuffer& operator = (const LineConn2d_IntervalBuffer&); + + protected: + // ---------- PROTECTED METHODS ---------- + + /** + * Test if theOther interval is intersected. If so, one of the intervals is + * cut by the other; the cutting interval is the one with the greater Z. See + * the source file LineConn2d_IntervalBuffer.cpp for this method definition. + * This method should only be called with both arguments being members of + * the collection myIntervals. + * @param theInt + * theInt[0] - newly added interval; theInt[1] - a previous interval. + * @return + * Pointer to the interval that should be checked with the following + * intervals in the buffer. + */ + LineConn2d_ZInterval * Cut (LineConn2d_ZInterval * theInt[2]); + + private: + // ---------- PRIVATE FIELDS ---------- + + NCollection_List myIntervals; +}; + + +#endif diff --git a/src/lineconn2d/LineConn2d_Model.cxx b/src/lineconn2d/LineConn2d_Model.cxx new file mode 100755 index 000000000..3ed40b765 --- /dev/null +++ b/src/lineconn2d/LineConn2d_Model.cxx @@ -0,0 +1,501 @@ +// File: LineConn2d_Model.cpp +// Created: 03.08.05 21:05:54 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + +#include + +#include +#include +#include +#include +#include + +#ifdef DEB +#include +#endif + +//======================================================================= +//function : LineConn2d_Model +//purpose : Empty constructor +//======================================================================= + +LineConn2d_Model::LineConn2d_Model () + : myAlloc (new NCollection_IncAllocator()), + myTree (new NCollection_IncAllocator()), + myTolerance (10 * Precision::Confusion()), + myPortLength (0.), + mySearchDepth (2.) +{ + myObjects.Append (LineConn2d_Object()); + myConnections.Append (LineConn2d_Connection()); + myPorts.Append (LineConn2d_Port()); +} + +//======================================================================= +//function : AddObject +//purpose : +//======================================================================= + +Standard_Integer LineConn2d_Model::AddObject () +{ + const Standard_Integer anInd = myObjects.Length(); + myObjects.Append (LineConn2d_Object (myAlloc)); + return anInd; +} + +//======================================================================= +//function : AddPort +//purpose : +//======================================================================= + +Standard_Integer LineConn2d_Model::AddPoort (const Standard_Integer iObj, + const gp_XY& thePnt, + const gp_Dir2d& theDir) +{ + Standard_Integer aResult (0); + if (iObj > 0 && iObj < myObjects.Length()) { + aResult = myPorts.Length(); + myPorts.Append (LineConn2d_Port (myObjects(iObj), thePnt, theDir)); + } + return aResult; +} + +//======================================================================= +//function : AddConnection +//purpose : +//======================================================================= + +Standard_Integer LineConn2d_Model::AddConnection (const Standard_Integer iPort1, + const Standard_Integer iPort2) +{ + Standard_Integer aResult (0); + const Standard_Integer nPorts = myPorts.Length(); + if (iPort1 > 0 && iPort1 < nPorts && + iPort2 > 0 && iPort2 < nPorts) { + aResult = myConnections.Length(); + myConnections.Append (LineConn2d_Connection (myAlloc, + iPort1, + iPort2)); + } + return aResult; +} + +//======================================================================= +//function : Update +//purpose : +//======================================================================= + +void LineConn2d_Model::Update () +{ + myTree.Clear(); + NCollection_UBTreeFiller + aTreeFiller(myTree); + + // skipping the 0th member; update the objects and fill the tree. + NCollection_Vector ::Iterator anIter (myObjects); + for (anIter.Next(); anIter.More(); anIter.Next()) { + LineConn2d_Object& anObj = anIter.ChangeValue(); + anObj.Update(); + aTreeFiller.Add (&anObj, anObj.Box()); + } + aTreeFiller.Fill(); + + _PortLen = LineConn2d::IsSmall (myPortLength)? 2 * myTolerance : myPortLength; + myTreeBox = myTree.Root().Bnd(); + // Update the box with all ports in the model + NCollection_Vector ::Iterator anIterP (myPorts); + for (anIterP.Next(); anIterP.More(); anIterP.Next()) + myTreeBox.Add (anIterP.Value().Location().XY() + + anIterP.Value().Direction().XY() * _PortLen); + myTreeBox.Enlarge (myTolerance + 10 * Precision::Confusion()); +} + +//======================================================================= +//function : HalfPerimeter +//purpose : +//======================================================================= + +Standard_Real LineConn2d_Model::HalfPerimeter () const +{ + const LineConn2d_Box& aBox = myTree.Root().Bnd(); + return 2 * (aBox.HSize().X() + aBox.HSize().Y()); +} + +//======================================================================= +//function : TempAlloc +//purpose : +//======================================================================= + +const Handle(NCollection_BaseAllocator)& LineConn2d_Model::TempAlloc () const +{ + if (myTempAlloc.IsNull()) + ((Handle(NCollection_IncAllocator)&) myTempAlloc) = + new NCollection_IncAllocator(); + return myTempAlloc; +} + +//======================================================================= +//function : Compute +//purpose : +//======================================================================= + +Standard_Boolean LineConn2d_Model::Compute () +{ + Update(); + + const Standard_Integer nConn = myConnections.Length(); + for (Standard_Integer iConn = 1; iConn < nConn; iConn++) { + LineConn2d_Connection& aConn = myConnections(iConn); + const LineConn2d_Port& aPortSrc = myPorts (aConn.Port(0)); + const LineConn2d_Port& aPortTgt = myPorts (aConn.Port(1)); + // Check the ports if any of them is included into other objects + if (checkPort (aPortSrc) == Standard_False || + checkPort (aPortTgt) == Standard_False) + continue; + + _PntTgt = gp_XY (aPortTgt.Location().XY() + + _PortLen * aPortTgt.Direction().XY()); + _SegTgtPort = LineConn2d_Segment (aPortTgt.Location().XY(), _PntTgt); + + // Create the root path (a short segment from the first port) + LineConn2d_Path aPathRoot; + LineConn2d::Orient anOrient = + LineConn2d::Orientation (aPortSrc.Direction().XY()); + if (!LineConn2d_Path::createPath (aPathRoot, * this, + aPortSrc.Location().XY(), anOrient, + Standard_True)) + continue; + if (aPathRoot.Delta().Modulus() < _PortLen) + continue; + aPathRoot.SetDelta (aPathRoot.Direction() * _PortLen); + aPathRoot.Evaluate (_PntTgt); + + const Standard_Integer aMaxDepthIncr = + Standard_Integer (mySearchDepth * LineConn2d_Path::PriceOfBreak()); + const Standard_Integer anUltimateDepth = aMaxDepthIncr * 3; + Standard_Integer aMaxDepth = aMaxDepthIncr; + + // Create three branches near the beginning of the first Path. + const gp_XY aPntExt = aPathRoot.Extremity(); + createPath (aPathRoot, aPntExt, -1); + createPath (aPathRoot, aPntExt, 0); + createPath (aPathRoot, aPntExt, 1); + + // Calculation loop. + Standard_Boolean isNewPath (Standard_True); + Standard_Integer aMinPrice (::IntegerLast()); + Standard_Integer aCurPrice (::IntegerLast()); + const LineConn2d_Path * aMinPricedPath = 0L; + + while (isNewPath) { + isNewPath = Standard_False; + // Evaluate the minimal price over all the leaves + LineConn2d_PathIterator aPathIter (aPathRoot, TempAlloc()); + while (aPathIter.More()) { + const LineConn2d_Path& aPath = aPathIter.Value(); + Standard_Integer aPathPrice = aPath.Price(); + // Correct the price for the terminating path if it makes an angle + // with the port direction. + if (aPath.IsComplete()) { + if (LineConn2d::IsSmall (aPath.Direction() ^ + aPortTgt.Direction().XY()) == Standard_False) + aPathPrice += LineConn2d_Path::PriceOfBreak(); + } + if (aPathPrice < aCurPrice) + aCurPrice = aPathPrice; + if (aPath.IsComplete() && aPathPrice < aMinPrice) { + aMinPrice = aPathPrice; + aMinPricedPath = &aPath; + } + aPathIter.Next(); + } + + // Create new path elements + aPathIter = LineConn2d_PathIterator (aPathRoot, TempAlloc()); + aPathIter.SetDepthLimit (20); + while (aPathIter.More()) { + LineConn2d_Path& aPath = aPathIter.Value(); + aPathIter.Next(); + const Standard_Integer aPrice = aPath.Price(); + if (aPrice < aMinPrice && aPrice < aCurPrice + aMaxDepth && + !aPath.IsComplete ()) + { + // Create new paths + gp_XY aProjPnt; + if (aPath.ProjectPoint (aProjPnt, _PntTgt)) { + // The target is projected on this path. Create a NEW SUB-PATH + // IN THE PROJECTION point. If this path does not reach the PntTgt, + // it is abandoned (not included). + if ((aProjPnt - aPath.Origin()).Modulus() > myTolerance) + if (createPath (aPath, aProjPnt, 100)) + isNewPath = Standard_True; + } + if (aPath.Limitation() >= 0) { + // limitation front or right => create the NEW PATH TO THE LEFT + if (createPath (aPath, aPath.Extremity(), -1)) + isNewPath = Standard_True; + } + if (aPath.Limitation() <= 0) { + // limitation front or left => create the NEW PATH TO THE RIGHT + if (createPath (aPath, aPath.Extremity(), 1)) + isNewPath = Standard_True; + } + // Create the outline on both sides, find the extrema + gp_XY aPathDir = aPath.Direction(); + NCollection_List lstOut (myTempAlloc); + for (Standard_Integer iSide = -1; iSide < 2; iSide += 2) { + pathOutline (lstOut, aPath, iSide); + NCollection_List::Iterator anIterOut (lstOut); + for (; anIterOut.More(); anIterOut.Next()) { + const gp_XY aPnt = aPath.Point (anIterOut.Value()); + // Check against the point proximity to the path start or end + if ((aPnt - aPath.Origin()) * aPathDir > myTolerance * 1.2 && + (aPath.Extremity() - aPnt) * aPathDir > myTolerance * 1.2) + { + if (createPath (aPath, aPnt, iSide)) + isNewPath = Standard_True; + } + } + } // end for(.. iSide ..) + } + } // end while (aPathIter) + if (isNewPath == Standard_False && aMinPricedPath == 0L) { + if (aMaxDepth < anUltimateDepth) { + aMaxDepth += aMaxDepthIncr; + isNewPath = Standard_True; + } + } + } + // Copy the result to the current Connection + const LineConn2d_Path * aPath = aMinPricedPath; + if (aPath) { + aConn.ClearSegments(); + gp_XY aPathPoint = aPath->Extremity(); + aConn.AddSegment (LineConn2d_Segment (aPathPoint, + aPortTgt.Location().XY())); + for (; aPath; aPath = &aPath -> Parent()) { + aConn.PrependSegment (LineConn2d_Segment (aPath->Origin(), aPathPoint)); + aPathPoint = aPath->Origin(); + } + } + myTempAlloc.Nullify(); // clear the temporary data storage + } + return Standard_True; // OK +} + +//======================================================================= +//function : pathOutline +//purpose : Find the maximal points on the model outline on the given +// side of the current path +//======================================================================= + +void LineConn2d_Model::pathOutline (NCollection_List& outList, + const LineConn2d_Path thePath, + const Standard_Integer theSide) +{ + const gp_XY aModelSize = 2 * Box().HSize(); + const Standard_Real aConf (Precision::Confusion()); + gp_XY aPntExtr = thePath.Extremity(); + Standard_Real aRelTol (0.); + + // Create the box for the transversal band covering the whole length + // of the path + LineConn2d_Box anOutBox; + const gp_XY aCenterPath = (thePath.Origin() + aPntExtr) * 0.5; + switch (thePath.Orientation()) { + case LineConn2d::E: + anOutBox = LineConn2d_Box (aCenterPath + + gp_XY (0., -theSide * aModelSize.Y()), + gp_XY (thePath.Delta().X() * 0.5 + aConf, + aModelSize.Y())); + aRelTol = myTolerance / thePath.Delta().X(); + break; + case LineConn2d::W: + anOutBox = LineConn2d_Box (aCenterPath + + gp_XY (0., theSide * aModelSize.Y()), + gp_XY (-thePath.Delta().X() * 0.5 + aConf, + aModelSize.Y())); + aRelTol = -myTolerance / thePath.Delta().X(); + break; + case LineConn2d::N: + anOutBox = LineConn2d_Box (aCenterPath + + gp_XY (theSide * aModelSize.X(), 0.), + gp_XY (aModelSize.X(), + thePath.Delta().Y() * 0.5 + aConf)); + aRelTol = myTolerance / thePath.Delta().Y(); + break; + case LineConn2d::S: + anOutBox = LineConn2d_Box (aCenterPath + + gp_XY (-theSide * aModelSize.X(), 0.), + gp_XY (aModelSize.X(), + -thePath.Delta().Y() * 0.5 + aConf)); + aRelTol = -myTolerance / thePath.Delta().Y(); + break; + } + + // Create the interval buffer and add there the baseline + LineConn2d_IntervalBuffer aZBuffer (myTempAlloc); + aZBuffer.Add (LineConn2d_ZInterval (-::RealLast(), 0., 1.)); + + // Select and iterate the boxes for model objects + LineConn2d_BoxTreeSelector aSelBox (anOutBox); + myTree.Select (aSelBox); + NCollection_List::Iterator + aSelBoxIter (aSelBox.GetObjects()); + for (; aSelBoxIter.More(); aSelBoxIter.Next()) { + const LineConn2d_Box& aBox = aSelBoxIter.Value() -> Box(); + // X[0] - coordinate of box start (normalized and relative to the path) + // X[1] - coordinate of box start (normalized and relative to the path) + // X[2] - Z-coordinate to be stored in Z-buffer + // (nearest to the path is the greatest) + Standard_Real anX[3]; + switch (thePath.Orientation()) { + case LineConn2d::E: + anX[0] = (aBox.Center().X() - aBox.HSize().X() + - thePath.Origin().X()) / thePath.Delta().X(); + anX[1] = (aBox.Center().X() + aBox.HSize().X() + - thePath.Origin().X()) / thePath.Delta().X(); + anX[2] = theSide * aBox.Center().Y() + aBox.HSize().Y(); + break; + case LineConn2d::N: + anX[0] = (aBox.Center().Y() - aBox.HSize().Y() + - thePath.Origin().Y()) / thePath.Delta().Y(); + anX[1] = (aBox.Center().Y() + aBox.HSize().Y() + - thePath.Origin().Y()) / thePath.Delta().Y(); + anX[2] = -theSide * aBox.Center().X() + aBox.HSize().X(); + break; + case LineConn2d::W: + anX[0] = (aBox.Center().X() + aBox.HSize().X() + - thePath.Origin().X()) / thePath.Delta().X(); + anX[1] = (aBox.Center().X() - aBox.HSize().X() + - thePath.Origin().X()) / thePath.Delta().X(); + anX[2] = -theSide * aBox.Center().Y() + aBox.HSize().Y(); + break; + case LineConn2d::S: + anX[0] = (aBox.Center().Y() + aBox.HSize().Y() + - thePath.Origin().Y()) / thePath.Delta().Y(); + anX[1] = (aBox.Center().Y() - aBox.HSize().Y() + - thePath.Origin().Y()) / thePath.Delta().Y(); + anX[2] = theSide * aBox.Center().X() + aBox.HSize().X(); + break; + default: + continue; + } + // Assertion check + if (aRelTol < Precision::Confusion() || anX[1] < anX[0]) + Standard_ProgramError::Raise (__FILE__); + if (anX[0] < 0.) anX[0] = 0.; + if (anX[1] > 1.) anX[1] = 1.; + if (anX[1] - anX[0] < aRelTol) + continue; + + aZBuffer.Add (LineConn2d_ZInterval (anX[2], anX[0], anX[1])); + } // end iteration on the model selected boxes + aZBuffer.CheckBuffer(); + aZBuffer.GetMinima (outList, aRelTol); + +// filebuf aFileBuf; +// if (aFileBuf.open("LineConn2d_Path.trace", ios::out|ios::app)) +// aZBuffer.Dump (ostream(&aFileBuf), aRelTol); +// aFileBuf.close(); +} + +//======================================================================= +//function : createPath +//purpose : +//======================================================================= + +Standard_Boolean LineConn2d_Model::createPath + (LineConn2d_Path& thePath, + const gp_XY& theStart, + const Standard_Integer iSide) const +{ + // Compute the orientation for the new path, taking into account the Side + LineConn2d::Orient anOrient; + Standard_Boolean isSearchTerm (Standard_False); + if (iSide > -2 && iSide < 2) + anOrient = thePath.Orientation (iSide); + else { + // the orientation is not on the side, it is directed to the target + isSearchTerm = Standard_True; + anOrient = LineConn2d::Orientation (_PntTgt - theStart); + } + + LineConn2d_Path aNewPath; + const Standard_Boolean aResult = + LineConn2d_Path::createPath (aNewPath, * this, theStart, anOrient, + Standard_False); + if (aResult) { + gp_XY aProjPnt; + if (aNewPath.ProjectPoint (aProjPnt, _PntTgt)) + if ((aProjPnt - _PntTgt).SquareModulus() < Precision::Confusion()) + aNewPath.SetExtremity (aProjPnt); + else { + if (isSearchTerm) + return Standard_False; + // Check that the created path does not intersect the target port + // segment; if so, abandon the path. + Standard_Real bidAlpha[2]; + if (_SegTgtPort.IsIntersect (aNewPath, bidAlpha)) + return Standard_False; + } + thePath.AddBranch (aNewPath, _PntTgt); + +#ifdef DEBB + static FILE * ff = NULL; + static int ccc = 0; + ff = fopen ("LineConn2d_Path.trace",ff ? "at" : "wt"); + + const gp_XY anExtr = aNewPath.Extremity(); + const LineConn2d_Path * aPath = &thePath; + Standard_Integer aDepth (0); + for (; aPath; aPath = &aPath->Parent()) + aDepth++; + const gp_XY anExP = thePath.Extremity(); + + fprintf (ff, "2dprofile pp%d F %.7g %.7g TT %.7g %.7g W # %c%5d\n", + ++ccc ,aNewPath.Origin().X(),aNewPath.Origin().Y(), + anExtr.X(),anExtr.Y(), aNewPath.IsComplete() ? 'C' : '.', + aNewPath.Price()); +// fprintf (ff, +// "=> (%6.1f %6.1f) - (%6.1f %6.1f), Lim %3d, Depth %3d, Price%4d\n", +// aNewPath.Origin().X(),aNewPath.Origin().Y(),anExtr.X(),anExtr.Y(), +// aNewPath.Limitation(), aDepth, aNewPath.Price()); + +// fprintf (ff, +// " [%6.1f %6.1f] - [%6.1f %6.1f], Lim %3d, Price%4d\n", +// thePath.Origin().X(), thePath.Origin().Y(), anExP.X(),anExP.Y(), +// thePath.Limitation(), thePath.Price()); + + fclose (ff); +#endif + } + return aResult; +} + +//======================================================================= +//function : checkPort +//purpose : +//======================================================================= + +Standard_Boolean LineConn2d_Model::checkPort + (const LineConn2d_Port& thePort) const +{ + Standard_Boolean aResult (Standard_True); + const gp_XY aPnt [2] = { + thePort.Location().XY(), + thePort.Location().XY() + _PortLen * thePort.Direction().XY() + }; + + for (Standard_Integer i = 1; i < myObjects.Length(); i++) { + const LineConn2d_Object& anObj = myObjects(i); + if (&anObj == &thePort.Object()) // skip checking the self + continue; + if (anObj.IsOut (aPnt[1], myTolerance) == Standard_False) { + aResult = Standard_False; + break; + } + } + return aResult; +} diff --git a/src/lineconn2d/LineConn2d_Model.h b/src/lineconn2d/LineConn2d_Model.h new file mode 100755 index 000000000..c5ed37263 --- /dev/null +++ b/src/lineconn2d/LineConn2d_Model.h @@ -0,0 +1,309 @@ +// File: LineConn2d_Model.h +// Created: 03.08.05 20:08:48 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_Model_HeaderFile +#define LineConn2d_Model_HeaderFile + +#include +#include +#include +#include +#include + +#include + +class LineConn2d_Path; + +/// Data Model for Line Connection algorithm. + +class LineConn2d_Model +{ + public: + // ---------- PUBLIC METHODS ---------- + + /// Empty constructor + Standard_EXPORT LineConn2d_Model (); + + /// Destructor +// Standard_EXPORT virtual ~LineConn2d_Model (); + + /** + * Create a new Object in the model. This is the exclusive way to create + * new objects. + * @return + * the index of the new object, always positive + */ + Standard_EXPORT Standard_Integer AddObject (); + + /** + * Create a new Port in the model. This method checks the validity of + * indices provided as parameters. It is the exclusive way to create + * new ports. + * @remark + * Thanks to Windows Platform SDK, AddPort is a kinda reserved word, we + * others cannot use it as identifier. So the method name is not mistyped. + * @return + * the index of the new Port, always positive or 0 on error. + */ + Standard_EXPORT Standard_Integer AddPoort (const Standard_Integer iObj, + const gp_XY& thePnt, + const gp_Dir2d& theDir); + + /** + * Create a new Connection in the model. This method checks the validity of + * indices provided as parameters. + * @param iPort1 + * index of the first Port + * @param iPort2 + * index of the second Port + * @return + * index of the new Connection (always positive) or 0 on error. + */ + Standard_EXPORT Standard_Integer AddConnection(const Standard_Integer iPort1, + const Standard_Integer iPort2); + + /** + * Query of the i-th Connection in the Model. You should be careful to provide + * a correct parameter value. + * @param i + * index of the object, in the range 1 .. NbConnections inclusive + * @return + * const Connection reference + */ + inline const LineConn2d_Connection& operator()(const Standard_Integer i) const + { return myConnections(i); } + + /** + * Query of the i-th Connection in the Model, non-const interface. + * You should be careful to provide a correct parameter value. + * @param i + * index of the object, in the range 1 .. NbConnections() inclusive + * @return + * Connection reference + */ + inline LineConn2d_Connection& operator() (const Standard_Integer i) + { return myConnections(i); } + + /** + * Query the i-th Object in the Model (const interface). + * You should be careful to provide a correct parameter value. + * @param i + * index of the object, in the range 1 .. NbObjects() inclusive + * @return + * const Object reference + */ + inline const LineConn2d_Object& Object (const Standard_Integer i) const + { return myObjects(i); } + + /** + * Query the i-th Object in the Model. + * You should be careful to provide a correct parameter value. + * @param i + * index of the object, in the range 1 .. NbObjects() inclusive + * @return + * Object reference + */ + inline LineConn2d_Object& ChangeObject(const Standard_Integer i) + { return myObjects(i); } + + /** + * Query the i-th Port in the Model (const interface). + * You should be careful to provide a correct parameter value. + * @param i + * index of the object, in the range 1 .. NbPorts() inclusive + * @return + * const Port reference + */ + inline const LineConn2d_Port& Port (const Standard_Integer i) const + { return myPorts(i); } + + /** + * Query the i-th Port in the Model. + * You should be careful to provide a correct parameter value. + * @param i + * index of the object, in the range 1 .. NbPorts() inclusive + * @return + * Port reference + */ + inline LineConn2d_Port& ChangePort (const Standard_Integer i) + { return myPorts(i); } + + /** + * Query the number of currently stored objects. + */ + inline Standard_Integer NbObjects () const + { return myObjects.Length() - 1; } + + /** + * Query the number of currently stored objects. + */ + inline Standard_Integer NbPorts () const + { return myPorts.Length() - 1; } + + /** + * Query the number of currently stored connections. + */ + inline Standard_Integer NbConnections () const + { return myConnections.Length() - 1; } + + /** + * Set the Tolerance value. + */ + inline void SetTolerance (const Standard_Real theTol) + { myTolerance = theTol; } + + /** + * Query the Tolerance value. + */ + inline Standard_Real Tolerance () const + { return myTolerance; } + + /** + * Set the port length parameter. By default it is equal to 2 * Tolerance(). + */ + inline void SetPortLength (const Standard_Real theLen) + { myPortLength = theLen; } + + /** + * Sets the value of mySearchDepth. The lower this value, the faster the + * calculations, though for some connections the process may fail due to + * not enough search depth allowed. Roughly, this parameter means the number + * of breaks (direction changes) above the minimal, allowed for each branch + * to propagate with new paths. + *

The default value of this parameter is 4. + */ + inline void SetSearchDepth(const Standard_Real theDep) + { mySearchDepth = ::Max (0.1, theDep); } + + /** + * Query the Tree structure. Should be called after Update(). + */ + inline const LineConn2d_BoxTree& GetTree () const + { return myTree; } + + /** + * Update the internal structures (including those of each contained Object) + * when all data have been loaded. + */ + Standard_EXPORT void Update (); + + /** + * Query the bounding box of the Model. Should be called after Update(). + */ + inline const LineConn2d_Box& Box () const + { return myTreeBox; } + + /** + * Query the sum of the width and the height of the Model Box. + */ + Standard_EXPORT Standard_Real HalfPerimeter () const; + + /** + * Query the allocator for temporary data. This allocator should be used + * ONLY from the code called in Compute(); the allocator is destroyed in + * the end of Compute, so please take care that no references to any + * allocated objects are propagated at the moment when Compute() terminates. + */ + Standard_EXPORT const Handle_NCollection_BaseAllocator& + TempAlloc () const; + + /** + * Calculate the connections on already initialized Model. + */ + Standard_EXPORT Standard_Boolean Compute (); + + private: + Standard_Boolean createPath (LineConn2d_Path& thePath, + const gp_XY& theStart, + const Standard_Integer iSide) const; + + void pathOutline(NCollection_List& outList, + const LineConn2d_Path thePath, + const Standard_Integer theSide); + + Standard_Boolean checkPort (const LineConn2d_Port& thePort) const; + + // ---------- PRIVATE (prohibited) METHODS ---------- + + /// Copy constructor + LineConn2d_Model (const LineConn2d_Model& theOther); + + /// Assignment operator + LineConn2d_Model& operator = (const LineConn2d_Model& theOther); + + private: + // ---------- PRIVATE FIELDS ---------- + + /** + * Allocator to manage allocations of all contained object data. + */ + const Handle_NCollection_IncAllocator myAlloc; + + /** + * Allocator to manage allocations of all temporary data. + */ + Handle_NCollection_IncAllocator myTempAlloc; + + /** + * Container of all Objects. + */ + NCollection_Vector myObjects; + + /** + * Container of all Connections. + */ + NCollection_Vector myConnections; + + /** + * Container of all Ports. + */ + NCollection_Vector myPorts; + + /** + * Tree of bounding boxes indexing the Objects. + */ + LineConn2d_BoxTree myTree; + + /** + * Bounding box including all objects and port locations. Initialized in + * the method Update(). + */ + LineConn2d_Box myTreeBox; + + /** + * Tolerance value: the minimal distance from path segments model Objects. + */ + Standard_Real myTolerance; + + /** + * Length of the short line connecting a port with the connection trajectory. + */ + Standard_Real myPortLength; + + /** + * Parameter of the algorithm implemented in Compute(): the maximal price + * interval in which the tree us updated by new paths. This value is + * multiplied by LineConn2d_Path::PriceOfBreak(), so the rough meaning of + * this field is the number of extra breaks allowed for each branch during + * its propagation. + */ + Standard_Real mySearchDepth; + + // temporary fields, used inside the method Compute() + Standard_Real _PortLen; ///< temporary + gp_XY _PntTgt; ///< temporary + LineConn2d_Segment _SegTgtPort; ///< temporary + + public: +// Declaration of CASCADE RTTI +//DEFINE_STANDARD_RTTI (LineConn2d_Model) +}; + +// Definition of HANDLE object using Standard_DefineHandle.hxx +//DEFINE_STANDARD_HANDLE (LineConn2d_Model, ) + + +#endif diff --git a/src/lineconn2d/LineConn2d_Object.cxx b/src/lineconn2d/LineConn2d_Object.cxx new file mode 100755 index 000000000..d9da05466 --- /dev/null +++ b/src/lineconn2d/LineConn2d_Object.cxx @@ -0,0 +1,114 @@ +// File: LineConn2d_Object.cpp +// Created: 03.08.05 21:28:05 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#include + +#include +#include +#include + +//======================================================================= +//function : Update +//purpose : +//======================================================================= + +void LineConn2d_Object::Update () +{ + // Create the bounding box of the polyline + if (myIsModified) { + myBox.Clear(); + PointIterator anIter (myPoints); + for (; anIter.More(); anIter.Next()) { + myBox.Add (anIter.Value()); + } + myIsModified = 0; + } +} + +//======================================================================= +//function : IsOut +//purpose : +//======================================================================= + +Standard_Boolean LineConn2d_Object::IsOut (const gp_XY& thePoint, + const Standard_Real theTol) const +{ + const Standard_Real aConfusion = Precision::Confusion(); + const Standard_Real aUniConf = 1. + aConfusion; + const Standard_Real aSqConfusion = aConfusion * aConfusion; + Standard_Real anYprev (1e+100); + const gp_XY * aPnt[2] = { 0L, 0L }; + + Standard_Integer aNIntersect (0); + PointIterator anIter (myPoints); + if (anIter.More()) { + aPnt[1] = &myPoints.Last(); + for (; anIter.More(); anIter.Next()) { + aPnt[0] = aPnt[1]; + aPnt[1] = &anIter.Value(); + const gp_XY& aPntLow = * (aPnt[0]->X() < aPnt[1]->X() ? aPnt[0]: aPnt[1]); + const gp_XY& aPntUp = * (aPnt[0]->X() < aPnt[1]->X() ? aPnt[1]: aPnt[0]); + const gp_XY aVec (aPntUp - aPntLow); + + // Check the distance (condition ON) + Standard_Real aDist (-1.); + const Standard_Real aSegLen = aVec.Modulus(); + if (aSegLen < aConfusion) + // Degenerated case + aDist = (thePoint - (aPntLow + aPntUp) * 0.5).Modulus(); + else { + // General case + const gp_XY aVecN = aVec / aSegLen; + + // Obtain the coordinate of the projection on the segment + const gp_XY aVecP = thePoint - aPntLow; + const Standard_Real aCoord = aVecN * aVecP; + + // Check if it projects before the 1st point => distance to 1st point + if (aCoord < aConfusion) + aDist = aVecP.Modulus(); + // Check if it projects before the 2nd point => distance to 2nd point + else if (aCoord > aSegLen - aConfusion) + aDist = (thePoint - aPntUp).Modulus(); + // Otherwise retrieve the projection point inside the segment + else + aDist = LineConn2d_FABS (aVecN ^ aVecP); + } + if (aDist < theTol) + // ON detected, we stop the analysis + return Standard_False; + + // Rejection test + if (thePoint.X() > aPntUp.X() + aConfusion || thePoint.X() < aPntLow.X()) + continue; + + // Treatment of a vertical contour segment + if (aVec.X() < gp::Resolution() && + aVec.X() > -gp::Resolution()) + { + if (LineConn2d::IsSmall (anYprev - aPntLow.Y())) + anYprev = aPntUp.Y(); + else if (LineConn2d::IsSmall (anYprev - aPntUp.Y())) + anYprev = aPntLow.Y(); + continue; + } + + // Evaluate the intersection + const Standard_Real anAlpha = (thePoint.X() - aPntLow.X()) / aVec.X(); + if (anAlpha < aUniConf) { + const Standard_Real anYint = aPntLow.Y() + anAlpha * aVec.Y(); + if (anYint > thePoint.Y()) { + const Standard_Real aD2 = anYint - anYprev; + if (aD2 * aD2 > aSqConfusion) { + ++aNIntersect; + anYprev = anYint; + } + } + } + } + } + return ((aNIntersect & 0x01) == 0); +} diff --git a/src/lineconn2d/LineConn2d_Object.h b/src/lineconn2d/LineConn2d_Object.h new file mode 100755 index 000000000..ea5c8b64b --- /dev/null +++ b/src/lineconn2d/LineConn2d_Object.h @@ -0,0 +1,102 @@ +// File: LineConn2d_Object.h +// Created: 03.08.05 20:34:45 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_Object_HeaderFile +#define LineConn2d_Object_HeaderFile + +#include +#include + +/** + * Data Object is represented by: + * - Polyline (a list of points) for one closed contour defioning the shape + * - Bounding box of the polyline. + * The Objects should be allocated/destroyed exclusively from the Model class. + */ + +class LineConn2d_Object +{ + public: + + /// Iterator type, to retrieve the contour points + typedef NCollection_List::Iterator PointIterator; + + // ---------- PUBLIC METHODS ---------- + + /// Empty constructor. + inline LineConn2d_Object () {} + + /** + * Add a next point to the polyline of the given Object. + * You should be careful to provide a correct index value. + */ + inline void AddPoint (const gp_XY& thePnt) + { + myPoints.Append (thePnt); + myIsModified = 1; + } + + /** + * Update the Object internal data after its initialisation. This method + * builds the bounding box and performs other preparations. + */ + Standard_EXPORT void Update (); + + /** + * Query the bounding box. + */ + inline const LineConn2d_Box& Box () const + { return myBox; } + + /** + * Query the number of points in the contour. + */ + inline Standard_Integer NbPoints () const + { return myPoints.Extent(); } + + /** + * Get Iterator on points. + */ + inline PointIterator PointsIterator () const + { return myPoints; } + + /** + * Query the last point in the contour. + */ + inline const gp_XY& LastPoint () const + { return myPoints.Last(); } + + /** + * Classify a point towards the polygon defined by the object + * @param thePoint + * The given point to be classified + * @param theTol + * Tolerance for ON condition: if thePoint is nearer to any contour segment + * than the value theTol, the method returns False. + * @return + * True if the given point is outside the Object contour. + */ + Standard_EXPORT Standard_Boolean IsOut (const gp_XY& thePoint, + const Standard_Real theTol)const; + + protected: + // ---------- PROTECTED METHODS ---------- + + /// Constructor. + inline LineConn2d_Object (const Handle(NCollection_BaseAllocator)& theAlloc) + : myPoints (theAlloc) {} + + private: + // ---------- PRIVATE FIELDS ---------- + + NCollection_List myPoints; + LineConn2d_Box myBox; + Standard_Boolean myIsModified : 1; + + friend class LineConn2d_Model; +}; + +#endif diff --git a/src/lineconn2d/LineConn2d_Path.cxx b/src/lineconn2d/LineConn2d_Path.cxx new file mode 100755 index 000000000..7504db5d8 --- /dev/null +++ b/src/lineconn2d/LineConn2d_Path.cxx @@ -0,0 +1,398 @@ +// File: LineConn2d_Path.cpp +// Created: 11.08.05 15:16:13 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#include + +#include +#include +#include + +//======================================================================= +//function : LineConn2d_Path +//purpose : Empty constructor +//======================================================================= + +LineConn2d_Path::LineConn2d_Path () + : myModel (0L), + myParent (0L), + myPriceLen (0), + myPriceDist (0), + myLimitation (0), + myOrient (LineConn2d::Indefinite), + myIsComplete (Standard_False) {} + +//======================================================================= +//function : LineConn2d_Path() +//purpose : Constructor +//======================================================================= + +LineConn2d_Path::LineConn2d_Path (const gp_XY& theStart, + const gp_XY& theEnd, + const LineConn2d_Model& theModel, + const LineConn2d::Orient theOri) + : LineConn2d_Segment (theStart, theEnd), + myModel (&theModel), + myParent (0L), + myBranches (theModel.TempAlloc()), + myPriceLen (0), + myPriceDist (0), + myLimitation (0), + myOrient (theOri), + myIsComplete (Standard_False) +{ + if (theOri == LineConn2d::Indefinite) + myOrient = LineConn2d::Orientation (Delta()); +} + +//======================================================================= +//function : Width +//purpose : +//======================================================================= + +Standard_Real LineConn2d_Path::Width () const +{ + return (myModel ? myModel -> Tolerance() : 0.); +} + +//======================================================================= +//function : AddBranch +//purpose : +//======================================================================= + +void LineConn2d_Path::AddBranch (LineConn2d_Path& theBranch, + const gp_XY& theTgt) +{ + theBranch.myParent = this; + theBranch.Evaluate (theTgt); + myBranches.Append (theBranch); +} + +//======================================================================= +//function : Evaluate +//purpose : +//======================================================================= + +Standard_Integer LineConn2d_Path::Evaluate (const gp_XY& theTarget) +{ + const Standard_Real aHalfPerimeterNorm (myModel->HalfPerimeter() / 1000.); + const Standard_Real aHalfPerimeterNorm1 (aHalfPerimeterNorm * 10.); + + // Calculate the price due to the distance + const gp_XY aDistVector (theTarget - Extremity()); + // ... distance from the extremity to the target + const Standard_Real aDist = + LineConn2d_FABS(aDistVector.X()) + LineConn2d_FABS(aDistVector.Y()); + // ... deflection from the shortest way + gp_XY aV = theTarget - Origin(); + Standard_Real aDist1 = (Delta() ^ aV); + aDist1 = ::sqrt((aDist1 * aDist1) / (aV * aV)); + + if (aDist < Precision::Confusion()) + myIsComplete = Standard_True; + + myPriceDist = Standard_Integer ((aDist + 0.2 * aDist1) / aHalfPerimeterNorm); + + // Calculate the price due to length. + myPriceLen = Standard_Integer (Delta().Modulus() / aHalfPerimeterNorm1); + + // Take into account the additive from the parent + if (myParent != 0L) { + if (myParent -> Orientation() != myOrient) + myPriceLen += PriceOfBreak(); + myPriceLen += (myParent -> myPriceLen - + (Origin() - myParent->Extremity()).Modulus() + / aHalfPerimeterNorm1); + } + return myPriceLen + myPriceDist; +} + +//======================================================================= +//function : createPath +//purpose : +//======================================================================= + +Standard_Boolean LineConn2d_Path::createPath + (LineConn2d_Path& thePath, + const LineConn2d_Model& theModel, + const gp_XY& theStart, + const LineConn2d::Orient theOrient, + const Standard_Boolean isRoot) +{ + Standard_Boolean aResult (Standard_False); + const Standard_Real aTol = theModel.Tolerance(); + // Create a long box extending in the direction theOrient (till the boundary) + LineConn2d_Box aPathBox; + const LineConn2d_Box& aModelBox = theModel.Box(); + Standard_Real aPathBoxLen (0.); + gp_XY aPathDir (0., 0.); + // Four segments forming the PathBox: + // 0 - the transversal segment containing theStart + // 1 - left side + // 2 - the front + // 3 - the right side + LineConn2d_Segment aSeg[4]; + switch (theOrient) { + case LineConn2d::E: + aPathBoxLen = aModelBox.Center().X() + aModelBox.HSize().X() - theStart.X(); + aPathBox = LineConn2d_Box (theStart + gp_XY (0.5 * aPathBoxLen, 0.), + gp_XY (0.5 * aPathBoxLen, aTol)); + aPathDir.SetX (1.); + aSeg[0] = LineConn2d_Segment (theStart + gp_XY (0., -aTol), + theStart + gp_XY (0., aTol)); + aSeg[1] = LineConn2d_Segment (theStart + gp_XY (0., aTol), + theStart + gp_XY (aPathBoxLen, aTol)); + aSeg[2] = LineConn2d_Segment (theStart + gp_XY (aPathBoxLen, aTol), + theStart + gp_XY (aPathBoxLen, -aTol)); + aSeg[3] = LineConn2d_Segment (theStart + gp_XY (0., -aTol), + theStart + gp_XY (aPathBoxLen, -aTol)); + break; + case LineConn2d::N: + aPathBoxLen = aModelBox.Center().Y() + aModelBox.HSize().Y() - theStart.Y(); + aPathBox = LineConn2d_Box (theStart + gp_XY (0., 0.5 * aPathBoxLen), + gp_XY (aTol, 0.5 * aPathBoxLen)); + aPathDir.SetY (1.); + aSeg[0] = LineConn2d_Segment (theStart + gp_XY (aTol, 0.), + theStart + gp_XY (-aTol, 0.)); + aSeg[1] = LineConn2d_Segment (theStart + gp_XY (-aTol, 0), + theStart + gp_XY (-aTol, aPathBoxLen)); + aSeg[2] = LineConn2d_Segment (theStart + gp_XY (-aTol, aPathBoxLen), + theStart + gp_XY (aTol, aPathBoxLen)); + aSeg[3] = LineConn2d_Segment (theStart + gp_XY (aTol, 0.), + theStart + gp_XY (aTol, aPathBoxLen)); + break; + case LineConn2d::W: + aPathBoxLen= -aModelBox.Center().X() + aModelBox.HSize().X() + theStart.X(); + aPathBox = LineConn2d_Box (theStart - gp_XY (0.5 * aPathBoxLen, 0.), + gp_XY (0.5 * aPathBoxLen, aTol)); + aPathDir.SetX (-1.); + aSeg[0] = LineConn2d_Segment (theStart - gp_XY (0., -aTol), + theStart - gp_XY (0., aTol)); + aSeg[1] = LineConn2d_Segment (theStart - gp_XY (0., aTol), + theStart - gp_XY (aPathBoxLen, aTol)); + aSeg[2] = LineConn2d_Segment (theStart - gp_XY (aPathBoxLen, aTol), + theStart - gp_XY (aPathBoxLen, -aTol)); + aSeg[3] = LineConn2d_Segment (theStart - gp_XY (0., -aTol), + theStart - gp_XY (aPathBoxLen, -aTol)); + break; + case LineConn2d::S: + aPathBoxLen= -aModelBox.Center().Y() + aModelBox.HSize().Y() + theStart.Y(); + aPathBox = LineConn2d_Box (theStart - gp_XY (0., 0.5 * aPathBoxLen), + gp_XY (aTol, 0.5 * aPathBoxLen)); + aPathDir.SetY (-1.); + aSeg[0] = LineConn2d_Segment (theStart - gp_XY (aTol, 0.), + theStart - gp_XY (-aTol, 0.)); + aSeg[1] = LineConn2d_Segment (theStart - gp_XY (-aTol, 0), + theStart - gp_XY (-aTol, aPathBoxLen)); + aSeg[2] = LineConn2d_Segment (theStart - gp_XY (-aTol, aPathBoxLen), + theStart - gp_XY (aTol, aPathBoxLen)); + aSeg[3] = LineConn2d_Segment (theStart - gp_XY (aTol, 0.), + theStart - gp_XY (aTol, aPathBoxLen)); + break; + } + + // Find intersections between aPathBox and the model Objects + Standard_Real aMinInterDistance (aPathBoxLen); + Standard_Integer anInterSide (0); + + aPathBox.Enlarge (4 * Precision::Confusion()); + LineConn2d_BoxTreeSelector aSelBox (aPathBox); + theModel.GetTree().Select (aSelBox); + NCollection_List::Iterator + aSelBoxIter (aSelBox.GetObjects()); + for (; aSelBoxIter.More(); aSelBoxIter.Next()) { + LineConn2d_SegmentIterator anIter (* aSelBoxIter.Value()); + Standard_Real aMinDistance (aMinInterDistance); + // Loop on the segments of the Object + for (; anIter.More(); anIter.Next()) { + const LineConn2d_Segment& aSegment = anIter.Value(); + Standard_Real anAlpha[2]; + // intersection box - segment + if (aPathBox.IsOut (aSegment) == Standard_False) { + if (aSeg[0].IsIntersect (aSegment, anAlpha)) // intersect with the rear + { + // cancel intersection test, the rear intersection means the + // intersection with the own object + aMinDistance = (isRoot ? ::RealLast() : 0.); + break; + } + if (aSeg[1].IsIntersect (aSegment, anAlpha)) // intersect with the Left + { + const Standard_Real aDist = anAlpha[0] * aPathBoxLen; + if (aDist < aMinDistance) { + aMinDistance = aDist; + anInterSide = -1; + } + } + if (aSeg[3].IsIntersect (aSegment, anAlpha)) // intersect with the Right + { + const Standard_Real aDist = anAlpha[0] * aPathBoxLen; + if (aDist < aMinDistance) { + aMinDistance = aDist; + anInterSide = 1; + } + } + if (aPathBox.IsOut (aSegment.Origin()) == Standard_False) { + const Standard_Real aDist = (aSegment.Origin() - theStart) * aPathDir; + if (aDist < aMinDistance) { + aMinDistance = aDist; + anInterSide = 0; + } + } + } + } + if (aMinDistance < aMinInterDistance) + aMinInterDistance = aMinDistance; + } + + // The PathLine segment is the medial segment of the PathBox prolongated + // by the Tolerance (i.e., by the half-width of the PathBox). Find the + // intersection with this PathLine. This intersection also delimits the Path. + if (aMinInterDistance > aTol) { + Standard_Real aPathLineDist = aTol + aMinInterDistance + 2 * Precision::Confusion(); + if (aPathLineDist > aPathBoxLen) + aPathLineDist = aPathBoxLen; + const LineConn2d_Segment aPathLine + (theStart, theStart + aPathDir * aPathLineDist); + + LineConn2d_BoxTreeSelector aSelSeg (aPathLine); + theModel.GetTree().Select (aSelSeg); + NCollection_List::Iterator + aSelSegIter (aSelSeg.GetObjects()); + for (; aSelSegIter.More(); aSelSegIter.Next()) { + LineConn2d_SegmentIterator anIter (* aSelSegIter.Value()); + for (; anIter.More(); anIter.Next()) { + const LineConn2d_Segment& aSegment = anIter.Value(); + Standard_Real anAlpha[2]; + // intersection pathline - segment + if (aPathLine.IsIntersect (aSegment, anAlpha)) { + const Standard_Real aDist = anAlpha[0] * aPathLineDist - aTol; + if (aDist < aMinInterDistance && aDist > 0) + aMinInterDistance = aDist; + } + } + } + } + + if (aMinInterDistance > aTol) { + thePath = LineConn2d_Path (theStart, theStart + aMinInterDistance*aPathDir, + theModel, theOrient); + thePath.myLimitation = anInterSide; + aResult = Standard_True; + } + return aResult; +} + +//======================================================================= +//function : Orientation +//purpose : +//======================================================================= + +LineConn2d::Orient LineConn2d_Path::Orientation + (const Standard_Integer theSide) const +{ + LineConn2d::Orient aResult (myOrient); + switch (theSide) { + case 1: + ((Standard_Integer&)aResult) --; + if (aResult == LineConn2d::Indefinite) + aResult = LineConn2d::S; + break; + case -1: + ((Standard_Integer&)aResult) ++; + if (aResult == LineConn2d::Indefinite1) + aResult = LineConn2d::E; + break; + } + return aResult; +} + + +//======================================================================= +//function : Direction +//purpose : +//======================================================================= + +gp_XY LineConn2d_Path::Direction (const Standard_Integer theSide) const +{ + gp_XY aResult (0., 0.); + switch (theSide) { + case -1: + switch (myOrient) { + case LineConn2d::E : aResult.SetY (1.); break; + case LineConn2d::N : aResult.SetX (-1.); break; + case LineConn2d::W : aResult.SetY (-1.); break; + case LineConn2d::S : aResult.SetX (1.); break; + } + break; + case 0: + switch (myOrient) { + case LineConn2d::E : aResult.SetX (1.); break; + case LineConn2d::N : aResult.SetY (1.); break; + case LineConn2d::W : aResult.SetX (-1.); break; + case LineConn2d::S : aResult.SetY (-1.); break; + } + break; + case 1: + switch (myOrient) { + case LineConn2d::E : aResult.SetY (-1.); break; + case LineConn2d::N : aResult.SetX (1.); break; + case LineConn2d::W : aResult.SetY (1.); break; + case LineConn2d::S : aResult.SetX (-1.); break; + } + break; + } + return aResult; +} + +//======================================================================= +//function : ProjectPoint +//purpose : +//======================================================================= + +Standard_Boolean LineConn2d_Path::ProjectPoint (gp_XY& theProj, + const gp_XY& thePoint) const +{ + Standard_Boolean aResult (Standard_False); + switch (myOrient) { + case LineConn2d::E : + if (LineConn2d::IsInside (thePoint.X(), + Origin().X(), + Extremity().X())) + { + aResult = Standard_True; + theProj.SetCoord (thePoint.X(), Origin().Y()); + } + break; + case LineConn2d::W : + if (LineConn2d::IsInside (thePoint.X(), + Extremity().X(), + Origin().X())) + { + aResult = Standard_True; + theProj.SetCoord (thePoint.X(), Origin().Y()); + } + break; + case LineConn2d::N : + if (LineConn2d::IsInside (thePoint.Y(), + Origin().Y(), + Extremity().Y())) + { + aResult = Standard_True; + theProj.SetCoord (Origin().X(), thePoint.Y()); + } + break; + case LineConn2d::S : + if (LineConn2d::IsInside (thePoint.Y(), + Extremity().Y(), + Origin().Y())) + { + aResult = Standard_True; + theProj.SetCoord (Origin().X(), thePoint.Y()); + } + break; + } + return aResult; +} diff --git a/src/lineconn2d/LineConn2d_Path.h b/src/lineconn2d/LineConn2d_Path.h new file mode 100755 index 000000000..80bb91a63 --- /dev/null +++ b/src/lineconn2d/LineConn2d_Path.h @@ -0,0 +1,187 @@ +// File: LineConn2d_Path.h +// Created: 11.08.05 15:08:00 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_Path_HeaderFile +#define LineConn2d_Path_HeaderFile + +#include +#include +#include + +class LineConn2d_Model; + +/** + * Single path as temporary object created during the calculation of + * connections. It can be treated as: + * @li Segment having a definite orientation, origin and length. or + * @li 2D box along that segment, with a width equal to the model tolerance, or + * @li Node of the tree of Paths created during the calculations. + */ + +class LineConn2d_Path : public LineConn2d_Segment +{ + public: + // ---------- PUBLIC METHODS ---------- + + /// Empty Constructor. + Standard_EXPORT LineConn2d_Path (); + + /// Constructor. + Standard_EXPORT LineConn2d_Path (const gp_XY& theStart, + const gp_XY& theEnd, + const LineConn2d_Model& theModel, + const LineConn2d::Orient theOri = + LineConn2d::Indefinite); + /** + * Query the Width. + */ + Standard_EXPORT Standard_Real Width () const; + + /** + * Query the parent. + */ + inline const LineConn2d_Path& Parent () const + { return * myParent; } + + /** + * Query the orientation, according to the given Side + * @param theSide + * Defines the side on which the orientation is calculated. + * @li Left : -1 + * @li Front: 0 + * @li Right: +1 + */ + Standard_EXPORT LineConn2d::Orient Orientation (const Standard_Integer theSide + = 0) const; + + /** + * Query the limitation of the Path. + * @return + * @li -1: limited on the left; + * @li 0: limited on the front or unlimited; + * @li 1: limited on the right. + */ + inline Standard_Integer Limitation () const + { return myLimitation; } + + /** + * Query the direction according to the given Side. + * @param theSide + * Defines the side on which the direction is calculated. + * @li Left : -1 + * @li Front: 0 + * @li Right: +1 + * @return + * Unit vector of the corresponding direction. + */ + Standard_EXPORT gp_XY Direction (const Standard_Integer theSide + = 0) const; + + /** + * Query the price associated with the end of the current Path. + * The price is calculated by the method Evaluate(). + * The algorithm: + * - the distance is calculated as sum of absolute distances along X and Y. + * - the distance contribution to the price is percent of the half-perimeter + * of the Model box. + * - each change of orientation gives the contribution of PriceOfBreak points. + */ + inline Standard_Integer Price () const + { return myPriceLen + myPriceDist; } + + /** + * Create a Path in the given direction. The Path stops at an Object or + * at the boundary of the Model. + * @param outPath + * Created object. + * @param theModel + * Used to provide the set of Objects, to properly stop the Path. + * @param theStart + * Beginning of the Path. + * @param theOrient + * Orientation of the Path. + * @param isRoot + * True indicates the the root path is built. + * @return + * True on success. + */ + static Standard_EXPORT Standard_Boolean + createPath (LineConn2d_Path& outPath, + const LineConn2d_Model& theModel, + const gp_XY& theStart, + const LineConn2d::Orient theOrient, + const Standard_Boolean isRoot); + + /** + * Evaluate the price of the trajectory where the current Path is the last + * one. This is done by incrementing the price of the Parent by the addition + * due to this Path element. + *

This method also checks if the path ends on theTarget, if yes then it + * sets the flag myIsComplete. + * @param theTarget + * Target point of the path sequence (the end of the calculated connection) + */ + Standard_EXPORT Standard_Integer + Evaluate (const gp_XY& theTarget); + + /** + * Add the branch path. This method sets the Parent field in theBranch + * @param theBranch + * Path added as branch to the current one. + * @param theTarget + * Target point for price evaluation (method Evaluate is called with it). + */ + Standard_EXPORT void AddBranch (LineConn2d_Path& theBranch, + const gp_XY& theTarget); + + /** + * Query if the Path is completed. + */ + inline Standard_Boolean + IsComplete () const + { return myIsComplete; } + + /** + * Project orthogonally the given point on the Path segment. + * @param theResult + * Output parameter, the projection point belonging to the inside of + * the Path segment (only updated if the method returns True). + * @param thePoint + * The given point to be projected. + * @return + * True if the projection is found inside the Path segment + */ + Standard_EXPORT Standard_Boolean ProjectPoint + (gp_XY& theResult, + const gp_XY& thePoint) const; + + /** + * Price contributon of one path break (change of orientation) + */ + static inline Standard_Integer + PriceOfBreak () + { return 300; } + + protected: + // ---------- PROTECTED METHODS ---------- + + + private: + // ---------- PRIVATE FIELDS ---------- + const LineConn2d_Model * myModel; + const LineConn2d_Path * myParent; + NCollection_List myBranches; + Standard_Integer myPriceLen; + Standard_Integer myPriceDist; + Standard_Integer myLimitation; ///< -1, 0(def) or 1 + LineConn2d::Orient myOrient; + Standard_Boolean myIsComplete; + + friend class LineConn2d_PathIterator; +}; + + +#endif diff --git a/src/lineconn2d/LineConn2d_PathIterator.cxx b/src/lineconn2d/LineConn2d_PathIterator.cxx new file mode 100755 index 000000000..7b8dc7722 --- /dev/null +++ b/src/lineconn2d/LineConn2d_PathIterator.cxx @@ -0,0 +1,62 @@ +// File: LineConn2d_PathIterator.cpp +// Created: 16.08.05 10:38:26 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#include + +#include + +//======================================================================= +//function : LineConn2d_PathIterator() +//purpose : Constructor +//======================================================================= + +LineConn2d_PathIterator::LineConn2d_PathIterator + (const LineConn2d_Path& theRoot, + const Handle(NCollection_BaseAllocator)& theAlloc) + : myStack (theAlloc), + myLimit (1024) +{ + PathListIterator anIter (theRoot.myBranches); + findNext (anIter); +} + +//======================================================================= +//function : Next +//purpose : +//======================================================================= + +void LineConn2d_PathIterator::Next () +{ + while (myStack.IsEmpty() == Standard_False) { + PathListIterator& anIter = myStack.ChangeTop(); + anIter.Next(); + if (anIter.More()) { + PathListIterator aNewIter (anIter.Value().myBranches); + if (findNext (aNewIter)) + break; + } + myStack.Pop(); + } +} + +//======================================================================= +//function : findNext +//purpose : +//======================================================================= + +Standard_Boolean LineConn2d_PathIterator::findNext + (LineConn2d_PathIterator::PathListIterator& theIter) +{ + Standard_Boolean aResult (Standard_False); + if (myStack.Depth() < myLimit) { + while (theIter.More()) { + myStack.Push (theIter); + theIter = PathListIterator (theIter.Value().myBranches); + } + aResult = Standard_True; + } + return aResult; +} diff --git a/src/lineconn2d/LineConn2d_PathIterator.h b/src/lineconn2d/LineConn2d_PathIterator.h new file mode 100755 index 000000000..f9a17cbb6 --- /dev/null +++ b/src/lineconn2d/LineConn2d_PathIterator.h @@ -0,0 +1,72 @@ +// File: LineConn2d_PathIterator.h +// Created: 16.08.05 10:31:29 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_PathIterator_HeaderFile +#define LineConn2d_PathIterator_HeaderFile + +#include +#include + +/// Tree iterator of Path structure + +class LineConn2d_PathIterator +{ + protected: + typedef NCollection_List ::Iterator PathListIterator; + + public: + // ---------- PUBLIC METHODS ---------- + + /// Empty constructor + inline LineConn2d_PathIterator () {} + + /** + * Constructor. + * @param theRoot + * The top-level Path object, the iterator would explore its branches. + * @param theAlloc + * Allocator for the internal Stack data structure. + */ + Standard_EXPORT LineConn2d_PathIterator + (const LineConn2d_Path& theRoot, + const Handle(NCollection_BaseAllocator)& theAlloc); + + /** + * Check if there is a Path object available. + */ + inline Standard_Boolean More () const + { return (myStack.IsEmpty() == Standard_False); } + + /** + * Advance the iterator to the next item - the leaf of the next tree branch. + */ + Standard_EXPORT void Next (); + + /** + * Query the iterated value. + */ + inline LineConn2d_Path& Value () const + { return myStack.Top().ChangeValue(); } + + /** + * Set the maximal depth for the iteration stack. After that, any Path that + * is more that theLimit level from the root, would be ignored. + */ + inline void SetDepthLimit (const Standard_Integer theLim) + { myLimit = theLim; } + + private: + // ---------- PRIVATE METHODS ---------- + Standard_Boolean findNext (PathListIterator&); + + private: + // ---------- PRIVATE FIELDS ---------- + + NCollection_Stack myStack; + Standard_Integer myLimit; ///< maximal stack depth +}; + +#endif diff --git a/src/lineconn2d/LineConn2d_Port.h b/src/lineconn2d/LineConn2d_Port.h new file mode 100755 index 000000000..16149cbe7 --- /dev/null +++ b/src/lineconn2d/LineConn2d_Port.h @@ -0,0 +1,49 @@ +// File: LineConn2d_Port.h +// Created: 03.08.05 22:50:38 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_Port_HeaderFile +#define LineConn2d_Port_HeaderFile + +#include +#include + +class LineConn2d_Object; + +/// Class LineConn2d_Port +// + +class LineConn2d_Port : public gp_Ax2d +{ + public: + // ---------- PUBLIC METHODS ---------- + + /// Empty constructor + inline LineConn2d_Port () : myObject (0L) {} + + /** + * Query the associated Object. + */ + inline const LineConn2d_Object& Object () const + { return * myObject; } + + protected: + // ---------- PROTECTED METHODS ---------- + + /// Constructor + inline LineConn2d_Port (const LineConn2d_Object& theObj, + const gp_XY theLocation, + const gp_Dir2d theDir) + : gp_Ax2d (theLocation, theDir), myObject (&theObj) {} + + private: + // ---------- PRIVATE FIELDS ---------- + + const LineConn2d_Object * myObject; + + friend class LineConn2d_Model; +}; + +#endif diff --git a/src/lineconn2d/LineConn2d_Segment.cxx b/src/lineconn2d/LineConn2d_Segment.cxx new file mode 100755 index 000000000..cbc5320ae --- /dev/null +++ b/src/lineconn2d/LineConn2d_Segment.cxx @@ -0,0 +1,51 @@ +// File: LineConn2d_Segment.cpp +// Created: 04.08.05 23:23:39 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#include + +#include +#include + +//======================================================================= +//function : Limit +//purpose : +//======================================================================= + +void LineConn2d_Segment::Limit (const LineConn2d_Box& theBox) +{ + // to be implemented ... +} + +//======================================================================= +//function : IsIntersect +//purpose : +//======================================================================= + +Standard_Boolean LineConn2d_Segment::IsIntersect + (const LineConn2d_Segment& theSegOther, + Standard_Real outAlpha[2]) const +{ + Standard_Boolean aResult (Standard_False); + const gp_XY aLink = theSegOther.myOrigin - myOrigin; + const Standard_Real aProd[3] = { + aLink ^ theSegOther.myDelta, + aLink ^ myDelta, + myDelta ^ theSegOther.myDelta + }; + if (LineConn2d::IsSmall(aProd[2]) == Standard_False) { // test parallel + const Standard_Real aCoeff [2] = { + aProd[0] / aProd[2], + aProd[1] / aProd[2] + }; + if (LineConn2d::IsInside (aCoeff[0], 0., 1.) && + LineConn2d::IsInside (aCoeff[1], 0., 1.)) { + aResult = Standard_True; // intersection found + outAlpha[0] = aCoeff[0]; + outAlpha[1] = aCoeff[1]; + } + } + return aResult; +} diff --git a/src/lineconn2d/LineConn2d_Segment.h b/src/lineconn2d/LineConn2d_Segment.h new file mode 100755 index 000000000..97fe051fb --- /dev/null +++ b/src/lineconn2d/LineConn2d_Segment.h @@ -0,0 +1,111 @@ +// File: LineConn2d_Segment.h +// Created: 04.08.05 22:37:59 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_Segment_HeaderFile +#define LineConn2d_Segment_HeaderFile + +#include + +class LineConn2d_Box; + +/** + * 2D segment for which the data are defined: + * @li Origin point; + * @li Extremity point; + * @li Delta (vector from Origin to Extremity). + */ +class LineConn2d_Segment +{ + public: + // ---------- PUBLIC METHODS ---------- + + /// Empty constructor + inline LineConn2d_Segment () + : myOrigin (0., 0.), myDelta (0., 0.) {} + + /** + * Constructor + */ + inline LineConn2d_Segment (const gp_XY& theOrigin, const gp_XY& theExtremity) + : myOrigin (theOrigin), + myDelta (theExtremity - theOrigin) {} + + /** + * Set the Origin point + */ + inline void SetOrigin (const gp_XY& theOrigin) + { myOrigin = theOrigin; } + + /** + * Set the Delta + */ + inline void SetDelta (const gp_XY& theDelta) + { myDelta = theDelta; } + + /** + * Set the Extremity + */ + inline void SetExtremity (const gp_XY& theExtremity) + { myDelta = theExtremity - myOrigin; } + + /** + * Query the Origin + */ + inline const gp_XY& Origin () const + { return myOrigin; } + + /** + * Query the Delta + */ + inline const gp_XY& Delta () const + { return myDelta; } + + /** + * Query the point interpolated between Origin and Extremity + * in interval [0 .. 1]. + * @param theParam + * interpolation parameter; if negative or more than 1, the result is + * outside the Segment + */ + inline gp_XY Point (const Standard_Real theParam) const + { return myOrigin + myDelta * theParam; } + + /** + * Query the Extremity + */ + inline gp_XY Extremity () const + { return myOrigin + myDelta; } + + /** + * Limit the Segment by the internals of theBox. + */ + Standard_EXPORT void Limit (const LineConn2d_Box& theBox); + + /** + * Test two segments for intersection. + * @param theSegOther + * Other segment (to be intersected with) + * @param outAlpha + * 2 Parameters of intersecton (this and other segment). The parameter + * defines the intersection point on the given segment, as interpolation + * value [0 .. 1] between the Origin and the Extremity. + * Indefinite if there is no intersection. + * @return + * True if there is intersection. + */ + Standard_EXPORT Standard_Boolean IsIntersect + (const LineConn2d_Segment& theSegOther, + Standard_Real outAlpha[2]) const; + + + private: + // ---------- PRIVATE FIELDS ---------- + + gp_XY myOrigin; + gp_XY myDelta; +}; + +#endif diff --git a/src/lineconn2d/LineConn2d_SegmentIterator.h b/src/lineconn2d/LineConn2d_SegmentIterator.h new file mode 100755 index 000000000..eb12b5175 --- /dev/null +++ b/src/lineconn2d/LineConn2d_SegmentIterator.h @@ -0,0 +1,69 @@ +// File: LineConn2d_SegmentIterator.h +// Created: 04.08.05 22:47:27 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_SegmentIterator_HeaderFile +#define LineConn2d_SegmentIterator_HeaderFile + +#include +#include + +/** + * Iterator that is invoked on LineConn2d_Object and returns contour + * segments starting from the one between the last point and the first point + * of the contour. + */ + +class LineConn2d_SegmentIterator +{ + public: + // ---------- PUBLIC METHODS ---------- + + /// Empty constructor + inline LineConn2d_SegmentIterator () + : myIsSeg (Standard_False) {} + + /// Constructor + inline LineConn2d_SegmentIterator (const LineConn2d_Object& theObject) + : myListIter (theObject.PointsIterator()), + myIsSeg (Standard_False) + { + if (theObject.NbPoints() > 1) { + mySeg.SetOrigin (theObject.LastPoint()); + mySeg.SetExtremity (myListIter.Value()); + myIsSeg = Standard_True; + } + } + + /// Method More() + inline Standard_Boolean More() const + { return myIsSeg; } + + /// Iterator increment + inline void Next () + { + if (myIsSeg) { + myListIter.Next(); + if (myListIter.More()) { + mySeg.SetOrigin (mySeg.Extremity()); + mySeg.SetExtremity (myListIter.Value()); + } else + myIsSeg = Standard_False; + } + } + + /// Query the currently iterated segment + inline const LineConn2d_Segment& Value () const + { return mySeg; } + + private: + // ---------- PRIVATE FIELDS ---------- + + NCollection_List ::Iterator myListIter; + LineConn2d_Segment mySeg; + Standard_Boolean myIsSeg; +}; + +#endif diff --git a/src/lineconn2d/LineConn2d_ZInterval.h b/src/lineconn2d/LineConn2d_ZInterval.h new file mode 100755 index 000000000..25c60dcb8 --- /dev/null +++ b/src/lineconn2d/LineConn2d_ZInterval.h @@ -0,0 +1,60 @@ +// File: LineConn2d_ZInterval.hxx +// Created: 21.02.05 14:48:01 +// Author: Alexander GRIGORIEV +// Copyright: Open Cascade 2005 + + +#ifndef LineConn2d_ZInterval_HeaderFile +#define LineConn2d_ZInterval_HeaderFile + +#include +#include + +/// Elementary interval used in LineConn2d_IntervalBuffer. + +class LineConn2d_ZInterval +{ + public: + // ---------- PUBLIC METHODS ---------- + + /// Empty constructor + inline LineConn2d_ZInterval () + : myZ (-::RealLast()) + { myX[0] = 0.; myX[1] = 0.; } + + /// Constructor + inline LineConn2d_ZInterval (const Standard_Real theZ, + const Standard_Real theX0, + const Standard_Real theX1) + : myZ (theZ) + { myX[0] = theX0; myX[1] = theX1; } + + /// Query the Z value. + inline Standard_Real Z () const { return myZ; } + + /// Query the X extremity value. + inline Standard_Real X (const Standard_Integer i) const { return myX[i&0x1];} + + /// Comparison operator. Checks only coincidence of X extremities. + inline Standard_Boolean operator == (const LineConn2d_ZInterval& theOther) const + { return ((myX[0] - theOther.myX[0]) * (myX[0] - theOther.myX[0]) + + (myX[1] - theOther.myX[1]) * (myX[1] - theOther.myX[1])) < 1e-6; } + + /// Set the attribute value + inline void SetAttribute (const long theAttrib) + { myAttrib = theAttrib; } + + /// Query the attribute value + inline long Attribute () const { return myAttrib; } + + private: + // ---------- PRIVATE FIELDS ---------- + + Standard_Real myZ; + Standard_Real myX[2]; + long myAttrib; + + friend class LineConn2d_IntervalBuffer; +}; + +#endif diff --git a/src/lineconn2d/Makefile.am b/src/lineconn2d/Makefile.am new file mode 100644 index 000000000..2957dae9a --- /dev/null +++ b/src/lineconn2d/Makefile.am @@ -0,0 +1,56 @@ + +include $(top_srcdir)/adm/unix/make_begin.am + +lib_LTLIBRARIES = libLineConn2d.la + +# Implementation files +LIBSOURCES = \ + LineConn2d.cxx \ + LineConn2d_Box.cxx \ + LineConn2d_BoxTree.cxx \ + LineConn2d_Connection.cxx \ + LineConn2d_IntervalBuffer.cxx \ + LineConn2d_Model.cxx \ + LineConn2d_Object.cxx \ + LineConn2d_Path.cxx \ + LineConn2d_PathIterator.cxx \ + LineConn2d_Segment.cxx + +# Headers +LIBHEADERS = \ + LineConn2d.h \ + LineConn2d_Box.h \ + LineConn2d_BoxTree.h \ + LineConn2d_Connection.h \ + LineConn2d_IntervalBuffer.h \ + LineConn2d_Model.h \ + LineConn2d_Object.h \ + LineConn2d_Path.h \ + LineConn2d_PathIterator.h \ + LineConn2d_Port.h \ + LineConn2d_Segment.h \ + LineConn2d_SegmentIterator.h \ + LineConn2d_ZInterval.h + +# MOC-generated files +MOCSOURCES = + +# Resources +LIBPOFILES = + +LIBICONS = + +# Add "resources" subdirectory to resource file names +POFILES = $(LIBPOFILES) +ICONS = $(LIBICONS) + +libLineConn2d_la_SOURCES = $(LIBSOURCES) $(LIBHEADERS) +nodist_libLineConn2d_la_SOURCES = $(MOCSOURCES) + +# List all generated files here +BUILT_SOURCES = $(MOCSOURCES) + +libLineConn2d_la_LIBADD = @CAS_KERNEL@ +libLineConn2d_la_CXXFLAGS = @CAS_CPPFLAGS@ + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/lineconn2d/Makefile_old.in b/src/lineconn2d/Makefile_old.in new file mode 100755 index 000000000..ae6898e53 --- /dev/null +++ b/src/lineconn2d/Makefile_old.in @@ -0,0 +1,54 @@ +# File : Makefile.in +# Author : Pavel TELKOV (OCN) +# Module : CATHARE + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@srcdir@/resources + + +@COMMENCE@ + +# header files +EXPORT_HEADERS= LineConn2d.h \ + LineConn2d_Box.h \ + LineConn2d_BoxTree.h \ + LineConn2d_Connection.h \ + LineConn2d_IntervalBuffer.h \ + LineConn2d_Model.h \ + LineConn2d_Object.h \ + LineConn2d_Path.h \ + LineConn2d_PathIterator.h \ + LineConn2d_Port.h \ + LineConn2d_Segment.h \ + LineConn2d_SegmentIterator.h \ + LineConn2d_ZInterval.h + +# .po files to transform in .qm +PO_FILES = \ + +# Libraries targets +LIB = libLineConn2d.la +LIB_SRC= LineConn2d.cxx \ + LineConn2d_Box.cxx \ + LineConn2d_BoxTree.cxx \ + LineConn2d_Connection.cxx \ + LineConn2d_IntervalBuffer.cxx \ + LineConn2d_Model.cxx \ + LineConn2d_Object.cxx \ + LineConn2d_Path.cxx \ + LineConn2d_PathIterator.cxx \ + LineConn2d_Segment.cxx + +LIB_MOC = \ + +RESOURCES_FILES = + +BIN = + +CPPFLAGS+=$(OCC_INCLUDES) + +LDFLAGS+=$(CAS_KERNEL) -lTKernel + +@CONCLUDE@ diff --git a/src/prs/Makefile.am b/src/prs/Makefile.am new file mode 100644 index 000000000..f9d629079 --- /dev/null +++ b/src/prs/Makefile.am @@ -0,0 +1,75 @@ + +include $(top_srcdir)/adm/unix/make_begin.am + +lib_LTLIBRARIES = libYACSPrs.la + +# Implementation files +LIBSOURCES = \ + YACSPrs_ElementaryNode.cxx \ + YACSPrs_ServiceNode.cxx \ + YACSPrs_InlineNode.cxx \ + YACSPrs_IfNode.cxx \ + YACSPrs_SwitchNode.cxx \ + YACSPrs_LoopNode.cxx \ + YACSPrs_ForEachLoopNode.cxx \ + YACSPrs_BlocNode.cxx \ + YACSPrs_Link.cxx + +# Headers +LIBHEADERS = \ + YACSPrs_ElementaryNode.h \ + YACSPrs_ServiceNode.h \ + YACSPrs_InlineNode.h \ + YACSPrs_IfNode.h \ + YACSPrs_SwitchNode.h \ + YACSPrs_LoopNode.h \ + YACSPrs_ForEachLoopNode.h \ + YACSPrs_BlocNode.h \ + YACSPrs_Link.h + +# MOC-generated files +MOCSOURCES = \ + YACSPrs_Link_moc.cxx + +# Resources +LIBPOFILES = \ + YACSPrs_msg_en.po \ + YACSPrs_images.po + +LIBICONS = \ + no_status.png \ + disabled.png \ + running.png \ + waiting.png \ + aborted1.png \ + aborted2.png \ + aborted3.png \ + done.png \ + right_arrows.png \ + left_arrows.png + +# Add "resources" subdirectory to resource file names +POFILES = $(LIBPOFILES:%=resources/%) +ICONS = $(LIBICONS:%=resources/%) + +libYACSPrs_la_SOURCES = $(LIBSOURCES) $(LIBHEADERS) +nodist_libYACSPrs_la_SOURCES = $(MOCSOURCES) + +# List all generated files here +BUILT_SOURCES = $(MOCSOURCES) + +libYACSPrs_la_LIBADD = \ + ../engine/libYACSEngine.la \ + ../runtime/libYACSRuntimeSALOME.la \ + @QT_MT_LIBS@ @GUI_LDFLAGS@ -lQxGraph @PYTHON_LDFLAGS@ + +libYACSPrs_la_CXXFLAGS = \ + $(THREAD_DEF) \ + $(PYTHON_CPPFLAGS) \ + -I$(KERNEL_ROOT_DIR)/include/salome \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + -I$(srcdir)/../runtime \ + @QT_INCLUDES@ @GUI_CXXFLAGS@ + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/prs/YACSPrs_BlocNode.cxx b/src/prs/YACSPrs_BlocNode.cxx new file mode 100644 index 000000000..3cfe7a38a --- /dev/null +++ b/src/prs/YACSPrs_BlocNode.cxx @@ -0,0 +1,912 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 +// + +#include "YACSPrs_BlocNode.h" + +#include "YACSPrs_Def.h" +#include "YACSPrs_LoopNode.h" +#include "YACSPrs_SwitchNode.h" +#include "YACSPrs_Link.h" + +#include "SUIT_ResourceMgr.h" + +#include + +using namespace YACS::ENGINE; + +void drawText4(QPainter& thePainter, const QString& theText, + const QRect& theRect, int theHAlign = Qt::AlignAuto) +{ + int flags = theHAlign | Qt::AlignVCenter; + QRect r(theRect.x() + TEXT_MARGIN, theRect.y(), + theRect.width() - 2*TEXT_MARGIN, theRect.height()); + + QWMatrix aMat = thePainter.worldMatrix(); + if (aMat.m11() != 1.0) { + // for scaled picture only + QRect r1 = aMat.mapRect(r); + QFont saved = thePainter.font(); + QFont f(saved); + if (f.pointSize() == -1) { + f.setPixelSize((int)(f.pixelSize()*aMat.m11())); + } + else { + f.setPointSize((int)(f.pointSize()*aMat.m11())); + } + thePainter.save(); + QWMatrix m; + thePainter.setWorldMatrix(m); + thePainter.setFont(f); + thePainter.drawText(r1, flags, theText); + thePainter.setFont(saved); + thePainter.restore(); + } + else { + thePainter.drawText(r, flags, theText); + } +} + +/*! + * =========================== YACSPrs_BlocNode =========================== + !*/ + +YACSPrs_BlocNode::YACSPrs_BlocNode(SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACS::ENGINE::Node* theNode, + DisplayMode theDisplayMode, int theZ, + int theLeft, int theTop, int theWidth, int theHeight): + YACSPrs_ElementaryNode(theMgr, theCanvas, theNode), + myDisplayMode(theDisplayMode) +{ + printf("YACSPrs_BlocNode::YACSPrs_BlocNode\n"); + setX(theLeft); + setY(theTop); + + setNodeColor(BLOCNODE_COLOR); + setNodeSubColor(BLOCNODE_SUBCOLOR); + + setStoreColor(nodeColor()); + setStoreSubColor(nodeSubColor()); + + myResizing = false; + myResizeDirection = No; + + myWidth = theWidth; + myHeight = theHeight; + + if ( myDisplayMode == Expanded ) + { + if ( myPointMaster ) myWidth = myPointMaster->width() > theWidth ? myPointMaster->width() : theWidth; + else myWidth = theWidth; + + int anEmptyHeight = getTitleHeight() + getGateHeight() + 2*BLOCNODE_MARGIN; + myHeight = ( (anEmptyHeight > theHeight) ? anEmptyHeight : theHeight); + + setTitleHeight(getTitleHeight()+2*PORT_MARGIN); + + myContentMoving = true; + myBoundColor = BLOCNODERECT_COLOR; + + setZ(theZ); + + updateGates(); + } + else + { + myContentMoving = false; + setZ(2); + + update(); + + // not yet implemented + } +} + +YACSPrs_BlocNode::~YACSPrs_BlocNode() +{ + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + delete (*it); + myChildren.clear(); +} + +void YACSPrs_BlocNode::setChildren(std::set& theChildren) +{ + if ( myDisplayMode == Expanded ) + { + myChildren = theChildren; + // resize bounding rectangle if needed + int aMaxWidth=0, aMaxHeight=0; + int aX = (int)x(); + int aY = (int)y() + getTitleHeight(); + bool hasBlocChild = false; + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + { + if ( aMaxWidth < (*it)->maxWidth() ) aMaxWidth = (*it)->maxWidth(); + if ( aMaxHeight < (*it)->maxHeight() ) aMaxHeight = (*it)->maxHeight(); + YACSPrs_LoopNode* aLoop = dynamic_cast( *it ); + if ( aLoop ) + (*it)->moveBy( aX - (*it)->boundingRect().x() + (( 2*HOOKPOINT_SIZE > 3*TITLE_HEIGHT/2 ) ? ( 2*HOOKPOINT_SIZE - 3*TITLE_HEIGHT/2 ) : 0) + BLOCNODE_MARGIN, + aY - (*it)->boundingRect().y() + BLOCNODE_MARGIN ); + else + { + YACSPrs_BlocNode* aBloc = dynamic_cast( *it ); + if ( aBloc ) { + (*it)->moveBy( aX - (*it)->boundingRect().x() + HOOKPOINTGATE_SIZE + BLOCNODE_MARGIN, aY - (*it)->boundingRect().y() + BLOCNODE_MARGIN ); + hasBlocChild = true; + } + else + (*it)->moveBy( aX - (*it)->boundingRect().x() + 2*HOOKPOINT_SIZE + BLOCNODE_MARGIN, + aY - (*it)->boundingRect().y() + BLOCNODE_MARGIN ); + } + (*it)->setIsInBloc(true); + } + if ( aMaxWidth > myWidth ) myWidth = aMaxWidth + 2*BLOCNODE_MARGIN; + if ( aMaxHeight > myHeight ) myHeight = aMaxHeight + getTitleHeight() + getGateHeight() + 2*BLOCNODE_MARGIN; + + setZ(z()); + + updateGates(); + printf("Parent : %s. Number of children : %d\n",myEngine->getName().c_str(),myChildren.size()); + } +} + +void YACSPrs_BlocNode::setCanvas(QCanvas* theCanvas) +{ + QCanvasItem::setCanvas(theCanvas); + + if ( myDisplayMode == Expanded ) + { + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + { + (*it)->setCanvas(theCanvas); + (*it)->setArea(getAreaRect()); + } + } + else + { + // not yet implemented + } + + // set canvas to all ports + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + aPort->setCanvas(theCanvas); + + // set canvas to master point + if (myPointMaster) + { + myPointMaster->setCanvas(theCanvas); + QPoint aPnt = getConnectionMasterPoint(); + myPointMaster->setCoords(aPnt.x(), aPnt.y()); + } +} + +bool YACSPrs_BlocNode::isResizable(QPoint thePoint, int& theCursorType) +{ + if ( myDisplayMode == Expanded ) + { + theCursorType = 0; + QRect aRect = getRect(); + + int aM11 = (int)( getTMatrix().m11() < 1 ? 1/getTMatrix().m11() : 1 ); + int aM22 = (int)( getTMatrix().m22() < 1 ? 1/getTMatrix().m22() : 1 ); + + int aW = 8*aM11; int aShiftX = (aW-2)/2; + int aH = 8*aM22; int aShiftY = (aH-2)/2; + + QRect aLeft( (int)x()-aShiftX, (int)y()-aShiftY, aW, height()+aH); + QRect aRight( (int)x()+width()-aShiftX,(int)y()-aShiftY, aW, height()+aH); + QRect aTop( (int)x()-aShiftX, (int)y()-aShiftY, width()+aW,aH); + QRect aBottom((int)x()-aShiftX, (int)y()+height()-aShiftY,width()+aW,aH); + + if ( aTop.contains(thePoint) && aRight.contains(thePoint) ) { + theCursorType = Direction(TopRight); // 6 + return true; + } + if ( aBottom.contains(thePoint) && aLeft.contains(thePoint) ) { + theCursorType = Direction(BottomLeft); // 8 + return true; + } + if ( aTop.contains(thePoint) && aLeft.contains(thePoint) ) { + theCursorType = Direction(LeftTop); // 5 + return true; + } + if ( aBottom.contains(thePoint) && aRight.contains(thePoint) ) { + theCursorType = Direction(RightBottom); // 7 + return true; + } + if ( aTop.contains(thePoint) ) { + theCursorType = Direction(Top); // 2 + return true; + } + if ( aBottom.contains(thePoint) ) { + theCursorType = Direction(Bottom); // 4 + return true; + } + if ( aLeft.contains(thePoint) ) { + theCursorType = Direction(Left); // 1 + return true; + } + if ( aRight.contains(thePoint) ) { + theCursorType = Direction(Right); // 3 + return true; + } + return false; + } + else return false; +} + +bool YACSPrs_BlocNode::isResizing() +{ + if ( myDisplayMode == Expanded ) return myResizing; + else return false; +} + +void YACSPrs_BlocNode::beforeResizing(int theCursorType) +{ + if ( myDisplayMode == Expanded ) + { + myResizing = true; + myResizeDirection = Direction(theCursorType); + } +} + +void YACSPrs_BlocNode::resize(QPoint thePoint) +{ + if ( myDisplayMode == Expanded ) + { + if ( !checkArea(0,0,thePoint) ) return; + + QPoint aBottomP = thePoint + QPoint(0, ( myPointMaster ? myPointMaster->height()/2 : 0 )); + QPoint aLeftP = thePoint + QPoint(-HOOKPOINTGATE_SIZE, 0); + QPoint aRightP = thePoint + QPoint(HOOKPOINTGATE_SIZE, 0); + + myContentMoving = false; + int xP = thePoint.x(); + int yP = thePoint.y(); + switch (myResizeDirection) + { + case 1: // left edge + if ( xP < minXContent() && checkArea(0,0,aLeftP) ) { + myWidth += (int)x() - xP; + setX(xP); + } + break; + case 2: // top edge + if ( yP < minYContent() ) { + myHeight += (int)y() - yP; + setY(yP); + } + break; + case 3: // right edge + if ( xP > maxXContent() && checkArea(0,0,aRightP) ) + myWidth += xP - (int)x() - myWidth; + break; + case 4: // bottom edge + if ( yP > maxYContent() && checkArea(0,0,aBottomP) ) + myHeight += yP - (int)y() - myHeight; + break; + case 5: // left and top edges + if ( checkArea(0,0,aLeftP) ) + { + if ( xP < minXContent() ) { + myWidth += (int)x() - xP; + setX(xP); + } + if ( yP < minYContent() ) { + myHeight += (int)y() - yP; + setY(yP); + } + } + break; + case 6: // right and top edges + if ( checkArea(0,0,aRightP) ) + { + if ( xP > maxXContent() ) + myWidth += xP - (int)x() - myWidth; + if ( yP < minYContent() ) { + myHeight += (int)y() - yP; + setY(yP); + } + } + break; + case 7: // right and bottom edges + if ( checkArea(0,0,aBottomP) && checkArea(0,0,aRightP) ) + { + if ( xP > maxXContent() ) + myWidth += xP - (int)x() - myWidth; + if ( yP > maxYContent() ) + myHeight += yP - (int)y() - myHeight; + } + break; + case 8: // left and bottom edges + if ( checkArea(0,0,aLeftP) && checkArea(0,0,aBottomP) ) + { + if ( xP < minXContent() ) { + myWidth += (int)x() - xP; + setX(xP); + } + if ( yP > maxYContent() ) + myHeight += yP - (int)y() - myHeight; + } + break; + default: + break; + } + QPoint aPnt = getConnectionMasterPoint(); + myPointMaster->setCoords(aPnt.x(), aPnt.y()); + + updateGates(); + + if ( canvas() ) { + + QRect aChangedRect = getRect(); + aChangedRect.setRect(aChangedRect.x()-2, aChangedRect.y()-2, + aChangedRect.width()*2/*+4*/, aChangedRect.height()*2/*+4*/); + canvas()->setChanged(aChangedRect); + canvas()->update(); + } + + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + (*it)->setArea(getAreaRect()); + + myContentMoving = true; + } +} + +void YACSPrs_BlocNode::afterResizing() +{ + if ( myDisplayMode == Expanded ) myResizing = false; +} + +void YACSPrs_BlocNode::showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos) +{ +} + +int YACSPrs_BlocNode::rtti() const +{ + return 0;//YACSPrs_Canvas::Rtti_BlocNode; +} + +void YACSPrs_BlocNode::setVisible(bool b) +{ + QCanvasPolygonalItem::setVisible(b); + + if ( myDisplayMode == Expanded ) + { + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + (*it)->setVisible(b); + // set visibility to all ports + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + aPort->setVisible(b); + } + else + { + // not yet implemented + // set visibility to all ports + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + if (aPort->isVisible()) aPort->setVisible(b); + } + + // set visibility to master point + myPointMaster->setVisible(b); + updateLabelLink(); +} + +QPointArray YACSPrs_BlocNode::constructAreaPoints(int theW, int theH) const +{ + int w = theW+2; + int h = theH+1; // add width of pen + + if ( myDisplayMode == Expanded ) + { + QPointArray aPnts(4); + aPnts[0] = QPoint((int)x()-2, (int)y()-2) + QPoint(-NODEBOUNDARY_MARGIN/2,-NODEBOUNDARY_MARGIN/2); + aPnts[1] = aPnts[0] + QPoint(w, 0) + QPoint(NODEBOUNDARY_MARGIN,0); + aPnts[2] = aPnts[1] + QPoint(0, h) + QPoint(0,NODEBOUNDARY_MARGIN); + aPnts[3] = aPnts[0] + QPoint(0, h) + QPoint(0,NODEBOUNDARY_MARGIN); + return aPnts; + } + else + { + return QPointArray(); // not yet implemented + } +} + +void YACSPrs_BlocNode::moveBy(double dx, double dy) +{ + // for constraint nodes' moving inside the Bloc--> + if ( isCheckAreaNeeded() && !checkArea(dx,dy) ) return; + // <-- + + int aX = (int) (x()+dx); + int aY = (int) (y()+dy); + int xx = aX - (int)x(); + int yy = aY - (int)y(); + + if ( canvas() ) + { + int w = aX + width() + GRAPH_MARGIN; + int h = aY + height() + GRAPH_MARGIN; + if (canvas()->width() > w) w = canvas()->width(); + if (canvas()->height() > h) h = canvas()->height(); + if (canvas()->width() < w || canvas()->height() < h) + canvas()->resize(w, h); + } + + if ( myDisplayMode == Expanded ) + { + // move all children if mouse is in background of Bloc node in expanded mode + QCanvasPolygonalItem::moveBy(dx, dy); // move the bounding rectangle + if ( myContentMoving ) { + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + (*it)->setSelfMoving(false); // for move link's points as a content of moving Bloc node + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + { + (*it)->setArea(getAreaRect()); + (*it)->moveBy(xx, yy); + } + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + (*it)->setSelfMoving(true); // for move link's points as a content of moving Bloc node + } + + // update port's rectangle + updateGates(); + //YACSPrs_Port* aPort; + //for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + // aPort->moveBy(xx, yy); + } + else + { + QCanvasPolygonalItem::moveBy(dx, dy); + + // not yet implemented + + // update port's rectangle + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + aPort->moveBy(xx, yy); + } + + myPointMaster->moveBy(dx, dy); + if ( myLabelLink ) myLabelLink->moveByNode(this, (int)dx, (int)dy); + + if ( isSelected() && canvas() && isMoving() ) + { + QRect aRect = boundingRect(); + QPoint aShift(20,20); + aRect.setTopLeft(aRect.topLeft()-aShift); + aRect.setBottomRight(aRect.bottomRight()+aShift); + canvas()->setChanged(aRect); + canvas()->update(); + } +} + +void YACSPrs_BlocNode::setZ(double z) +{ + QCanvasItem::setZ(z); + + if ( myDisplayMode == Expanded ) + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) { + if ( dynamic_cast( *it ) ) (*it)->setZ(z+4); + else (*it)->setZ(z+3); + } + else + { + // not yet implemented + } + + // update port's + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + aPort->setZ(z,false); + + if ( myPointMaster ) myPointMaster->setZ(z); +} + +void YACSPrs_BlocNode::updateGates() +{ + bool aDisp = isVisible(); + if (aDisp) hide(); + + if ( myDisplayMode == Expanded ) + { + QRect aRect = getRect(); + int aPRectWidth = (int)(aRect.width()/2) - 2*PORT_MARGIN; + + int ix = aRect.left() + PORT_MARGIN;// + 1; + int iy = aRect.bottom()-getGateHeight() + PORT_MARGIN;// + 1; + int ox = ix + aPRectWidth + 2*PORT_MARGIN + 2; // add pen width + int oy = aRect.bottom()-getGateHeight() + PORT_MARGIN;// + 1; + + if ( myPortList.isEmpty() ) + { // create (and update) + // input Gate + YACSPrs_InOutPort* anInPort = new YACSPrs_InOutPort(myMgr,canvas(),myEngine->getInGate(),this); + anInPort->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT)); + anInPort->setColor(nodeSubColor()); + anInPort->setStoreColor(nodeSubColor()); + myPortList.append(anInPort); + + // output Gate + YACSPrs_InOutPort* anOutPort = new YACSPrs_InOutPort(myMgr,canvas(),myEngine->getOutGate(),this); + anOutPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT)); + anOutPort->setColor(nodeSubColor()); + anOutPort->setStoreColor(nodeSubColor()); + myPortList.append(anOutPort); + } + else + { // only update + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + YACSPrs_InOutPort* anIOPort = dynamic_cast( aPort ); + if ( anIOPort && anIOPort->isGate() ) + { + anIOPort->setStoreColor(nodeSubColor()); + if ( anIOPort->isInput() ) // test input ports + anIOPort->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT), !isSelfMoving(), myArea); + else // test output ports + anIOPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT), !isSelfMoving(), myArea); + } + } + } + } + else + { + // not yet implemented + } + + if (aDisp) show(); +} + +int YACSPrs_BlocNode::width() const +{ + if ( myDisplayMode == Expanded ) return myWidth; + else return 0; // not yet implemented +} + +int YACSPrs_BlocNode::height() const +{ + if ( myDisplayMode == Expanded ) return myHeight; + else return 0; // not yet implemented +} + +void YACSPrs_BlocNode::resize(int theWidth, int theHeight) +{ + if ( myDisplayMode == Expanded ) + { + myContentMoving = false; + + myWidth = theWidth; + myHeight = theHeight; + + QPoint aPnt = getConnectionMasterPoint(); + myPointMaster->setCoords(aPnt.x(), aPnt.y()); + + updateGates(); + + if ( canvas() ) { + + QRect aChangedRect = getRect(); + aChangedRect.setRect(aChangedRect.x()-2, aChangedRect.y()-2, + aChangedRect.width()*2/*+4*/, aChangedRect.height()*2/*+4*/); + canvas()->setChanged(aChangedRect); + canvas()->update(); + } + + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + (*it)->setArea(getAreaRect()); + + myContentMoving = true; + } +} + +int YACSPrs_BlocNode::minXContent() +{ + if ( myDisplayMode == Expanded ) + { + int aMinX = (!myChildren.empty()) ? (int)((*myChildren.begin())->boundingRect().left()) : boundingRect().left() + 2*BLOCNODE_MARGIN; + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + if ( aMinX > (*it)->boundingRect().left() ) aMinX = (int)( (*it)->boundingRect().left() ); + + aMinX -= 2*HOOKPOINT_SIZE + BLOCNODE_MARGIN; + return aMinX; + } + return 0; +} + +int YACSPrs_BlocNode::maxXContent() +{ + if ( myDisplayMode == Expanded ) + { + int aMaxX = (!myChildren.empty()) ? (int)((*myChildren.begin())->boundingRect().right()) : boundingRect().right() - 2*BLOCNODE_MARGIN; + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + if ( aMaxX < (*it)->boundingRect().right() ) aMaxX = (int)( (*it)->boundingRect().right() ); + + aMaxX += 2*HOOKPOINT_SIZE + BLOCNODE_MARGIN; + return aMaxX; + } + return 0; +} + +int YACSPrs_BlocNode::minYContent() +{ + if ( myDisplayMode == Expanded ) + { + int aMinY = (!myChildren.empty()) ? (int)((*myChildren.begin())->boundingRect().top()) : (int)x(); + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + if ( aMinY > (*it)->boundingRect().top() ) aMinY = (int)( (*it)->boundingRect().top() ); + + aMinY -= getTitleHeight() + BLOCNODE_MARGIN; + return aMinY; + } + return 0; +} + +int YACSPrs_BlocNode::maxYContent() +{ + if ( myDisplayMode == Expanded ) + { + int aMaxY = (!myChildren.empty()) ? (int)((*myChildren.begin())->boundingRect().bottom()) : (int)x(); + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + if ( aMaxY < (*it)->boundingRect().bottom() ) aMaxY = (int)( (*it)->boundingRect().bottom() ); + + aMaxY += getGateHeight() + (myPointMaster ? myPointMaster->height()/2 : 0 ) + BLOCNODE_MARGIN; + return aMaxY; + } + return 0; +} + +int YACSPrs_BlocNode::minWidth() const +{ + if ( myDisplayMode == Expanded ) + { + int aMinWidth = myPointMaster ? myPointMaster->width() : 0; + int aMinX = (!myChildren.empty()) ? (int)((*myChildren.begin())->x()) : (int)x(); + int aMaxX = aMinX; + int aChildMaxWidth = 0; + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + { + if ( aMinX > (*it)->x() ) aMinX = (int)( (*it)->x() ); + if ( aMaxX < (*it)->x() ) aMaxX = (int)( (*it)->x() ); + if ( aChildMaxWidth < (*it)->maxWidth() ) aChildMaxWidth = (*it)->maxWidth(); + } + if ( aMinWidth < aMaxX - aMinX + aChildMaxWidth ) aMinWidth = aMaxX - aMinX + aChildMaxWidth + 2*BLOCNODE_MARGIN; + return aMinWidth; + } + else + { + return width();// + sliseWidth; // not yet implemented + } +} + +int YACSPrs_BlocNode::minHeight() const +{ + if ( myDisplayMode == Expanded ) + { + int aMinHeight = getTitleHeight() + getGateHeight() + 2*BLOCNODE_MARGIN; + int aMinY = (!myChildren.empty()) ? (int)((*myChildren.begin())->y()) : (int)y(); + int aMaxY = aMinY; + int aChildMaxHeight = 0; + for ( std::set::iterator it = myChildren.begin(); it != myChildren.end(); it++ ) + { + if ( aMinY > (*it)->y() ) aMinY = (int)( (*it)->y() ); + if ( aMaxY < (*it)->y() ) aMaxY = (int)( (*it)->y() ); + if ( aChildMaxHeight < (*it)->maxHeight() ) aChildMaxHeight = (*it)->maxHeight(); + + YACSPrs_LoopNode* aLoop = dynamic_cast( *it ); + if ( aLoop ) aChildMaxHeight -= 3*TITLE_HEIGHT/2; + else + { + YACSPrs_SwitchNode* aSwitch = dynamic_cast( *it ); + if ( aSwitch ) aChildMaxHeight -= 2*TITLE_HEIGHT; + } + + } + if ( aMinHeight < aMaxY - aMinY + aChildMaxHeight ) aMinHeight += aMaxY - aMinY + aChildMaxHeight; + return aMinHeight; + } + else + { + return height();// + sliseWidth; // not yet implemented + } +} + +int YACSPrs_BlocNode::maxWidth() const +{ + if ( myDisplayMode == Expanded ) + { + return boundingRect().width() + 2*HOOKPOINTGATE_SIZE; + } + else + { + return width();// + sliseWidth; // not yet implemented + } +} + +int YACSPrs_BlocNode::maxHeight() const +{ + if ( myDisplayMode == Expanded ) + { + return YACSPrs_ElementaryNode::maxHeight(); + } + else + { + return YACSPrs_ElementaryNode::maxHeight();// + sliseWidth; // not yet implemented + } +} + +QRect YACSPrs_BlocNode::getTitleRect() const +{ + if ( myDisplayMode == Expanded ) + return QRect((int)x(), (int)y(), width(), getTitleHeight()); + else + return YACSPrs_ElementaryNode::getTitleRect(); +} + +QRect YACSPrs_BlocNode::getGateRect() const +{ + if ( myDisplayMode == Expanded ) + return QRect((int)x(), getRect().bottom()-getGateHeight(), width(), getGateHeight()); + else + return YACSPrs_ElementaryNode::getGateRect(); +} + +QRect YACSPrs_BlocNode::getAreaRect() const +{ + if ( myDisplayMode == Expanded ) + { + QPoint aShift(BLOCNODE_MARGIN/2, BLOCNODE_MARGIN/2); + QPoint aTopLeft = getTitleRect().bottomLeft() + aShift; + QPoint aBottomRight = getGateRect().topRight() - aShift; + QRect anArea(aTopLeft, aBottomRight); + return anArea; + } + return QRect(); +} + +bool YACSPrs_BlocNode::checkArea(double dx, double dy, QPoint thePoint) +{ + if ( myDisplayMode == Expanded ) + { + // for constraint nodes' moving inside the Bloc--> + if ( !myIsInBloc ) return true; + + if ( !thePoint.isNull() ) + if ( myArea.isValid() && myArea.contains(thePoint,true) ) return true; + else return false; + + QRect aRect = boundingRect(); + aRect.moveBy((int)dx, (int)dy); + aRect.setRect(aRect.x()-HOOKPOINTGATE_SIZE, aRect.y() + NODEBOUNDARY_MARGIN/2, maxWidth(), maxHeight()); + if ( myArea.isValid() && myArea.contains(aRect) ) + return true; + return false; + // <-- + } + return true; +} + +void YACSPrs_BlocNode::drawShape(QPainter& thePainter) +{ + if ( myDisplayMode == Expanded ) + { + drawFrame(thePainter); + drawTitle(thePainter); + drawGate(thePainter); + } + else + { + // not yet implemented + } +} + +void YACSPrs_BlocNode::drawTitle(QPainter& thePainter) +{ + QPen savedP = thePainter.pen(); + thePainter.setPen(QPen(myBoundColor, 2, Qt::SolidLine)); + thePainter.drawLine((int)x(), (int)(y()+getTitleHeight()), (int)(x()+width()), (int)(y()+getTitleHeight())); + + QBrush savedB = thePainter.brush(); + thePainter.setBrush(nodeSubColor()); + thePainter.setPen(thePainter.brush().color().dark(140)); + + QRect aRoundRect = getTitleRect(); + aRoundRect.setRect(aRoundRect.x() + PORT_MARGIN, aRoundRect.y() + PORT_MARGIN, + aRoundRect.width() - 2*PORT_MARGIN, aRoundRect.height() - 2*PORT_MARGIN); + thePainter.drawRoundRect(aRoundRect,myXRnd,myYRnd); + + thePainter.setPen(Qt::white); + drawText4(thePainter, QString(myEngine->getName()), aRoundRect, Qt::AlignHCenter); + + thePainter.setBrush(savedB); + thePainter.setPen(savedP); +} + +void YACSPrs_BlocNode::drawGate(QPainter& thePainter) +{ + if ( myDisplayMode == Expanded ) + { + QPen savedP = thePainter.pen(); + thePainter.setPen(QPen(myBoundColor, 2, Qt::SolidLine)); + + QRect aRect = getRect(); + int aGateTop = aRect.bottom()-getGateHeight(); + thePainter.drawLine(aRect.left(), aGateTop, aRect.right(), aGateTop); + + int x0 = (aRect.left() + aRect.right())/2; + thePainter.drawLine(x0, aGateTop, x0, aRect.bottom()); + + int aRRectWidth = x0 - aRect.left() - 2*PORT_MARGIN; + //QRect aTRect = getTitleRect(); + //int aXRnd = aTRect.width()*myXRnd/aRRectWidth; + //int aYRnd = aTRect.height()*myYRnd/PORT_HEIGHT; + + thePainter.setPen(nodeSubColor()); + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + if ( (YACSPrs_InOutPort*)aPort && ((YACSPrs_InOutPort*)aPort)->isGate() ) + aPort->draw(thePainter,myXRnd,myYRnd);//aXRnd,aYRnd); + + thePainter.setPen(savedP); + } + else + { + // not yet implemented + } +} + +void YACSPrs_BlocNode::drawFrame(QPainter& thePainter) +{ + if ( myDisplayMode == Expanded ) + { + QBrush savedB = thePainter.brush(); + thePainter.setBrush(nodeColor());/*NoBrush*/ + + QPen savedP = thePainter.pen(); + thePainter.setPen(QPen(myBoundColor, 2, Qt::DashLine)); + + thePainter.drawRect(getRect()); + + thePainter.setPen(savedP); + thePainter.setBrush(savedB); + + // draw bounding nodes' polygon if node is currently selected + if ( isSelected() ) drawBoundary(thePainter,2); + } + else + { + // not yet implemented + } +} + +QString YACSPrs_BlocNode::getToolTipText(const QPoint& theMousePos, QRect& theRect) const +{ + // Check if the tooltip for ports is needed + if (getBodyRect().contains(theMousePos, true) || getGateRect().contains(theMousePos, true)) + return YACSPrs_ElementaryNode::getToolTipText(theMousePos,theRect); + + QString aText = QString(""); + aText += QString("Name: %1\n").arg(getEngine()->getName()); + aText += QString("Type: %1\n").arg("Block node"); + theRect = getTitleRect(); + theRect = theRect.unite(getAreaRect()); + return aText; +} diff --git a/src/prs/YACSPrs_BlocNode.h b/src/prs/YACSPrs_BlocNode.h new file mode 100644 index 000000000..bd9f425f3 --- /dev/null +++ b/src/prs/YACSPrs_BlocNode.h @@ -0,0 +1,125 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSPRS_BLOCNODE_H +#define YACSPRS_BLOCNODE_H + +#include "YACSPrs_ElementaryNode.h" + +#include + +class SUIT_ResourceMgr; + +/*! Presentation for the Bloc node. Implement expanded mode. + */ +class YACSPrs_BlocNode : public YACSPrs_ElementaryNode { + public: + typedef enum { Collapsed, Expanded } DisplayMode; + + YACSPrs_BlocNode( SUIT_ResourceMgr*, QCanvas*, YACS::ENGINE::Node*, + DisplayMode theDisplayMode=Expanded, + int theZ=0, + int theLeft=0, int theTop=0, + int theWidth=0, int theHeight=0); + virtual ~YACSPrs_BlocNode(); + + DisplayMode getDisplayMode() const { return myDisplayMode; } + + void setChildren(std::set& theChildren); + std::set getChildren() const { return myChildren; } + + virtual void setCanvas(QCanvas* theCanvas); + + /* reimplement functions from QxGraph_ActiveItem */ + virtual bool isMoveable() { return true; } + virtual void beforeMoving() { myZ = z(); setMoving(true); /*setZ(myZ+100);*/ } + virtual void afterMoving() { setMoving(false); setZ(myZ); canvas()->update(); } + virtual bool isResizable(QPoint thePoint, int& theCursorType); + virtual bool isResizing(); + virtual void beforeResizing(int theCursorType); + virtual void resize(QPoint thePoint); + virtual void afterResizing(); + virtual void showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos = QPoint()); + + virtual int rtti() const; + + virtual void setVisible(bool b); + + virtual QPointArray constructAreaPoints(int theW, int theH) const; + void moveBy(double dx, double dy); + void setZ(double z); + + virtual void updateGates(); + + virtual int width() const; + virtual int height() const; + void resize(int theWidth, int theHeight); + + int minXContent(); + int maxXContent(); + + int minYContent(); + int maxYContent(); + + int minWidth() const; + int minHeight() const; + + virtual int maxWidth() const; + virtual int maxHeight() const; + + virtual QRect getTitleRect() const; + virtual QRect getGateRect() const; + + // for constraint nodes' moving inside the Bloc--> + QRect getAreaRect() const; + virtual bool checkArea(double dx, double dy, QPoint thePoint=QPoint()); + // <-- + + virtual QString getToolTipText(const QPoint& theMousePos, QRect& theRect) const; + + protected: + virtual void drawShape(QPainter& thePainter); + + virtual void drawTitle(QPainter& thePainter); + virtual void drawGate(QPainter& thePainter); + virtual void drawFrame(QPainter& thePainter); + + private: + std::set myChildren; + + DisplayMode myDisplayMode; + + // myColor here is the color of the rectangle bounds (expanded mode) or node color (collapsed mode) + + // for expanded display mode--> + + QColor myBoundColor; // color for dashed bounding box + + int myHeight; + + bool myResizing; // resize or not in the current moment + bool myContentMoving; // move or not the content of Bloc during resizing + + typedef enum { No=0, Left, Top, Right, Bottom, + LeftTop, TopRight, RightBottom, BottomLeft } Direction; + Direction myResizeDirection; // horiz., vert. or diagonals + + // <-- +}; + +#endif diff --git a/src/prs/YACSPrs_Def.h b/src/prs/YACSPrs_Def.h new file mode 100644 index 000000000..a34990404 --- /dev/null +++ b/src/prs/YACSPrs_Def.h @@ -0,0 +1,88 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSPRS_DEF_H +#define YACSPRS_DEF_H + +#define GRAPH_MARGIN 50 + +#define NODE_WIDTH 266 //160 +#define NODE_COLOR QColor(255,249,147) +#define NODE_MARGIN 4 +#define NODE_SPACE 2 + +#define SERVICENODE_COLOR QColor(255,255,255) +#define SERVICENODE_SUBCOLOR QColor(85,85,255) + +#define INLINENODE_COLOR QColor(255,255,255) +#define INLINENODE_SUBCOLOR QColor(12,131,30) + +#define IFNODE_COLOR QColor(255,255,255) +#define IFNODE_SUBCOLOR QColor(255,170,0) + +#define SWITCHNODE_COLOR QColor(255,255,255) +#define SWITCHNODE_SUBCOLOR QColor(255,99,38) + +#define LOOPNODE_COLOR QColor(255,255,255) +#define LOOPNODE_SUBCOLOR QColor(236,1,107) +#define LOOPNODE_BRACKETCOLOR QColor(255,255,0) + +#define BLOCNODE_COLOR QColor(221,255,221) +#define BLOCNODE_SUBCOLOR QColor(131,0,0) +#define BLOCNODERECT_COLOR QColor(0,0,127) +#define BLOCNODE_MARGIN 4 + +#define NODEBOUNDARY_MARGIN 2 + +#define NODE_HILIGHT_COLOR QColor(222,222,222) + +#define TITLE_HEIGHT 20 +#define TITLE_COLOR QColor(63, 213, 255) + +#define PIXMAP_HEIGHT TITLE_HEIGHT*3 +#define PIXMAP_MARGIN 4 + +#define PORT_WIDTH 75 +#define PORT_HEIGHT 20 +#define PORT_MARGIN 4 +#define PORT_SPACE 2 + +#define LABELPORT_COLOR QColor(170,0,0) + +#define PORT_HILIGHT_COLOR QColor(222,222,222) + +#define LINKPOINT_SIZE 5 +#define LINKEDGE_WIDTH 2 +#define LINKDRAW_COLOR QColor(0,0,127) +#define LINK_HILIGHT_COLOR QColor(222,222,222) +#define LINK_SELECT_COLOR QColor(0,0,0) + +#define LABELLINKDRAW_COLOR QColor(170,0,0) + +#define HOOKPOINT_SIZE 10 +#define HOOKPOINTGATE_SIZE 14 +#define HOOKPOINTMASTER_SIZE 66 +#define HOOK_COLOR QColor(0,0,127) +#define HOOK_HILIGHT_COLOR LINK_HILIGHT_COLOR +#define HOOK_SELECT_COLOR LINK_SELECT_COLOR + +#define TEXT_MARGIN 5 +#define MARGIN 2 + +#endif diff --git a/src/prs/YACSPrs_ElementaryNode.cxx b/src/prs/YACSPrs_ElementaryNode.cxx new file mode 100644 index 000000000..96ea85bdf --- /dev/null +++ b/src/prs/YACSPrs_ElementaryNode.cxx @@ -0,0 +1,2294 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 +// + +#include + +#include "YACSPrs_ElementaryNode.h" + +#include "YACSPrs_Link.h" +#include "YACSPrs_Def.h" + +#include "SUIT_ResourceMgr.h" + +#include +//#include // for states animation + +#include +#include +#include +#include +#include +#include +#include +#include +#include // for SeqAnyInputPort +#include +#include +#include +#include + +using namespace YACS::ENGINE; + +using namespace std; +#include +#include + +void drawText(QPainter& thePainter, const QString& theText, + const QRect& theRect, int theHAlign = Qt::AlignAuto) +{ + int flags = theHAlign | Qt::AlignVCenter; + QRect r(theRect.x() + TEXT_MARGIN, theRect.y(), + theRect.width() - 2*TEXT_MARGIN, theRect.height()); + + QWMatrix aMat = thePainter.worldMatrix(); + if (aMat.m11() != 1.0) { + // for scaled picture only + QRect r1 = aMat.mapRect(r); + QFont saved = thePainter.font(); + QFont f(saved); + if (f.pointSize() == -1) { + f.setPixelSize((int)(f.pixelSize()*aMat.m11())); + } + else { + f.setPointSize((int)(f.pointSize()*aMat.m11())); + } + thePainter.save(); + QWMatrix m; + thePainter.setWorldMatrix(m); + thePainter.setFont(f); + thePainter.drawText(r1, flags, theText); + thePainter.setFont(saved); + thePainter.restore(); + } + else { + thePainter.drawText(r, flags, theText); + } +} + +char * toString(CORBA::Any* theAny, QString& theRetStr) +{ + if ( !theAny ) theRetStr += QString("< ? >"); + else + { + CORBA::Any anAny = *theAny; + if ( !anAny.value() ) theRetStr += QString("< ? >"); + else + { + ostringstream astr; + const char * retstr; + int startstr = 0; + switch ( anAny.type()->kind() ) + { + case CORBA::tk_string: { + anAny >>= retstr; + theRetStr += QString(retstr); + break; + } + case CORBA::tk_long: { + CORBA::Long l; + anAny >>= l; + astr << l << ends; + theRetStr += QString(astr.str()); + break; + } + case CORBA::tk_double: { + double d; + anAny >>= d; + astr << d << ends; + //astr << setw(25) << setprecision(18) << d << ends; + QString aRetStr = QString(astr.str()); + int i = 0; + while ( i < (int ) theRetStr.length() && theRetStr.at(i++) == ' ' ) { + startstr = i; + } + theRetStr += aRetStr.mid(startstr,aRetStr.length()); + break; + } + case CORBA::tk_sequence: { + theRetStr += QString("["); + + CORBA::Long aSeqLength = 0; + *(anAny.type()->parameter(1)) >>= aSeqLength; + + if ( aSeqLength == 0 ) + { + theRetStr += QString(" ]"); + break; + } + + // TO DO : implement recursion for the sequence type + /*CORBA::TypeCode* aType; + *(anAny.type()->parameter(0)) >>= aType; + switch ( aType->kind() ) + { + case CORBA::tk_string: { + printf("StringElem\n"); + CORBA::StringSeq* aStringSeq; + anAny >>= aStringSeq; + for (int i=0; i < aSeqLength; i++) + { + CORBA::Any anArg; + anArg <<= aStringSeq[i]; + toString( &anArg, theRetStr ); + if ( i < aSeqLength-1 ) theRetStr += QString(","); + } + break; + } + case CORBA::tk_double: { + printf("DoubleElem\n"); + CORBA::DoubleSeq* aDoubleSeq; + anAny >>= aDoubleSeq; + for (int i=0; i < aSeqLength; i++) + { + CORBA::Any anArg; + anArg <<= aDoubleSeq[i]; + toString( &anArg, theRetStr ); + if ( i < aSeqLength-1 ) theRetStr += QString(","); + } + break; + } + case CORBA::tk_sequence: { + printf("SequenceElem\n"); + CORBA::Any* aSequenceSeq; + anAny >>= aSequenceSeq; + for (int i=0; i < aSeqLength; i++) + { + CORBA::Any anArg; + anArg <<= aSequenceSeq[i]; + toString( &anArg, theRetStr ); + if ( i < aSeqLength-1 ) theRetStr += QString(","); + } + break; + } + default: { + printf("DefaultElem\n"); + theRetStr += QString("< ? >"); + break; + } + }*/ + theRetStr += QString("]"); + break; + } + case CORBA::tk_objref: { + /*CORBA::Object_ptr obj; + try { + anAny >>= (CORBA::Any::to_object ) obj; + theRetStr += QString( _Orb->object_to_string( obj ) ); + } + catch ( ... ) { + theRetStr += QString("object_to_string catched "); + }*/ + theRetStr += QString("Objref"); + break; + } + default: { + theRetStr += QString("< ? >"); + break; + } + } + } + } +} + +void toString(PyObject* theObject, QString& theRetStr) +{ + if ( !theObject ) theRetStr += QString("< ? >"); + + ostringstream aStr; + if ( PyString_CheckExact(theObject) ) + theRetStr += QString( PyString_AsString(theObject) ); + else if ( PyLong_CheckExact(theObject) ) + { + long aVal = PyLong_AsLong(theObject); + aStr << aVal << ends; + theRetStr += QString( aStr.str() ); + } + else if ( PyInt_CheckExact(theObject) ) + { + long aVal = PyInt_AsLong(theObject); + aStr << aVal << ends; + theRetStr += QString( aStr.str() ); + } + else if ( PyBool_Check(theObject) ) + theRetStr += QString( (theObject == Py_True) ? "true" : "false" ); + else if ( PyFloat_CheckExact(theObject) ) + { + double aVal = PyFloat_AsDouble(theObject); + aStr << aVal << ends; + theRetStr += QString( aStr.str() ); + } + else if ( PyList_CheckExact(theObject) ) + { + theRetStr += QString("["); + for (int i=0; i < PyList_Size(theObject); i++) + { + toString( PyList_GetItem(theObject, i), theRetStr ); + if ( i < PyList_Size(theObject)-1 ) theRetStr += QString(","); + } + theRetStr += QString("]"); + } + //else if ( ... ) // objref case + else + theRetStr += QString("< ? >"); +} + +void toString(Any* theAny, QString& theValue) +{ + if ( !theAny ) theValue += QString("< ? >"); + else if ( theAny->getType() ) + { + DynType aKind = theAny->getType()->kind(); + switch (aKind) + { + case Double: + theValue += QString::number(theAny->getDoubleValue()); + break; + case Int: + theValue += QString::number(theAny->getIntValue()); + break; + case String: + theValue += QString(theAny->getStringValue()); + break; + case Bool: + theValue += QString(theAny->getBoolValue()?"true":"false"); + break; + case Objref: + theValue += QString("Objref"); /// ? + break; + case Sequence: { + SequenceAny* aSeqAny = dynamic_cast( theAny ); + if ( aSeqAny ) + { + theValue += QString("["); + for (int i=0; i < aSeqAny->size(); i++) + { + toString( (*aSeqAny)[i], theValue ); + if ( i < aSeqAny->size()-1 ) theValue += QString(","); + } + theValue += QString("]"); + } + break; + } + case None: + default: + theValue += QString(""); + break; + } + } +} + +/*! + * =========================== YACSPrs_ElementaryNode =========================== + !*/ + +YACSPrs_ElementaryNode::YACSPrs_ElementaryNode(SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACS::ENGINE::Node* theNode): + QxGraph_ActiveItem(), + QCanvasPolygonalItem(theCanvas), + myMgr(theMgr), + myEngine(theNode), + myLabelLink(0), + myHilightedPort(0), + mySelectedPort(0) +{ + printf("YACSPrs_ElementaryNode::YACSPrs_ElementaryNode\n"); + myWidth = NODE_WIDTH; + if (2*(PORT_WIDTH+PORT_MARGIN) > myWidth) + myWidth = 2*(PORT_WIDTH+PORT_MARGIN); + + myTitleHeight = TITLE_HEIGHT; + myStatusHeight = TITLE_HEIGHT; + myTimeHeight = TITLE_HEIGHT; + myPortHeight = 2*PORT_MARGIN; + myGateHeight = PORT_HEIGHT + 2*PORT_MARGIN; + + myStoreColor = myColor = myMgr->colorValue("QxGraph", "NodeBody", NODE_COLOR); + myStoreSubColor = mySubColor = myMgr->colorValue( "QxGraph", "Title", TITLE_COLOR ); + + QRect aTRect = getTitleRect(); + myXRnd = 50*aTRect.height()/aTRect.width(); + myYRnd = 50; + + myMoving = false; + mySelfMoving = true; + mySelected = false; + + myIsCheckAreaNeeded = true; + + myIsInBloc = false; + myArea = QRect(); + + myTime = QString("00:00:00"); + myTimeIteration = 0; + myPercentage = -1.; + + myStarted = false; + myFinished = false; + + /*QValueList aPMList; + aPMList.append(myStatePixmap); + static QCanvasPixmapArray aPMArray(aPMList); + mySprite = new QCanvasSprite( &aPMArray, theCanvas ); + //mySprite->setAnimated(true); + mySprite->setZ(1); + mySprite->show();*/ + + myPointMaster = new YACSPrs_Hook(myMgr, canvas(), this, false, false, true); + + setZ(2); + //updatePorts(); // create presentations for all ports of node, + // must be called only in constructor of derived classes (because this is the base prs class) + // or createPrs() on demand and not in constructor!!! + //moveBy(2*HOOKPOINT_SIZE,0); // move node only is subclasses, because moveBy() function calls + // updatePorts() method corresponding to this subclass +} + +YACSPrs_ElementaryNode::~YACSPrs_ElementaryNode() +{ + myPortList.setAutoDelete(true); + myPortList.clear(); + + if (myPointMaster) delete myPointMaster; +} + +YACSPrs_InOutPort* YACSPrs_ElementaryNode::getPortPrs(YACS::ENGINE::Port* thePort) +{ + YACSPrs_InOutPort* aRetPort = 0; + for (YACSPrs_Port* aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + YACSPrs_InOutPort* anIOPort = dynamic_cast( aPort ); + if ( anIOPort && anIOPort->getEngine() == thePort ) + aRetPort = anIOPort; + } + return aRetPort; +} + +void YACSPrs_ElementaryNode::setCanvas(QCanvas* theCanvas) +{ + QCanvasItem::setCanvas(theCanvas); + + // set canvas to all ports + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + aPort->setCanvas(theCanvas); + + // set canvas to master point + if (myPointMaster) + { + myPointMaster->setCanvas(theCanvas); + QPoint aPnt = getConnectionMasterPoint(); + myPointMaster->setCoords(aPnt.x(), aPnt.y()); + } + + // set canvas to in/out points + //myPointIn->setCanvas(theCanvas); + //myPointOut->setCanvas(theCanvas); +} + +void YACSPrs_ElementaryNode::removeLabelLink() +{ + if ( myLabelLink ) myLabelLink = 0; +} + +void YACSPrs_ElementaryNode::updateLabelLink() +{ + if ( myLabelLink ) myLabelLink->moveByNode(this); +} + +void YACSPrs_ElementaryNode::beforeMoving() +{ + myZ = z(); + setMoving(true); + setZ(myZ+100); +} + +void YACSPrs_ElementaryNode::afterMoving() +{ + setMoving(false); + setZFromLinks(myZ); + canvas()->update(); +} + +void YACSPrs_ElementaryNode::hilight(const QPoint& theMousePos, const bool toHilight) +{ + // process the hilighting for node and ports + if (toHilight) + { + if (getBodyRect().contains(theMousePos, true) || getGateRect().contains(theMousePos, true)) { + // process ports + QPtrList aPortList = getPortList(); + for (YACSPrs_Port* aPort = aPortList.first(); aPort; aPort = aPortList.next()) { + QRect aPortRect = aPort->getPortRect(); + aPortRect.setTop(aPortRect.top() - PORT_MARGIN); + aPortRect.setBottom(aPortRect.bottom() + PORT_MARGIN); + if (aPortRect.contains(theMousePos, true)) { + if ( aPort == myHilightedPort ) return; + + if ( myHilightedPort ) + myHilightedPort->setColor(myHilightedPort->storeColor(), false, true); + else + setNodeColor( storeColor() ); + + if ( aPort->isSelected()) { + myHilightedPort = 0; + return; + } + + QColor aColor = myMgr->colorValue("YACSGui", "port_hilight_color", PORT_HILIGHT_COLOR); + aPort->setColor(aColor, false, true); + myHilightedPort = aPort; + return; + } + } + } + + if ( myHilightedPort ) { + QColor aColor; + if (isSelected()) { + aColor = nodeSubColor(); + if (dynamic_cast(myHilightedPort)) + aColor = aColor.dark(140); + } + else + aColor = myHilightedPort->storeColor(); + + myHilightedPort->setColor(aColor, false, true); + myHilightedPort = 0; + } + + // hilight node + if (!isSelected()) { + QColor aColor = myMgr->colorValue("YACSGui", "node_hilight_color", NODE_HILIGHT_COLOR); + if (aColor != nodeColor()) + setNodeColor(aColor); + } + } + else + { + if ( myHilightedPort ) { + myHilightedPort->setColor(myHilightedPort->storeColor(), false, true); + myHilightedPort = 0; + } + else + setNodeColor( storeColor() ); + } +} + +void YACSPrs_ElementaryNode::select(const QPoint& theMousePos, const bool toSelect) +{ + if ( toSelect ) + { + // unhilight the item under the mouse cursor + hilight(theMousePos, false); + + bool isOnPort = false; + if (getBodyRect().contains(theMousePos, true) || getGateRect().contains(theMousePos, true)) + { + // process ports + QPtrList aPortList = getPortList(); + for (YACSPrs_Port* aPort = aPortList.first(); aPort; aPort = aPortList.next()) { + if (aPort->getPortRect().contains(theMousePos, true)) { + isOnPort = true; + if ( aPort != mySelectedPort ) + { + if ( mySelectedPort ) + { + mySelectedPort->setSelected(false); + mySelectedPort->setColor(mySelectedPort->storeColor(), false, true, true); + } + else + { + setSelected(false); + setNodeSubColor( myStoreSubColor, true ); + } + aPort->setSelected(true); + aPort->setColor(aPort->Color().dark(130), false, true, true); + mySelectedPort = aPort; + } + break; + } + } + } + + if ( !isOnPort ) + { + if ( mySelectedPort ) + { + mySelectedPort->setSelected(false); + mySelectedPort = 0; + } + + if ( myStoreSubColor.dark(130) != mySubColor ) + { + myStoreSubColor = mySubColor; + + setSelected(true); + setNodeSubColor( nodeSubColor().dark(130), true ); + } + } + } + else + { + if ( mySelectedPort ) { + mySelectedPort->setSelected(false); + mySelectedPort->setColor(mySelectedPort->storeColor(), false, true, true); + mySelectedPort = 0; + } + else { + setSelected(false); + setNodeSubColor( myStoreSubColor, true ); + } + } +} + +void YACSPrs_ElementaryNode::showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos) +{ +} + +QString YACSPrs_ElementaryNode::getToolTipText(const QPoint& theMousePos, QRect& theRect) const +{ + QString aText = QString(""); + + if (getBodyRect().contains(theMousePos, true) || getGateRect().contains(theMousePos, true)) + { + // process ports + QPtrList aPortList = getPortList(); + for (YACSPrs_Port* aPort = aPortList.first(); aPort; aPort = aPortList.next()) { + if (aPort->getPortRect().contains(theMousePos, true)) { + YACSPrs_InOutPort* anIOPort = dynamic_cast( aPort ); + if ( anIOPort) { + aText += anIOPort->isInput()?QString("Input"):QString("Output"); + if (!anIOPort->isGate()) { + if ( dynamic_cast(anIOPort->getEngine()) + || + dynamic_cast(anIOPort->getEngine()) ) + aText += QString(" data stream"); + aText += QString(" port \"") + anIOPort->getName() + QString("\", "); + aText += anIOPort->getType(true) + QString(", "); + aText += QString("value = ") + anIOPort->getValue(); + } + else + aText += QString(" gate port"); + + theRect = anIOPort->getPortRect(); + return aText; + } + else if (YACSPrs_LabelPort* aLabelPort = dynamic_cast( aPort )) { + aText += QString("Label port"); + if ( YACS::ENGINE::Node* aSlaveNode = aLabelPort->getSlaveNode()) + aText += QString(", connected to node \"") + aSlaveNode->getName() + QString("\""); + theRect = aLabelPort->getPortRect(); + return aText; + } + } + } + } + + // info about node + //if (getGateRect().contains(theMousePos, true)) + // theRect = getGateRect(); + else if (getTitleRect().contains(theMousePos, true)) + theRect = getTitleRect(); + else if (getPixmapRect().contains(theMousePos, true)) + theRect = getPixmapRect(); + + aText += QString("Name: %1\n").arg(getEngine()->getName()); + //aText += QString("Type: %1\n").arg(getEngine()->getType()); + return aText; +} + +int YACSPrs_ElementaryNode::rtti() const +{ + return 0;//YACSPrs_Canvas::Rtti_ElementaryNode; +} + +void YACSPrs_ElementaryNode::setVisible(bool b) +{ + QCanvasPolygonalItem::setVisible(b); + + // set visibility to all ports + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + if (aPort->isVisible()) aPort->setVisible(b); + + // set visibility to master point + myPointMaster->setVisible(b); + updateLabelLink(); + + // set visibility to in/out points + //myPointIn->setVisible(b); + //myPointOut->setVisible(b); +} + +QPointArray YACSPrs_ElementaryNode::areaPoints() const +{ + int w = width(); + int h = height()+1; // add pen width + + return constructAreaPoints(w,h); +} + +QPointArray YACSPrs_ElementaryNode::maxAreaPoints() const +{ + int w = width(); + int h = maxHeight()+1; // add pen width + + return constructAreaPoints(w,h); +} + +QPointArray YACSPrs_ElementaryNode::constructAreaPoints(int theW, int theH) const +{ + QPointArray aPnts(4); + aPnts[0] = QPoint((int)x(), (int)y()) + QPoint(-NODEBOUNDARY_MARGIN,-NODEBOUNDARY_MARGIN); + aPnts[1] = aPnts[0] + QPoint(theW, 0) + QPoint(NODEBOUNDARY_MARGIN,0); + aPnts[2] = aPnts[1] + QPoint(0, theH) + QPoint(0,NODEBOUNDARY_MARGIN); + aPnts[3] = aPnts[0] + QPoint(0, theH) + QPoint(0,NODEBOUNDARY_MARGIN); + return aPnts; +} + +void YACSPrs_ElementaryNode::moveBy(double dx, double dy) +{ + // for constraint nodes' moving inside the Bloc--> + if ( isCheckAreaNeeded() && !checkArea(dx,dy) ) return; + // <-- + + int aX = (int) (x()+dx); + int aY = (int) (y()+dy); + int xx = aX - (int)x(); + int yy = aY - (int)y(); + + if ( canvas() ) + { + int w = aX + width() + GRAPH_MARGIN; + int h = aY + height() + GRAPH_MARGIN; + if (canvas()->width() > w) w = canvas()->width(); + if (canvas()->height() > h) h = canvas()->height(); + if (canvas()->width() < w || canvas()->height() < h) + canvas()->resize(w, h); + } + + // save new coordinates only if node is really moving... + //if (isMoving()) { + // myNode->getEngine()->Coords(aX, aY); + //} + + QCanvasPolygonalItem::moveBy(dx, dy); + + // update port's rectangle + updatePorts(); + //YACSPrs_Port* aPort; + //for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + // aPort->moveBy(xx, yy); + + myPointMaster->moveBy(dx, dy); + if ( myLabelLink ) myLabelLink->moveByNode(this, (int)dx, (int)dy); + + //if (!myCellPrs) { + // myPointIn->moveBy(dx, dy); + // myPointOut->moveBy(dx, dy); + //} + + if ( isSelected() && canvas() && isMoving() ) + { /* update changed areas on canvas only if a node moves itself ( not with + its Bloc node as a content ), in this case isMoving() returns true */ + QRect aRect = boundingRect(); + QPoint aShift(20,20); + aRect.setTopLeft(aRect.topLeft()-aShift); + aRect.setBottomRight(aRect.bottomRight()+aShift); + canvas()->setChanged(aRect); + canvas()->update(); + } +} + +void YACSPrs_ElementaryNode::setZ(double z) +{ + QCanvasItem::setZ(z); + + // update port's + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + aPort->setZ(z,isMoving()); + + if ( myPointMaster ) myPointMaster->setZ(z); +} + +void YACSPrs_ElementaryNode::setZFromLinks(double z) +{ + // find the maximum Z on all links of this node + double aMaxLinkZ = 0; + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + list aLinks = aPort->getLinks(); + for(list::iterator it = aLinks.begin(); it != aLinks.end(); it++) + if ( aMaxLinkZ < (*it)->getMyZ() ) aMaxLinkZ = (*it)->getMyZ(); + } + + double aMaxZ = ( z > aMaxLinkZ+1 ) ? z : aMaxLinkZ+1; + + QCanvasItem::setZ(aMaxZ); + // update port's + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + aPort->setZ(aMaxZ,isMoving()); + + if ( myPointMaster ) myPointMaster->setZ(aMaxZ); +} + +//! Updates a node presentation during execution +/*! + * 1) Update state of this node. + * 2) Update ports values of this node. + * 3) Update progress bar. + */ +void YACSPrs_ElementaryNode::update() +{ + if ( !myEngine ) return; + + // update state + setState( myEngine->getState() ); + + // update ports values + YACSPrs_Port* aPort = 0; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + YACSPrs_InOutPort* anIOPort = dynamic_cast( aPort ); + if ( anIOPort && !anIOPort->isGate() ) anIOPort->update(); + } + + // update progress bar + nextTimeIteration(); + + // update execution time + updateExecTime(); + + if ( canvas() ) { + canvas()->setChanged(getRect()); + canvas()->update(); + } +} + +//! Updates a node presentation during execution. !!! Use this function only for update original body node of ForEachLoop node. +/*! + * 1) Update state of this node. + * 2) Update ports values of this node. + * 3) Update progress bar. + * + * \param theEngine : the engine of clone node from which we have to update presentation of this node. + */ +void YACSPrs_ElementaryNode::updateForEachLoopBody(YACS::ENGINE::Node* theEngine) +{ + if ( !myEngine || !theEngine ) return; + + // update state + setState( theEngine->getState() ); + + // update ports values + YACSPrs_Port* aPort = 0; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + YACSPrs_InOutPort* anIOPort = dynamic_cast( aPort ); + if ( anIOPort && !anIOPort->isGate() ) { + if ( anIOPort->isInput() ) + anIOPort->update( false, theEngine->getInPort(anIOPort->getName().latin1()) ); + else + anIOPort->update( false, theEngine->getOutPort(anIOPort->getName().latin1()) ); + } + } + + // update progress bar + nextTimeIteration(theEngine); + + // update execution time + updateExecTime(theEngine); + + myPercentage = getPercentage(theEngine); + + if ( canvas() ) { + canvas()->setChanged(getRect()); + canvas()->update(); + } +} + +void YACSPrs_ElementaryNode::updatePorts() +{ + bool aDisp = isVisible(); + if (aDisp) hide(); + + // iterates on all engine ports of the engine node myEngine, + // create (if not already exists) for each engine port YACSPrs_InOutPort object and + // set the rectangle for it + + bool withCreate = false; + if ( myPortList.isEmpty() ) withCreate = true; + + QRect r = getBodyRect(); + int aPRectWidth = (int)(r.width()/2) - 2*PORT_MARGIN; + if ( aPRectWidth < PORT_WIDTH ) aPRectWidth = PORT_WIDTH; + + int ix = r.x() + PORT_MARGIN + 1; + int iy = r.y() + PORT_MARGIN;// + 1; + int ox = ix + aPRectWidth + 2*PORT_MARGIN; + int oy = r.y() + PORT_MARGIN;// + 1; + + if ( withCreate ) + { // create (and update) + + // input ports + list anInPortsEngine = myEngine->getSetOfInPort(); + list::iterator anInPortsIter = anInPortsEngine.begin(); + int heightIncr = 0; + for( ;anInPortsIter!=anInPortsEngine.end();anInPortsIter++) + { + YACSPrs_InOutPort* anInPort = new YACSPrs_InOutPort(myMgr, canvas(), *anInPortsIter, this); + anInPort->setPortRect(QRect(ix, iy+heightIncr, aPRectWidth, PORT_HEIGHT)); + anInPort->setColor(nodeSubColor()); + anInPort->setStoreColor(nodeSubColor()); + myPortList.append(anInPort); + heightIncr += PORT_HEIGHT+PORT_SPACE; + } + + // output ports + list anOutPortsEngine = myEngine->getSetOfOutPort(); + list::iterator anOutPortsIter = anOutPortsEngine.begin(); + heightIncr = 0; + for( ;anOutPortsIter!=anOutPortsEngine.end();anOutPortsIter++) + { + YACSPrs_InOutPort* anOutPort = new YACSPrs_InOutPort(myMgr, canvas(), *anOutPortsIter, this); + anOutPort->setPortRect(QRect(ox, oy+heightIncr, aPRectWidth, PORT_HEIGHT)); + anOutPort->setColor(nodeSubColor()); + anOutPort->setStoreColor(nodeSubColor()); + myPortList.append(anOutPort); + heightIncr += PORT_HEIGHT+PORT_SPACE; + } + + int aPortsIncrement = + anInPortsEngine.size()>anOutPortsEngine.size()?anInPortsEngine.size():anOutPortsEngine.size(); + myPortHeight += PORT_HEIGHT*aPortsIncrement + (aPortsIncrement-1)*PORT_SPACE; + } + else + { // only update + YACSPrs_InOutPort* aPort; + for (aPort = (YACSPrs_InOutPort*)(myPortList.first()); + aPort && !aPort->isGate(); + aPort = (YACSPrs_InOutPort*)(myPortList.next())) + { + if ( aPort->isInput() ) + { // test input ports + aPort->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT), !mySelfMoving, myArea); + iy += PORT_HEIGHT+PORT_SPACE; + } + else + { // test output ports + aPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT), !mySelfMoving, myArea); + oy += PORT_HEIGHT+PORT_SPACE; + } + } + } + + // can update gates only after body height will be defined + updateGates(withCreate); + + if (aDisp) show(); +} + +void YACSPrs_ElementaryNode::updateGates(bool theCreate) +{ + bool aDisp = isVisible(); + if (aDisp) hide(); + + QRect aRect = getRect(); + QRect aBRect = getBodyRect(); + int aPRectWidth = (int)(aRect.width()/2) - 2*PORT_MARGIN; + + int ix = aBRect.left() + PORT_MARGIN + 1; + int iy = aBRect.bottom() + PORT_MARGIN + 1; + int ox = ix + aPRectWidth + 2*PORT_MARGIN; + int oy = aBRect.bottom() + PORT_MARGIN + 1; + + if ( theCreate ) + { // create (and update) + // input Gate + YACSPrs_InOutPort* anInPort = new YACSPrs_InOutPort(myMgr,canvas(),myEngine->getInGate(),this); + anInPort->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT)); + anInPort->setColor(nodeSubColor()); + anInPort->setStoreColor(nodeSubColor()); + myPortList.append(anInPort); + + // output Gate + YACSPrs_InOutPort* anOutPort = new YACSPrs_InOutPort(myMgr,canvas(),myEngine->getOutGate(),this); + anOutPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT)); + anOutPort->setColor(nodeSubColor()); + anOutPort->setStoreColor(nodeSubColor()); + myPortList.append(anOutPort); + } + else + { // only update + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + YACSPrs_InOutPort* anIOPort = dynamic_cast( aPort ); + if ( anIOPort && anIOPort->isGate() ) + { + if ( anIOPort->isInput() ) // test input ports + anIOPort->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT), !mySelfMoving, myArea); + else // test output ports + anIOPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT), !mySelfMoving, myArea); + } + } + } + + if (aDisp) show(); +} + +void YACSPrs_ElementaryNode::setNodeColor(const QColor& theColor) +{ + myColor = theColor; + if ( canvas() ) + { + canvas()->setChanged(boundingRect()); + canvas()->update(); + } +} + +void YACSPrs_ElementaryNode::setNodeSubColor(const QColor& theColor, bool theSelectionProcess) +{ + mySubColor = theColor; + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) { + if ( dynamic_cast( aPort ) ) + aPort->setColor(theColor.dark(140)); + else + aPort->setColor(theColor); + } + if ( canvas() ) + { + QRect aRect; + if ( theSelectionProcess ) + { + aRect = boundingRect(); + QPoint aShift(20,20); + aRect.setTopLeft(aRect.topLeft()-aShift); + aRect.setBottomRight(aRect.bottomRight()+aShift); + } + else + aRect = getRect(); + canvas()->setChanged(aRect); + canvas()->update(); + } +} + +int YACSPrs_ElementaryNode::height() const +{ + return NODE_MARGIN + getInfoHeight() + NODE_MARGIN + getBodyHeight() + + getGateHeight(); +} + +int YACSPrs_ElementaryNode::maxWidth() const +{ + return boundingRect().width() + 4*HOOKPOINT_SIZE; +} + +int YACSPrs_ElementaryNode::maxHeight() const +{ + return boundingRect().height() + ( myPointMaster ? myPointMaster->height()/2 : 0 ); +} + +int YACSPrs_ElementaryNode::getInfoHeight() const +{ + return myTitleHeight; +} + +int YACSPrs_ElementaryNode::getStatusHeight() const +{ + return myStatusHeight; +} + +int YACSPrs_ElementaryNode::getTimeHeight() const +{ + return myTimeHeight; +} + +int YACSPrs_ElementaryNode::getBodyHeight() const +{ + return myPortHeight; +} + +int YACSPrs_ElementaryNode::getGateHeight() const +{ + return myGateHeight; +} + +QRect YACSPrs_ElementaryNode::getRect() const +{ + return QRect((int)x(), (int)y(), width(), height()); +} + +QRect YACSPrs_ElementaryNode::getTitleRect() const +{ + return QRect((int)x()+NODE_MARGIN, (int)y()+NODE_MARGIN, + width()-2*NODE_MARGIN, getTitleHeight()); +} + +int YACSPrs_ElementaryNode::getPixMapHeight() const +{ + return PIXMAP_HEIGHT; +} + +int YACSPrs_ElementaryNode::getPixMapWidth() const +{ + int width; + int height = PIXMAP_HEIGHT; + if ( !myStatePixmap.isNull() ) + width = myStatePixmap.width()*(height-2*PIXMAP_MARGIN)/myStatePixmap.height() + 2*PIXMAP_MARGIN; + else + width = height; + return width; +} + +QRect YACSPrs_ElementaryNode::getPixmapRect(bool theLeft, bool theService) const +{ + int x = (int)(theLeft ? getTitleRect().left() : getTitleRect().right() + NODE_MARGIN); + int y = (int)getTitleRect().y() + (theService ? getTitleHeight() + ( getInfoHeight() - getTitleHeight() - getPixMapHeight() )/2 : 0 ); + /* vertical margin */ + return QRect(x, y, getPixMapWidth(), getPixMapHeight()); +} + +QRect YACSPrs_ElementaryNode::getBodyRect() const +{ + return QRect((int)x(), ((int)y())+NODE_MARGIN+getInfoHeight()+NODE_MARGIN, + width(), getBodyHeight()); +} + +QRect YACSPrs_ElementaryNode::getGateRect() const +{ + return QRect((int)x(), ((int)y())+NODE_MARGIN+getInfoHeight()+NODE_MARGIN+ + getBodyHeight(), + width(), getGateHeight()); +} + +//! Increments time iteration. +/*! + * Note : use not null argument of this function only for update original body node of ForEachLoop node. + * + * \param theEngine : the engine of clone node from which we have to update presentation of this node. + */ +void YACSPrs_ElementaryNode::nextTimeIteration(YACS::ENGINE::Node* theEngine) +{ + bool nullifyOnToActivate = false; + if ( !theEngine ) theEngine = myEngine; + else nullifyOnToActivate = true; + + if ( theEngine + && + ( theEngine->getState() == YACS::INITED || theEngine->getEffectiveState() == YACS::INITED + || + ( nullifyOnToActivate && ( theEngine->getState() == YACS::TOACTIVATE || theEngine->getEffectiveState() == YACS::TOACTIVATE) ) ) ) + myTimeIteration = 0.; + else if ( theEngine && + theEngine->getState() != YACS::INITED && theEngine->getEffectiveState() != YACS::INITED && + !myFinished ) { + const double aGoodTime = 0.02 * 100; // estimated time to run, s + myTimeIteration += 1./aGoodTime; + } +} + +//! Returns the progress bar percentage. +/*! + * Note : use not null argument of this function only for update original body node of ForEachLoop node. + * + * \param theEngine : the engine of clone node from which we have to update presentation of this node. + */ +double YACSPrs_ElementaryNode::getPercentage(YACS::ENGINE::Node* theEngine) const +{ + bool nullifyOnToActivate = false; + if ( !theEngine ) theEngine = myEngine; + else nullifyOnToActivate = true; + + if ( !theEngine ) return 0.; + + if ( theEngine->getState() == YACS::INITED || theEngine->getEffectiveState() == YACS::INITED || + theEngine->getState() == YACS::TOLOAD || theEngine->getEffectiveState() == YACS::TOLOAD || + theEngine->getState() == YACS::DISABLED || theEngine->getEffectiveState() == YACS::DISABLED + || + ( nullifyOnToActivate && ( theEngine->getState() == YACS::TOACTIVATE || theEngine->getEffectiveState() == YACS::TOACTIVATE) ) ) + return 0.; + if ( theEngine->getState() == YACS::DONE ) + return 100.; + // progress bar is manipulated at logarithmic scale: + // iteration=1 -> 1%, iteration==goodtime -> 50%, iteration=infinite -> 99% + return ( 0.499 + 99. * ( myTimeIteration * myTimeIteration / ( 1. + myTimeIteration * myTimeIteration ) ) ); +} + +//! Updates execution time. +/*! + * Note : use not null argument of this function only for update original body node of ForEachLoop node. + * + * \param theEngine : the engine of clone node from which we have to update presentation of this node. + */ +void YACSPrs_ElementaryNode::updateExecTime(YACS::ENGINE::Node* theEngine) +{ + bool nullifyOnToActivate = false; + if ( !theEngine ) theEngine = myEngine; + else nullifyOnToActivate = true; + + if ( !theEngine ) return; + + if ( theEngine->getState() == YACS::DISABLED || theEngine->getEffectiveState() == YACS::DISABLED ) + { + myTime = QString("00:00:00"); + return; + } + + if ( theEngine->getState() == YACS::INITED || theEngine->getEffectiveState() == YACS::INITED + || + ( nullifyOnToActivate && ( theEngine->getState() == YACS::TOACTIVATE || theEngine->getEffectiveState() == YACS::TOACTIVATE) ) ) + { + myTime = QString("00:00:00"); + myStarted = false; + if ( theEngine->getState() == YACS::INITED ) return; + } + + if ( !myTime.compare(QString("00:00:00")) && !myStarted ) { + myStartTime.start(); + myStarted = true; + myFinished = false; + } + + if ( theEngine->getState() != YACS::INITED && theEngine->getState() != YACS::DONE && + theEngine->getState() != YACS::FAILED && theEngine->getState() != YACS::ERROR ) + { + int aMS = myStartTime.elapsed(); + int aH = aMS/3600000; + int aM = aMS/60000 - aH*60; + int aS = aMS/1000 - aH*3600 - aM*60; + QTime aT(aH,aM,aS); + myTime = aT.toString(); + return; + } + + if ( !myFinished && ( theEngine->getState() == YACS::DONE || + theEngine->getState() == YACS::FAILED || + theEngine->getState() == YACS::ERROR ) ) + { + int aMS = myStartTime.elapsed(); + int aH = aMS/3600000; + int aM = aMS/60000 - aH*60; + int aS = aMS/1000 - aH*3600 - aM*60; + QTime aT(aH,aM,aS); + myTime = aT.toString(); + myFinished = true; + return; + } +} + +/*! + Set state and update pixmap +*/ +void YACSPrs_ElementaryNode::setState(YACS::StatesForNode theState) +{ + switch ( theState ) + { + case YACS::INITED: + myStatus = QString("Inited"); + myStatePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_STATUS_NO" )); + break; + case YACS::TOLOAD: + myStatus = QString("To Load"); + myStatePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_STATUS_WAITING" )); + break; + case YACS::LOADED: + myStatus = QString("Loaded"); + myStatePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_STATUS_WAITING" )); + break; + case YACS::TOACTIVATE: + myStatus = QString("To Activate"); + myStatePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_STATUS_WAITING" )); + break; + case YACS::ACTIVATED: + myStatus = QString("Activated"); + myStatePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_STATUS_RUNNING" )); + break; + case YACS::DESACTIVATED: + myStatus = QString("Desactivated"); + myStatePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_STATUS_DONE" )); + break; + case YACS::DONE: + myStatus = QString("Done"); + myStatePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_STATUS_DONE" )); + break; + case YACS::SUSPENDED: + case YACS::LOADFAILED: + case YACS::EXECFAILED: + case YACS::PAUSE: + break; + case YACS::DISABLED: + myStatus = QString("Disabled"); + myStatePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_DISABLED" )); + break; + case YACS::INTERNALERR: + myStatus = QString("Internal Error"); + myStatePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_STATUS_ABORTED" )); + break; + case YACS::FAILED: + myStatus = QString("Failed"); + myStatePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_STATUS_ABORTED" )); + break; + case YACS::ERROR: + myStatus = QString("Error"); + myStatePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_STATUS_ABORTED" )); + break; + default: + break; + } +} + +void YACSPrs_ElementaryNode::draw(QPainter& thePainter) +{ + thePainter.setPen(pen()); + thePainter.setBrush(nodeColor()); + drawShape(thePainter); +} + +void YACSPrs_ElementaryNode::drawShape(QPainter& thePainter) +{ + drawFrame(thePainter); + drawTitle(thePainter); + drawPort(thePainter); + drawGate(thePainter); +} + +void YACSPrs_ElementaryNode::drawTitleShape(QPainter& thePainter) +{ + thePainter.drawRoundRect(getTitleRect(),myXRnd,myYRnd); + drawText(thePainter, QString(myEngine->getName()), getTitleRect(), Qt::AlignHCenter); +} + +void YACSPrs_ElementaryNode::drawTitle(QPainter& thePainter) +{ + QBrush saved = thePainter.brush(); + QBrush br( mySubColor ); + thePainter.setBrush(br); + drawTitleShape(thePainter); + thePainter.setBrush(saved); +} + +void YACSPrs_ElementaryNode::drawPort(QPainter& thePainter) +{ + QRect r = getBodyRect(); + r.setHeight(r.height()+1); + + thePainter.drawRect(r); + int x0 = (r.left() + r.right())/2; + thePainter.drawLine(x0, r.top(), x0, r.bottom()); + //if (getStreamHeight() > 0) { + // int y0 = r.top() + getPortHeight(); + // thePainter.drawLine(r.left(), y0, r.right(), y0); + //} + + int aRRectWidth = (x0 - r.left() - 2*PORT_MARGIN - 2*PORT_SPACE)/3; + QRect aTRect = getTitleRect(); + int aXRnd = aTRect.width()*myXRnd/aRRectWidth; + int aYRnd = aTRect.height()*myYRnd/PORT_HEIGHT; + + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + aPort->draw(thePainter, aXRnd, aYRnd); + } +} + +void YACSPrs_ElementaryNode::drawGate(QPainter& thePainter) +{ + QRect aRect = getRect(); + QRect aBRect = getBodyRect(); + int x0 = (aRect.left() + aRect.right())/2; + thePainter.drawLine(x0, aBRect.bottom(), x0, aRect.bottom()); + + int aRRectWidth = x0 - aRect.left() - 2*PORT_MARGIN; + QRect aTRect = getTitleRect(); + int aXRnd = aTRect.width()*myXRnd/aRRectWidth; + int aYRnd = aTRect.height()*myYRnd/PORT_HEIGHT; + + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + if ( (YACSPrs_InOutPort*)aPort && ((YACSPrs_InOutPort*)aPort)->isGate() ) + aPort->draw(thePainter,aXRnd,aYRnd); + } +} + +void YACSPrs_ElementaryNode::drawFrame(QPainter& thePainter) +{ + QRect aRect = getRect(); + QRect aTRect = getTitleRect(); + int aXRnd = aTRect.width()*myXRnd/aRect.width(); + int aYRnd = aTRect.height()*myYRnd/aRect.height(); + thePainter.drawRoundRect(aRect,aXRnd,aYRnd); + + // draw bounding nodes' polygon if node is currently selected + if ( isSelected() ) drawBoundary(thePainter,2); +} + +void YACSPrs_ElementaryNode::drawBoundary(QPainter& thePainter, int theRightBottomPointIndex) +{ + QPointArray anArr = areaPoints(); + int aSize = anArr.size(); + QPoint aFirstP = *(anArr.begin()); + anArr.putPoints(aSize, 1, aFirstP.x(), aFirstP.y()); + + thePainter.drawPolyline(anArr,0,theRightBottomPointIndex+1); + + QPoint aRPM( getConnectionMasterPoint().x() + (myPointMaster?myPointMaster->width()/2:0), + anArr[theRightBottomPointIndex].y() ); + QPoint aLPM( getConnectionMasterPoint().x() - (myPointMaster?myPointMaster->width()/2:0), + anArr[theRightBottomPointIndex].y() ); + thePainter.drawLine(anArr[theRightBottomPointIndex],aRPM); + thePainter.drawLine(aLPM,anArr[theRightBottomPointIndex+1]); + + thePainter.drawPolyline(anArr,theRightBottomPointIndex+1,aSize-theRightBottomPointIndex); +} + +QPoint YACSPrs_ElementaryNode::getConnectionMasterPoint() +{ + QRect aRect = getRect(); + return QPoint(aRect.left()+aRect.width()/2, aRect.bottom()); +} + +void YACSPrs_ElementaryNode::setMasterPointColor(QColor theColor) +{ + if ( myPointMaster ) myPointMaster->setBrush(theColor); +} + +bool YACSPrs_ElementaryNode::checkArea(double dx, double dy) +{ + // for constraint nodes' moving inside the Bloc--> + if ( !myIsInBloc ) return true; + + QRect aRect = boundingRect(); + aRect.moveBy((int)dx, (int)dy); + aRect.setRect(aRect.x()-2*HOOKPOINT_SIZE, aRect.y(), maxWidth(), maxHeight()); + if ( myArea.isValid() && myArea.contains(aRect) )//,true) ) + return true; + return false; + // <-- +} + +/*! + * =========================== YACSPrs_Port =========================== + !*/ + +YACSPrs_Port::YACSPrs_Port( SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACSPrs_ElementaryNode* theNode ): + myMgr(theMgr), + myCanvas(theCanvas), + myPoint(0), + myNode(theNode) +{ + myName = QString(""); + + myVisible = true; + myStoreColor = myColor = QColor(); + + mySelected = false; +} + +YACSPrs_Port::~YACSPrs_Port() +{ + if (myPoint) delete myPoint; + + for(list::iterator it = myLinks.begin(); it != myLinks.end(); it++) { + if ( YACSPrs_PortLink* aPL = dynamic_cast( *it ) ) { + aPL->setInputPort(0); + aPL->setOutputPort(0); + } + else if ( YACSPrs_LabelLink* aLL = dynamic_cast( *it ) ) { + aLL->setOutputPort(0); + aLL->setSlaveNode(0); + } + } + + //for(list::iterator it = myLinks.begin(); it != myLinks.end(); ++it) { + // delete (*it); + //} + //myLinks.clear(); +} + +void YACSPrs_Port::setCanvas(QCanvas* theCanvas) +{ + myCanvas = theCanvas; + + // set canvas to hook + if (myPoint) myPoint->setCanvas(theCanvas); +} + +void YACSPrs_Port::updateLinks(bool theMoveInternalLinkPoints, QRect theArea) +{ + for(list::iterator it = myLinks.begin(); it != myLinks.end(); it++) + (*it)->moveByPort(this, theMoveInternalLinkPoints, theArea); +} + +QString YACSPrs_Port::getName() const +{ + return myName; +} + +void YACSPrs_Port::setVisible(bool b) +{ + if (myPoint) myPoint->setVisible(b); + if (b) updateLinks(); +} + +void YACSPrs_Port::setColor(const QColor& theColor, bool theUpdatePointColor, + bool theUpdate, bool theSelectionProcess) +{ + myColor = theColor; + if (myCanvas && theUpdate) + { + QRect aRect = getPortRect(); + if ( theSelectionProcess ) + { + QPoint aShift(PORT_MARGIN/2,PORT_MARGIN/2); + aRect.setTopLeft(aRect.topLeft()-aShift); + aRect.setBottomRight(aRect.bottomRight()+aShift); + } + myCanvas->setChanged(aRect); + myCanvas->update(); + } +} + +void YACSPrs_Port::moveBy(int dx, int dy) +{ + for(list::iterator it = myLinks.begin(); it != myLinks.end(); it++) + (*it)->moveByPort(this, dx, dy); +} + +void YACSPrs_Port::setZ(double z, bool storeOldZ) +{ + if (myPoint) myPoint->setZ(z); + for(list::iterator it = myLinks.begin(); it != myLinks.end(); it++) { + if ( storeOldZ ) (*it)->setMyZ((*it)->z()); + (*it)->setZ(z-2); + } +} + +double YACSPrs_Port::z() +{ + if (myPoint) return myPoint->z(); + return 0; +} + +/*! + * =========================== YACSPrs_LabelPort =========================== + !*/ + +YACSPrs_LabelPort::YACSPrs_LabelPort( SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACS::ENGINE::Node* theNode, YACSPrs_ElementaryNode* theNodePrs, + const bool& theSwitch, const int& theId ): + YACSPrs_Port(theMgr, theCanvas, theNodePrs), + mySlaveNode(theNode) +{ + if ( theSwitch ) + myName = QString("Case ") + QString::number(theId); + else + myName = QString("Body"); + + myStoreColor = myColor = LABELPORT_COLOR; + + myPoint = new YACSPrs_Hook(theMgr, theCanvas, this, false, false); +} + +YACSPrs_LabelPort::~YACSPrs_LabelPort() +{ +} + +void YACSPrs_LabelPort::setPortRect(const QRect& theRect, bool theMoveInternalLinkPoints, QRect theArea) +{ + myNameRect = theRect; + myNameRect.setWidth(theRect.width()-3); + + QPoint aPnt = getConnectionPoint(); + if (myPoint) { + myPoint->setCoords(aPnt.x(), aPnt.y()); + if (myVisible) myPoint->show(); + } + updateLinks(theMoveInternalLinkPoints, theArea); +} + +QRect YACSPrs_LabelPort::getPortRect() const +{ + return myNameRect; +} + +void YACSPrs_LabelPort::setColor(const QColor& theColor, bool theUpdatePointColor, + bool theUpdate, bool theSelectionProcess) +{ + if ( theUpdatePointColor ) myPoint->setColor( theColor ); + YACSPrs_Port::setColor(theColor, theUpdatePointColor, theUpdate, theSelectionProcess); +} + +void YACSPrs_LabelPort::moveBy(int dx, int dy) +{ + myNameRect.moveBy(dx, dy); + if (myPoint) myPoint->moveBy(dx, dy); + + YACSPrs_Port::moveBy(dx, dy); +} + +QPoint YACSPrs_LabelPort::getConnectionPoint() const +{ + int x, y; + x = myNameRect.right() + PORT_MARGIN + 2 + 3*HOOKPOINT_SIZE/2; + y = (int)(myNameRect.top() + myNameRect.bottom())/2; + return QPoint(x, y); +} + +void YACSPrs_LabelPort::draw(QPainter& thePainter, int theXRnd, int theYRnd) +{ + QBrush savedB = thePainter.brush(); + QBrush br( myColor ); + thePainter.setBrush(br); + + QPen savedP = thePainter.pen(); + thePainter.setPen(thePainter.brush().color().dark(140)); + thePainter.drawRoundRect(myNameRect,theXRnd,theYRnd); + + thePainter.setPen(Qt::white); + drawText(thePainter, myName, myNameRect, Qt::AlignHCenter); + + thePainter.setPen(savedP); + thePainter.setBrush(savedB); + + // draw bounding rectangle of the port if it is currently selected + if ( isSelected() ) + { + QBrush savedB = thePainter.brush(); + thePainter.setBrush(Qt::NoBrush); + + QRect aRect = getPortRect(); + aRect.setTopLeft(aRect.topLeft()-QPoint(PORT_MARGIN/2,PORT_MARGIN/2)); + aRect.setBottomRight(aRect.bottomRight()+QPoint(PORT_MARGIN/2,PORT_MARGIN/2)); + thePainter.drawRect(aRect); + + thePainter.setBrush(savedB); + } +} + +/*! + * =========================== YACSPrs_InOutPort =========================== + !*/ + +YACSPrs_InOutPort::YACSPrs_InOutPort( SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACS::ENGINE::Port* thePort, YACSPrs_ElementaryNode* theNodePrs ): + YACSPrs_Port(theMgr, theCanvas, theNodePrs), + myEngine(thePort) +{ + myInput = false; + myGate = false; + + InPort* anInPort = dynamic_cast(myEngine); + if (anInPort) myInput = true; + else { + InGate* anInGate = dynamic_cast< InGate*>(myEngine); + if (anInGate) myGate = myInput = true; + else { + OutGate* anOutGate = dynamic_cast< OutGate*>(myEngine); + if (anOutGate) myGate = true; + } + } + + myName = getName(); + + if ( !myGate ) { + myType = getType(); + myValue = getValue(); + } + + myColor = myMgr->colorValue( "QxGraph", "Title", TITLE_COLOR ); + + myPoint = new YACSPrs_Hook(theMgr, theCanvas, this, myInput, myGate); +} + +YACSPrs_InOutPort::~YACSPrs_InOutPort() +{ +} + +//! Updates a port presentation during execution. +/*! + * Note : use not null second argument of this function only for update original body node of ForEachLoop node. + * + * \param theEngine : the engine of port of clone node from which we have to update value of this port. + */ +void YACSPrs_InOutPort::update(bool theForce, YACS::ENGINE::Port* theEngine) +{ + QString aNewName = getName(); + if (theForce || myName.compare(aNewName) != 0) { + myName = aNewName; + if (myCanvas) myCanvas->setChanged(myNameRect); + } + if ( !myGate ) + { + QString aNewType = getType(); + QString aNewValue = getValue(theEngine); + if (theForce || myType.compare(aNewType) != 0) { + myType = aNewType; + if (myCanvas) myCanvas->setChanged(myTypeRect); + } + if (theForce || myValue.compare(aNewValue) != 0) { + myValue = aNewValue; + if (myCanvas) myCanvas->setChanged(myValueRect); + } + } +} + +bool YACSPrs_InOutPort::isHilight() const +{ + //Port aPort = myPort->getEngine(); + bool b = false; + /*if (!aPort->IsGate()) { + if (aPort->IsInput()) { + if (aPort->HasInput() && !aPort->IsLinked()) + b = true; + } + else if (myPort->inherits("YACSGui_PortOut")) { + YACSGui_PortOut* aPortOut = (YACSGui_PortOut*) myPort; + if (aPortOut->isInStudy()) + b = true; + } + }*/ + return b; +} + +bool YACSPrs_InOutPort::isAlert() const +{ + bool b = false; + /*Port aPort = myPort->getEngine(); + if (!aPort->IsGate()) { + if (aPort->IsInput() && !aPort->HasInput() && !aPort->IsLinked()) + b = true; + }*/ + return b; +} + +QString YACSPrs_InOutPort::getName() const +{ + QString aName; + if ( !myGate ) + { + DataPort* aDataPort = dynamic_cast(myEngine); + if ( aDataPort ) + aName = QString(aDataPort->getName()); + } + else + aName = QString("Gate"); + return aName; +} + +QString YACSPrs_InOutPort::getType(const bool forToolTip) const +{ + QString aType; + if ( !myGate ) + { + DataPort* aDataPort = dynamic_cast(myEngine); + if (aDataPort) { + DynType aDType = aDataPort->edGetType()->kind(); + if (aDType == Objref) { + TypeCodeObjref* aRefTypeCode = dynamic_cast(aDataPort->edGetType()); + if (aRefTypeCode) { + aType = aRefTypeCode->name(); + if (aType.isEmpty()) + aType = QString(TypeCode::getKindRepr( aDType )); + if (forToolTip) + aType += QString(" (obj. reference)"); + } + } + else if (aDType == Sequence) { + TypeCodeSeq* aSeqTypeCode = dynamic_cast(aDataPort->edGetType()); + if (aSeqTypeCode) { + aType = aSeqTypeCode->name(); + if (aType.isEmpty()) + aType = QString(TypeCode::getKindRepr( aDType )); + if (forToolTip) + aType += QString(" (seq. of %1)").arg(aSeqTypeCode->contentType()->name()); + } + } + else + aType = QString( TypeCode::getKindRepr( aDType ) ); + } + } + return aType; +} + +//! Returns a port value. +/*! + * Note : use not null argument of this function only for update original body node of ForEachLoop node. + * + * \param theEngine : the engine of port of clone node from which we have to get value of this port. + */ +QString YACSPrs_InOutPort::getValue(YACS::ENGINE::Port* theEngine) const +{ + if ( !theEngine ) theEngine = myEngine; + + QString aValue; + if ( !myGate ) + { + // variables to store ports values + Any* anAny = 0; + CORBA::Any* aCorbaAny = 0; + + if ( myInput ) + { + if ( SeqAnyInputPort* aSeqAnyP = dynamic_cast(theEngine) ) + { // check if theEngine is SeqAnyInputPort + //printf("SeqAnyInputPort : %s\n",getName().latin1()); + anAny = aSeqAnyP->getValue(); + if ( !anAny ) aValue = QString("[ ? ]"); + else toString(anAny, aValue); + } + else if ( AnyInputPort* anAnyP = dynamic_cast(theEngine) ) + { // check if theEngine is AnyInputPort + //printf("AnyInputPort : %s\n",getName().latin1()); + toString(anAnyP->getValue(), aValue); + } + else if ( ConditionInputPort* aConditionP = dynamic_cast(theEngine) ) + { // check if theEngine is ConditionInputPort + //printf("ConditionInputPort : %s\n",getName().latin1()); + aValue = QString( aConditionP->getValue() ? "true" : "false" ); + } + else if ( InputCorbaPort* aCorbaP = dynamic_cast(theEngine) ) + { // check if theEngine is InputCorbaPort + //printf("InputCorbaPort : %s\n",getName().latin1()); + toString( aCorbaP->getAny(), aValue ); + } + else if ( InputPyPort* aPyP = dynamic_cast(theEngine) ) + { // check if theEngine is InputPyPort + //printf("InputPyPort : %s\n",getName().latin1()); + toString( aPyP->getPyObj(), aValue ); + } + else if ( InputXmlPort* aXmlP = dynamic_cast(theEngine) ) + { // check if theEngine is InputXmlPort + //printf("InputXmlPort : %s\n",getName().latin1()); + } + else if ( InputCalStreamPort* aCalStreamP = dynamic_cast(theEngine) ) + { // check if theEngine is InputCalStreamPort + //printf("InputCalStreamPort : %s\n",getName().latin1()); + aValue = QString("data stream"); + } + else if ( InputDataStreamPort* aDataStreamP = dynamic_cast(theEngine) ) + { // check if theEngine is InputDataStreamPort + //printf("InputDataStreamPort : %s\n",getName().latin1()); + aValue = QString("data stream"); + } + else if ( InputPort* anInputP = dynamic_cast(theEngine) ) + { // check if theEngine is InputPort + //printf("InputPort : %s\n",getName().latin1()); + } + } + else + { + // this case was implemented only for the initial output ports values (before execution finished) + + if ( AnyOutputPort* anAnyP = dynamic_cast(theEngine) ) + { // check if theEngine is AnyOutputPort + //printf("AnyOutputPort : %s\n",getName().latin1()); + toString(anAnyP->getValue(), aValue); + } + else if ( OutputCorbaPort* aCorbaP = dynamic_cast(theEngine) ) + { // check if theEngine is OutputCorbaPort + //printf("OutputCorbaPort : %s\n",getName().latin1()); + toString( aCorbaP->getAny(), aValue ); + } + else if ( OutputPyPort* aPyP = dynamic_cast(theEngine) ) + { // check if theEngine is OutputPyPort + //printf("OutputPyPort : %s\n",getName().latin1()); + toString( aPyP->get(), aValue ); + } + else if ( OutputXmlPort* aXmlP = dynamic_cast(theEngine)) + { // check if theEngine is OutputXmlPort + //printf("OutputXmlPort : %s\n",getName().latin1()); + } + else if ( OutputCalStreamPort* aCalStreamP = dynamic_cast(theEngine) ) + { // check if theEngine is OutputCalStreamPort + //printf("OutputCalStreamPort : %s\n",getName().latin1()); + aValue = QString("data stream"); + } + else if ( OutputDataStreamPort* aCalStreamP = dynamic_cast(theEngine) ) + { // check if theEngine is OutputDataStreamPort + //printf("OutputDataStreamPort : %s\n",getName().latin1()); + aValue = QString("data stream"); + } + else if ( OutputPort* anOutputP = dynamic_cast(theEngine) ) + { // check if theEngine is OutputPort + //printf("OutputPort : %s\n",getName().latin1()); + } + } + } + return aValue; +} + +int YACSPrs_InOutPort::getAlignment() const +{ + int a = Qt::AlignAuto; + if ( myGate && myInput ) + a = Qt::AlignLeft; + else if ( myGate && !myInput ) + a = Qt::AlignRight; + return a; +} + +void YACSPrs_InOutPort::setPortRect(const QRect& theRect, bool theMoveInternalLinkPoints, QRect theArea) +{ + if ( !myGate ) + { + int aRectWidth = (theRect.right() - theRect.left() - 2*(PORT_SPACE))/3; + myNameRect = QRect(theRect.left(), theRect.top(), + aRectWidth,PORT_HEIGHT); + myTypeRect = QRect(myNameRect.right()+PORT_SPACE, theRect.top(), + aRectWidth,PORT_HEIGHT); + myValueRect = QRect(myTypeRect.right()+PORT_SPACE, theRect.top(), + aRectWidth,PORT_HEIGHT); + } + else + { + myNameRect = theRect; + myNameRect.setWidth(theRect.width()-3); + } + + QPoint aPnt = getConnectionPoint(); + if (myPoint) { + myPoint->setCoords(aPnt.x(), aPnt.y()); + if (myVisible) myPoint->show(); + } + + updateLinks(theMoveInternalLinkPoints,theArea); +} + +QRect YACSPrs_InOutPort::getPortRect() const +{ + if ( !myGate ) + return QRect(myNameRect.left(), myNameRect.top(), + myNameRect.width()*3+2*PORT_SPACE, PORT_HEIGHT); + else + return myNameRect; +} + +void YACSPrs_InOutPort::moveBy(int dx, int dy) +{ + myNameRect.moveBy(dx, dy); + if ( !myGate ) + { + myTypeRect.moveBy(dx, dy); + myValueRect.moveBy(dx, dy); + } + if (myPoint) myPoint->moveBy(dx, dy); + + YACSPrs_Port::moveBy(dx, dy); +} + +void YACSPrs_InOutPort::setZ(double z, bool storeOldZ) +{ + if (myPoint) myPoint->setZ(z); + for(list::iterator it = myLinks.begin(); it != myLinks.end(); it++) { + if ( storeOldZ ) (*it)->setMyZ((*it)->z()); + + YACSPrs_PortLink* aPortLink = dynamic_cast( *it ); + if ( aPortLink ) + { + if ( myInput && aPortLink->getOutputPort() ) + aPortLink->setZ( ( z > aPortLink->getOutputPort()->z() ) ? z-2 : aPortLink->getOutputPort()->z()-2 ); + if ( !myInput && aPortLink->getInputPort() ) + aPortLink->setZ( ( z > aPortLink->getInputPort()->z() ) ? z-2 : aPortLink->getInputPort()->z()-2 ); + } + } +} + +QPoint YACSPrs_InOutPort::getConnectionPoint() const +{ + int x, y; + if ( myGate ) + { + if ( myInput ) + x = myNameRect.left() - PORT_MARGIN - 1; + else + x = myNameRect.right() + PORT_MARGIN + 3; + } + else + { + if ( myInput ) + x = myNameRect.left() - PORT_MARGIN - 1 - 3*HOOKPOINT_SIZE/2; + else + x = myValueRect.right() + PORT_MARGIN + 2 + 3*HOOKPOINT_SIZE/2; + } + y = (int)(myNameRect.top() + myNameRect.bottom())/2; + return QPoint(x, y); +} + +void YACSPrs_InOutPort::draw(QPainter& thePainter, int theXRnd, int theYRnd) +{ + QFont savedF = thePainter.font(); + QFont f(savedF); + f.setBold(isHilight()); + thePainter.setFont(f); + + QBrush savedB = thePainter.brush(); + QBrush br( myColor ); + thePainter.setBrush(br); + + QPen savedP = thePainter.pen(); + if ( myType.compare(QString("Sequence")) ) + thePainter.setPen(thePainter.brush().color().dark(140)); + + // port name + thePainter.drawRoundRect(myNameRect,theXRnd,theYRnd); + if ( !myGate ) + { + // port type + thePainter.drawRoundRect(myTypeRect,theXRnd,theYRnd); + // port value + thePainter.drawRoundRect(myValueRect,theXRnd,theYRnd); + } + + /*if (myPort->isStream()) + thePainter.setPen(QColor(128, 64, 0)); + else */ + if (isHilight()) + thePainter.setPen(Qt::black); + else if (isAlert()) + thePainter.setPen(Qt::red.dark(120)); + else + thePainter.setPen(Qt::white); + + drawText(thePainter, myName, myNameRect, getAlignment()); + if ( !myGate ) + { + drawText(thePainter, myType, myTypeRect, getAlignment()); + drawText(thePainter, myValue, myValueRect, getAlignment()); + } + + thePainter.setPen(savedP); + thePainter.setFont(savedF); + thePainter.setBrush(savedB); + + // draw bounding rectangle of the port if it is currently selected + if ( isSelected() ) + { + QBrush savedB = thePainter.brush(); + thePainter.setBrush(Qt::NoBrush); + + QRect aRect = getPortRect(); + aRect.setTopLeft(aRect.topLeft()-QPoint(PORT_MARGIN/2,PORT_MARGIN/2)); + if ( myGate ) + aRect.setBottomRight(aRect.bottomRight()+QPoint(PORT_MARGIN/2,PORT_MARGIN/2)); + else + aRect.setBottomRight(aRect.bottomRight()+QPoint(PORT_MARGIN/2-2,PORT_MARGIN/2)); + thePainter.drawRect(aRect); + + thePainter.setBrush(savedB); + } +} + +/*! + * =========================== YACSPrs_Hook =========================== + !*/ + +YACSPrs_Hook::YACSPrs_Hook(SUIT_ResourceMgr* theMgr, + QCanvas* theCanvas, + YACSPrs_ElementaryNode* theNode, + const bool& theIn, + const bool& theGate, + const bool& theMaster): + QCanvasEllipse(HOOKPOINT_SIZE, HOOKPOINT_SIZE, theCanvas), + myMgr(theMgr), myNodePrs(theNode), myPortPrs(0), myIn(theIn), myGate(theGate), myMaster(theMaster), myLine(0), mySelected(false) +{ + init(theCanvas); +} + +YACSPrs_Hook::YACSPrs_Hook(SUIT_ResourceMgr* theMgr, + QCanvas* theCanvas, + YACSPrs_Port* thePort, + const bool& theIn, + const bool& theGate, + const bool& theMaster): + QCanvasEllipse(HOOKPOINT_SIZE, HOOKPOINT_SIZE, theCanvas), + myMgr(theMgr), myNodePrs(0), myPortPrs(thePort), myIn(theIn), myGate(theGate), myMaster(theMaster), myLine(0), mySelected(false) +{ + init(theCanvas); +} + +void YACSPrs_Hook::init(QCanvas* theCanvas) +{ + if ( myMaster ) + { + setSize(HOOKPOINTMASTER_SIZE, HOOKPOINTMASTER_SIZE/2); + setAngles(180*16,180*16); + } + else if ( myGate ) + { + setSize(HOOKPOINTGATE_SIZE, HOOKPOINTGATE_SIZE); + if ( myIn ) setAngles(90*16,180*16); + else setAngles(270*16,180*16); + } + else + { + myLine = new QCanvasLine(theCanvas); + myLine->setPen(QPen(HOOK_COLOR, 2)); + } + + setBrush(HOOK_COLOR); + setZ(1); +} + +YACSPrs_Hook::~YACSPrs_Hook() +{ + hide(); + if ( myLine ) { + delete myLine; + myLine = 0; + } +} + +void YACSPrs_Hook::setCanvas(QCanvas* theCanvas) +{ + QCanvasItem::setCanvas(theCanvas); + + // set canvas to line + if (myLine) myLine->setCanvas(theCanvas); +} + +void YACSPrs_Hook::hilight(const QPoint& theMousePos, const bool toHilight) +{ + if ( mySelected ) return; + + // process the hilighting for hook: + QColor aHookHilightColor = myMgr->colorValue("YACSGui", "hook_hilight_color", HOOK_HILIGHT_COLOR); + QColor aHookDrawColor = myMgr->colorValue("YACSGui", "hook_color", HOOK_COLOR); + QColor aDefinedColor = toHilight?aHookHilightColor:aHookDrawColor; + + if (myNodePrs) { + YACSPrs_LabelLink* aLabelLink = myNodePrs->getLabelLink(); + if (aLabelLink) { + YACSPrs_LabelPort* aLabelPort = aLabelLink->getOutputPort(); + QColor aColor = toHilight?aHookHilightColor:aLabelPort->storeColor(); + setColor(aColor); + aLabelLink->setHilighted(toHilight); + aLabelPort->GetHook()->setColor(aColor); + } + else + setColor(aDefinedColor); + } + else if (YACSPrs_LabelPort* aLabelPort = dynamic_cast(myPortPrs)) + setColor(toHilight?aHookHilightColor:aLabelPort->storeColor()); + else + setColor(aDefinedColor); + + // hilight items connected to the hook + if (myPortPrs) + { + std::list aLinks = myPortPrs->getLinks(); + if ( aLinks.size() < 1 ) { + if ( canvas() ) canvas()->update(); + return; + } + std::list::iterator it = aLinks.begin(); + for(; it != aLinks.end(); it++) { + YACSPrs_Link* aLink = *it; + aLink->setHilighted(toHilight); + if (YACSPrs_LabelLink* aLabelLink = dynamic_cast(aLink)) { + if (YACSPrs_ElementaryNode* aSlaveNode = aLabelLink->getSlaveNode()) + aSlaveNode->setMasterPointColor(toHilight?aHookHilightColor:myPortPrs->storeColor()); + } + else if (YACSPrs_PortLink* aPortLink = dynamic_cast(aLink)) { + + if (aPortLink->getInputPort() != myPortPrs) + aPortLink->getInputPort()->GetHook()->setColor(aDefinedColor); + else + aPortLink->getOutputPort()->GetHook()->setColor(aDefinedColor); + } + } + } + + if ( canvas() ) canvas()->update(); +} + +void YACSPrs_Hook::select(const QPoint& theMousePos, const bool toSelect) +{ + // unhilight the item under the mouse cursor + hilight(theMousePos, false); + + // process the hilighting for hook: + mySelected = toSelect; + QColor aDefinedColor = toSelect?HOOK_SELECT_COLOR:HOOK_COLOR; + + if (myNodePrs) { + YACSPrs_LabelLink* aLabelLink = myNodePrs->getLabelLink(); + if (aLabelLink) { + YACSPrs_LabelPort* aLabelPort = aLabelLink->getOutputPort(); + QColor aColor = toSelect?HOOK_SELECT_COLOR:aLabelPort->storeColor(); + setColor(aColor); + aLabelLink->setSelected(toSelect); + aLabelPort->GetHook()->setSelected(toSelect); + aLabelPort->GetHook()->setColor(aColor); + } + else + setColor(aDefinedColor); + } + else if (YACSPrs_LabelPort* aLabelPort = dynamic_cast(myPortPrs)) + setColor(toSelect?HOOK_SELECT_COLOR:aLabelPort->storeColor()); + else + setColor(aDefinedColor); + + // select items connected to the hook + if (myPortPrs) + { + std::list aLinks = myPortPrs->getLinks(); + if ( aLinks.size() < 1 ) return; + std::list::iterator it = aLinks.begin(); + for(; it != aLinks.end(); it++) { + YACSPrs_Link* aLink = *it; + aLink->setSelected(toSelect); + if (YACSPrs_LabelLink* aLabelLink = dynamic_cast(aLink)) { + if (YACSPrs_ElementaryNode* aSlaveNode = aLabelLink->getSlaveNode()) { + if ( aSlaveNode->getMasterPoint() ) aSlaveNode->getMasterPoint()->setSelected(toSelect); + aSlaveNode->setMasterPointColor(toSelect?HOOK_SELECT_COLOR:myPortPrs->storeColor()); + } + } + else if (YACSPrs_PortLink* aPortLink = dynamic_cast(aLink)) { + + if (aPortLink->getInputPort() != myPortPrs) { + aPortLink->getInputPort()->GetHook()->setSelected(toSelect); + aPortLink->getInputPort()->GetHook()->setColor(aDefinedColor); + } + else { + aPortLink->getOutputPort()->GetHook()->setSelected(toSelect); + aPortLink->getOutputPort()->GetHook()->setColor(aDefinedColor); + } + } + } + } + + if ( canvas() ) canvas()->update(); +} + +void YACSPrs_Hook::showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos) +{ +} + +QObject* YACSPrs_Hook::getObject() const +{ + /*QObject* anObj = 0; + if ( myNodePrs ) + anObj = myNodePrs->getNode(); + else if ( myPortPrs ) + anObj = myPortPrs->getPort(); + return anObj;*/ +} + +void YACSPrs_Hook::setCoords(int x, int y) +{ + move(x,y); + if (myLine) { // for not Gate port only + myLine->move(0, 0); + myLine->setPoints(x+(myIn?3*HOOKPOINT_SIZE/2:-3*HOOKPOINT_SIZE/2), y, x, y); + myTrPoint = QPoint(myLine->startPoint().x()+(myIn?-HOOKPOINT_SIZE/2:HOOKPOINT_SIZE/2), + myLine->startPoint().y()-HOOKPOINT_SIZE/2); + // myTrPoint + // x + // |\ + // input port __|_\ output port + // | / + // |/ + } +} + +void YACSPrs_Hook::setColor(const QColor& theColor) +{ + setBrush(theColor); + if(myLine) + myLine->setPen(QPen(theColor, 2)); +} + +void YACSPrs_Hook::setVisible(bool b) +{ + QCanvasEllipse::setVisible(b); + if (myLine) myLine->setVisible(b); +} + +void YACSPrs_Hook::moveBy(double dx, double dy) +{ + QCanvasEllipse::moveBy(dx, dy); + if (myLine) + { + myLine->moveBy(dx, dy); + myTrPoint.setX((int)(myTrPoint.x()+dx)); + myTrPoint.setY((int)(myTrPoint.y()+dy)); + } +} + +void YACSPrs_Hook::setZ(double z) +{ + QCanvasEllipse::setZ(z); + if (myLine) myLine->setZ(z); +} + +int YACSPrs_Hook::rtti() const +{ + return 0;//YACSPrs_Canvas::Rtti_Hook; +} + +QPointArray YACSPrs_Hook::areaPoints() const +{ + if ( myGate || myMaster ) return QCanvasEllipse::areaPoints(); + else + { + int w = width() + ( myLine ? ( myIn ? -1 : 1 )*(myLine->endPoint().x()-myLine->startPoint().x()) : 0 ); + int h = height()+1; // add pen width + + QPointArray aPnts(4); + aPnts[0] = QPoint((int)x(), (int)y()) + QPoint( myIn ? -HOOKPOINT_SIZE/2 : HOOKPOINT_SIZE/2 , -HOOKPOINT_SIZE/2); + aPnts[1] = aPnts[0] + QPoint( myIn ? w : -w , 0); + aPnts[2] = aPnts[1] + QPoint(0, h); + aPnts[3] = aPnts[0] + QPoint(0, h); + return aPnts; + } +} + +void YACSPrs_Hook::drawShape(QPainter& thePainter) +{ + QCanvasEllipse::drawShape(thePainter); + + if ( myMaster ) + { + QPen savedP = thePainter.pen(); + thePainter.setPen(Qt::white); + QRect aRectText((int)(x()-width()/2), (int)y(), width(), height()/2); + drawText(thePainter, QString("Master"), aRectText, Qt::AlignHCenter); + thePainter.setPen(savedP); + } + else if ( myGate ) + { // draw line + //thePainter.drawLine( (int)x(), (int)(y()-HOOKPOINTGATE_SIZE/2), + // (int)x(), (int)(y()+HOOKPOINTGATE_SIZE/2) ); + } + else + { //draw triangle + if ( myLine ) + { + QPointArray aPA(3); + aPA.putPoints(0, 3, myTrPoint.x(),myTrPoint.y(), + myTrPoint.x()+HOOKPOINT_SIZE/2,myTrPoint.y()+HOOKPOINT_SIZE/2, + myTrPoint.x(),myTrPoint.y()+HOOKPOINT_SIZE); + thePainter.drawPolygon( aPA ); + } + } +} diff --git a/src/prs/YACSPrs_ElementaryNode.h b/src/prs/YACSPrs_ElementaryNode.h new file mode 100644 index 000000000..b38dcafa3 --- /dev/null +++ b/src/prs/YACSPrs_ElementaryNode.h @@ -0,0 +1,429 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSPRS_ELEMENTARYNODE_H +#define YACSPRS_ELEMENTARYNODE_H + +#include +#include + +#include "QxGraph_ActiveItem.h" + +#include +#include + + +class SUIT_ResourceMgr; + +class YACSPrs_Port; +class YACSPrs_ElementaryNode; + +class YACSPrs_Hook : public QxGraph_ActiveItem, public QCanvasEllipse +{ + public: + YACSPrs_Hook(SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACSPrs_ElementaryNode* theNode, + const bool& theIn, const bool& theGate, const bool& theMaster=false); + YACSPrs_Hook(SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACSPrs_Port* thePort, + const bool& theIn, const bool& theGate, const bool& theMaster=false); + ~YACSPrs_Hook(); + + virtual void setCanvas(QCanvas* theCanvas); + + /* reimplement functions from QxGraph_ActiveItem */ + virtual bool isMoveable() { return false; } + virtual void beforeMoving() {} + virtual void afterMoving() {} + virtual void hilight(const QPoint& theMousePos, const bool toHilight = true); + virtual void select(const QPoint& theMousePos, const bool toSelect = true); + virtual void showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos = QPoint()); + virtual QString getToolTipText(const QPoint& theMousePos, QRect& theRect) const { return QString(""); } + + QObject* getObject() const; + + void setCoords(int x, int y); + + void setColor(const QColor& theColor); + + void setVisible(bool b); + void moveBy(double dx, double dy); + void setZ(double z); + + void setSelected(bool b) { mySelected = b; } + + virtual int rtti() const; + + QPointArray areaPoints() const; + + protected: + //void draw(QPainter& thePainter); + virtual void drawShape(QPainter& thePainter); + + SUIT_ResourceMgr* myMgr; + + private: + void init(QCanvas* theCanvas); + + YACSPrs_ElementaryNode* myNodePrs; + YACSPrs_Port* myPortPrs; + + bool myIn; + bool myGate; + bool myMaster; + + QCanvasLine* myLine; + QPoint myTrPoint; + + bool mySelected; +}; + +class YACSPrs_Link; +class YACSPrs_ElementaryNode; +class YACSPrs_Port { + + public: + YACSPrs_Port( SUIT_ResourceMgr*, QCanvas*, YACSPrs_ElementaryNode*); + ~YACSPrs_Port(); + + std::list getLinks() const { return myLinks; } + YACSPrs_ElementaryNode* getNode() const { return myNode; } + + void setCanvas(QCanvas* theCanvas); + + void addLink(YACSPrs_Link* theLink) { myLinks.push_back(theLink); } + void removeLink(YACSPrs_Link* theLink) { if (!myLinks.empty()) myLinks.remove(theLink); } + void updateLinks(bool theMoveInternalLinkPoints=false, QRect theArea=QRect()); + YACSPrs_Hook* GetHook() const { return myPoint; } + + virtual QString getName() const; + + virtual void setPortRect(const QRect& theRect, bool theMoveInternalLinkPoints=false, QRect theArea=QRect()) = 0; + virtual QRect getPortRect() const = 0; + + void setVisible(bool b); + void changeVisibility(bool b) { myVisible = b; } + bool isVisible() const { return myVisible; } + + virtual void setColor(const QColor& theColor, bool theUpdatePointColor=true, + bool theUpdate=false, bool theSelectionProcess=false); + QColor Color() const { return myColor; } + + virtual void setStoreColor(const QColor& theColor) { myStoreColor = theColor; } + QColor storeColor() const { return myStoreColor; } + + virtual void moveBy(int dx, int dy); + virtual void setZ(double z, bool updateLinksZ); + double z(); + + void setSelected(bool b) { mySelected = b; } + bool isSelected() const { return mySelected; } + + virtual QPoint getConnectionPoint() const = 0; + virtual void draw(QPainter& thePainter, int theXRnd, int theYRnd) = 0; + + protected: + SUIT_ResourceMgr* myMgr; + + QCanvas* myCanvas; + + QRect myNameRect; + QString myName; + + YACSPrs_Hook* myPoint; + bool myVisible; + + QColor myColor; + QColor myStoreColor; + + std::list myLinks; + + private: + bool mySelected; + + YACSPrs_ElementaryNode* myNode; +}; + +class YACSPrs_LabelPort : public YACSPrs_Port { + + public: + YACSPrs_LabelPort( SUIT_ResourceMgr*, QCanvas*, YACS::ENGINE::Node*, YACSPrs_ElementaryNode*, + const bool& theSwitch=false, const int& theId=-1); + ~YACSPrs_LabelPort(); + + YACS::ENGINE::Node* getSlaveNode() const { return mySlaveNode; } + + void setName(QString theName) { myName = theName; } + + virtual void setPortRect(const QRect& theRect, bool theMoveInternalLinkPoints=false, QRect theArea=QRect()); + virtual QRect getPortRect() const; + + virtual void setColor(const QColor& theColor, bool theUpdatePointColor=true, + bool theUpdate=false, bool theSelectionProcess=false); + + virtual void moveBy(int dx, int dy); + + virtual QPoint getConnectionPoint() const; + virtual void draw(QPainter& thePainter, int theXRnd, int theYRnd); + + private: + YACS::ENGINE::Node* mySlaveNode; // engine of slave node (i.e. the node on this case for Switch or + // the node inside the loop body for Loop) +}; + +class YACSPrs_InOutPort : public YACSPrs_Port { + + public: + YACSPrs_InOutPort( SUIT_ResourceMgr*, QCanvas*, YACS::ENGINE::Port*, YACSPrs_ElementaryNode* ); + ~YACSPrs_InOutPort(); + + YACS::ENGINE::Port* getEngine() const { return myEngine; } + + bool isInput() const { return myInput; } + bool isGate() const { return myGate; } + + virtual void update(bool theForce = false, YACS::ENGINE::Port* theEngine = 0); + + virtual bool isHilight() const; + virtual bool isAlert() const; + + virtual QString getName() const; + virtual QString getType(const bool forToolTip = false) const; + virtual QString getValue(YACS::ENGINE::Port* theEngine = 0) const; + + virtual int getAlignment() const; + + virtual void setPortRect(const QRect& theRect, bool theMoveInternalLinkPoints=false, QRect theArea=QRect()); + virtual QRect getPortRect() const; + + virtual void moveBy(int dx, int dy); + virtual void setZ(double z, bool updateLinksZ); + + virtual QPoint getConnectionPoint() const; + virtual void draw(QPainter& thePainter, int theXRnd, int theYRnd); + + private: + YACS::ENGINE::Port* myEngine; // port engine + + QRect myTypeRect; + QRect myValueRect; + + QString myType; + QString myValue; + + bool myInput; // to remove when connect with engine + bool myGate; // to remove when connect with engine +}; + +class YACSPrs_LabelLink; +class YACSPrs_ElementaryNode : public QxGraph_ActiveItem, public QCanvasPolygonalItem { + public: + YACSPrs_ElementaryNode( SUIT_ResourceMgr*, QCanvas*, YACS::ENGINE::Node* ); + virtual ~YACSPrs_ElementaryNode(); + + YACS::ENGINE::Node* getEngine() const { return myEngine; } + + QPtrList getPortList() const { return myPortList; } + + YACSPrs_InOutPort* getPortPrs(YACS::ENGINE::Port* thePort); + + virtual void setCanvas(QCanvas* theCanvas); + + void addLabelLink(YACSPrs_LabelLink* theLink) { myLabelLink = theLink; } + void removeLabelLink(); + void updateLabelLink(); + YACSPrs_LabelLink* getLabelLink() const { return myLabelLink; } + + /* reimplement functions from QxGraph_ActiveItem */ + virtual bool isMoveable() { return true; } + virtual void beforeMoving(); + virtual void afterMoving(); + virtual void hilight(const QPoint& theMousePos, const bool toHilight = true); + virtual void select(const QPoint& theMousePos, const bool toSelect = true); + virtual void showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos = QPoint()); + virtual QString getToolTipText(const QPoint& theMousePos, QRect& theRect) const; + + void setMoving(bool b) { myMoving = b; } + bool isMoving() const { return myMoving; } + + void setSelfMoving(bool b) { mySelfMoving = b; } + bool isSelfMoving() const { return mySelfMoving; } + + void setSelected(bool b) { mySelected = b; } + bool isSelected() const { return mySelected; } + + virtual int rtti() const; + + virtual void setVisible(bool b); + + QPointArray areaPoints() const; + virtual QPointArray maxAreaPoints() const; + virtual QPointArray constructAreaPoints(int theW, int theH) const; + + void moveBy(double dx, double dy); + void setZ(double z); + void setZFromLinks(double z); + + virtual void update(); + virtual void updateForEachLoopBody(YACS::ENGINE::Node* theEngine=0); + virtual void updatePorts(); + virtual void updateGates(bool theCreate); + + virtual void setNodeColor(const QColor& theColor); + virtual QColor nodeColor() const { return myColor; } + + virtual void setNodeSubColor(const QColor& theColor, bool theSelectionProcess=false); + virtual QColor nodeSubColor() const { return mySubColor; } + + void setStoreColor(const QColor& theColor) { myStoreColor = theColor; } + QColor storeColor() const { return myStoreColor; } + + void setStoreSubColor(const QColor& theColor) { myStoreSubColor = theColor; } + QColor storeSubColor() const { return myStoreSubColor; } + + virtual int width() const { return myWidth; } + virtual int height() const; + + virtual int maxWidth() const; + virtual int maxHeight() const; + + virtual int getTitleHeight() const { return myTitleHeight; } + void setTitleHeight(int theTitleHeight) { myTitleHeight = theTitleHeight; } + + virtual int getInfoHeight() const; + virtual int getStatusHeight() const; + virtual int getTimeHeight() const; + virtual int getBodyHeight() const; + virtual int getGateHeight() const; + + virtual int getPixMapHeight() const; + virtual int getPixMapWidth() const; + + virtual QRect getRect() const; + virtual QRect getTitleRect() const; + virtual QRect getPixmapRect(bool theLeft=false, bool theService=false) const; + virtual QRect getBodyRect() const; + virtual QRect getGateRect() const; + + virtual QRect getWholeRect() const { return QRect(); } // a whole progress bar area + virtual QRect getPercentRect() const { return QRect(); } // filled area of the progress bar + + void setTimeIteration(double theTimeIteration) { myTimeIteration = theTimeIteration; } + double getTimeIteration() const { return myTimeIteration; } + + double getStoredPercentage() const { return myPercentage; } + + virtual void nextTimeIteration(YACS::ENGINE::Node* theEngine=0); + virtual double getPercentage(YACS::ENGINE::Node* theEngine=0) const; + + void updateExecTime(YACS::ENGINE::Node* theEngine=0); + bool isFinished() const { return myFinished; } + + virtual void setState(YACS::StatesForNode theState); // set state and update pixmap + /*state type from engine (may be enum)*/ + + YACSPrs_Hook* getMasterPoint() const { return myPointMaster; } + virtual QPoint getConnectionMasterPoint(); + void setMasterPointColor(QColor theColor); + + // for constraint nodes' moving inside the Bloc--> + bool isInBloc() { return myIsInBloc; } + void setIsInBloc(bool theIsInBloc) { myIsInBloc = theIsInBloc; } + void setArea(QRect theArea) { myArea = theArea; } + virtual bool checkArea(double dx, double dy); + // <-- + + bool isCheckAreaNeeded() const { return myIsCheckAreaNeeded; } + void setIsCheckAreaNeeded(bool theValue) { myIsCheckAreaNeeded = theValue; } + + protected: + void draw(QPainter& thePainter); + virtual void drawShape(QPainter& thePainter); + virtual void drawTitleShape(QPainter& thePainter); + + virtual void drawTitle(QPainter& thePainter); + virtual void drawPort(QPainter& thePainter); + virtual void drawGate(QPainter& thePainter); + + virtual void drawFrame(QPainter& thePainter); + void drawBoundary(QPainter& thePainter, int theRightBottomPointIndex); + + SUIT_ResourceMgr* myMgr; + + YACS::ENGINE::Node* myEngine; // node engine + + QPixmap myStatePixmap; + //QCanvasSprite* mySprite; // for states animation + + QString myStatus; + QString myTime; + + int myWidth; + + int myXRnd; + int myYRnd; + + int myPortHeight; + + QPtrList myPortList; + YACSPrs_Port* myHilightedPort; + YACSPrs_Port* mySelectedPort; + + double myZ; + + YACSPrs_Hook* myPointMaster; + YACSPrs_LabelLink* myLabelLink; + + // for constraint nodes' moving inside the Bloc--> + bool myIsInBloc; + QRect myArea; + // <-- + + private: + int myTitleHeight; + int myStatusHeight; + int myTimeHeight; + int myGateHeight; + + QColor myColor; + QColor mySubColor; + QColor myStatusColor; + + QColor myStoreColor; + QColor myStoreSubColor; + + YACSPrs_Hook* myPointIn; + YACSPrs_Hook* myPointOut; + + bool myMoving; + bool mySelfMoving; // field to indicate if node is moving itself + // or as a content of moving Bloc node + bool mySelected; + + // for update node geometry after import from XML file + bool myIsCheckAreaNeeded; + + // for progress bar indicator + double myTimeIteration; + double myPercentage; // note : use for update original body node of ForEachLoop node only + + // for execution time measuring + QTime myStartTime; + bool myStarted; + bool myFinished; +}; + +#endif diff --git a/src/prs/YACSPrs_ForEachLoopNode.cxx b/src/prs/YACSPrs_ForEachLoopNode.cxx new file mode 100644 index 000000000..b590e826a --- /dev/null +++ b/src/prs/YACSPrs_ForEachLoopNode.cxx @@ -0,0 +1,208 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 +// + +#include "YACSPrs_ForEachLoopNode.h" +#include "YACSPrs_Def.h" + +#include "SUIT_ResourceMgr.h" + +#include + +#include + +using namespace YACS::ENGINE; + +/*! + Constructor +*/ +YACSPrs_ForEachLoopNode::YACSPrs_ForEachLoopNode( SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACS::ENGINE::Node* theNode ): + YACSPrs_LoopNode(theMgr, theCanvas, theNode, false) +{ + //updatePorts(); // will be called in moveBy(...) function + moveBy(3*TITLE_HEIGHT/2, 3*TITLE_HEIGHT/2); +} + +/*! + Destructor +*/ +YACSPrs_ForEachLoopNode::~YACSPrs_ForEachLoopNode() +{ +} + +int YACSPrs_ForEachLoopNode::rtti() const +{ + return 0;//YACSPrs_Canvas::Rtti_ForEachLoopNode; +} + +void YACSPrs_ForEachLoopNode::updatePorts() +{ + bool aDisp = isVisible(); + if (aDisp) hide(); + + // ForEachLoop has 2 input ports and 2 output ports. + // Input ports : 1) 'nbBranches' port, its type is 'int', its value is a number of iterations; + // 2) 'SmplsCollection' port, its type is 'sequence' of elelmnts of the given type, + // it is a list of values of the given type. + // Output ports : 1) 'SmplPrt' port, its type is the given type, its value is a value of the + // list item, which is processed at the current moment. + // 2) 'Body' label port, this 'label' port connects with help of label link to + // 'Master' hook of the node, which is set as an internal node of the loop. + + bool withCreate = false; + if ( myPortList.isEmpty() ) withCreate = true; + + QRect r = getBodyRect(); + int aPRectWidth = (int)(r.width()/2) - 2*PORT_MARGIN; + if ( aPRectWidth < PORT_WIDTH ) aPRectWidth = PORT_WIDTH; + + int ix = r.x() + PORT_MARGIN + 1; + int iy = r.y() + PORT_MARGIN;// + 1; + int ox = ix + aPRectWidth + 2*PORT_MARGIN; + int oy = r.y() + PORT_MARGIN;// + 1; + + if ( withCreate ) + { // create (and update) + ForEachLoop* aFELoop = dynamic_cast( myEngine ); + if ( aFELoop ) + { // create 2 input and 1 output ports + // 'nbBranches' + YACSPrs_InOutPort* anIn1Port = new YACSPrs_InOutPort(myMgr,canvas(),aFELoop->edGetNbOfBranchesPort(),this); + anIn1Port->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT)); + anIn1Port->setColor(nodeSubColor()); + anIn1Port->setStoreColor(nodeSubColor()); + myPortList.append(anIn1Port); + // 'SmplsCollection' + YACSPrs_InOutPort* anIn2Port = new YACSPrs_InOutPort(myMgr,canvas(),aFELoop->edGetSeqOfSamplesPort(),this); + anIn2Port->setPortRect(QRect(ix, iy+PORT_HEIGHT+PORT_SPACE, aPRectWidth, PORT_HEIGHT)); + anIn2Port->setColor(nodeSubColor()); + anIn2Port->setStoreColor(nodeSubColor()); + myPortList.append(anIn2Port); + + myPortHeight += 2*PORT_HEIGHT+PORT_SPACE; + + // 'SmplPtr' + YACSPrs_InOutPort* anOutPort = new YACSPrs_InOutPort(myMgr,canvas(),aFELoop->edGetSamplePort(),this); + anOutPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT)); + anOutPort->setColor(nodeSubColor()); + anOutPort->setStoreColor(nodeSubColor()); + myPortList.append(anOutPort); + + // get a set of internal loop nodes (in fact ForEachLoop has 2 internal nodes: _node and _initNode, + // but only _node was initialized in engine, in all examples _initNode is null) + std::set aNodes = aFELoop->edGetDirectDescendants(); + std::set::iterator aNodesIter = aNodes.begin(); + for (; aNodesIter != aNodes.end(); aNodesIter++) + { // output label port + YACSPrs_LabelPort* anOutPort = new YACSPrs_LabelPort(myMgr,canvas(),*aNodesIter,this); + anOutPort->setPortRect(QRect(ox, oy+PORT_HEIGHT+PORT_SPACE, aPRectWidth, PORT_HEIGHT)); + anOutPort->setColor(nodeSubColor().dark(140)); + anOutPort->setStoreColor(nodeSubColor().dark(140)); + myPortList.append(anOutPort); + oy += PORT_HEIGHT+PORT_SPACE; + } + if ( aNodes.size() > 1 ) + myPortHeight += (aNodes.size()-1)*PORT_HEIGHT + (aNodes.size()-2)*PORT_SPACE; + } + } + else + { // only update + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + YACSPrs_InOutPort* anIOPort = dynamic_cast( aPort ); + if ( anIOPort ) + { + if ( !anIOPort->isGate() ) + { + if ( anIOPort->isInput() ) + { // input data (i.e. not Gate) ports + anIOPort->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT), !isSelfMoving(), myArea); + iy += PORT_HEIGHT+PORT_SPACE; + } + else + { // output data (i.e. not Gate) ports + anIOPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT), !isSelfMoving(), myArea); + oy += PORT_HEIGHT+PORT_SPACE; + } + } + } + else + { // not YACSPrs_InOutPort => it is YACSPrs_LabelPort (output!) => we not need to dynamic cast + aPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT), !isSelfMoving(), myArea); + oy += PORT_HEIGHT+PORT_SPACE; + } + } + } + + // can update gates only after body height will be defined + updateGates(withCreate); + + if (aDisp) show(); +} + +//! Increments time iteration. +/*! + * Note : use not null argument of this function only for update original body node of ForEachLoop node. + * + * \param theEngine : the engine of clone node from which we have to update presentation of this node. + */ +void YACSPrs_ForEachLoopNode::nextTimeIteration(YACS::ENGINE::Node* theEngine) +{ + bool nullifyOnToActivate = false; + if ( !theEngine ) theEngine = myEngine; + else nullifyOnToActivate = true; + + if ( theEngine + && + ( theEngine->getState() == YACS::INITED || theEngine->getEffectiveState() == YACS::INITED + || + ( nullifyOnToActivate && ( theEngine->getState() == YACS::TOACTIVATE || theEngine->getEffectiveState() == YACS::TOACTIVATE) ) ) ) + setTimeIteration( 0. ); + else if ( theEngine && + theEngine->getState() != YACS::INITED && theEngine->getEffectiveState() != YACS::INITED && + !isFinished() ) { + if ( ForEachLoop* aLoop = dynamic_cast( theEngine ) ) + setTimeIteration( aLoop->getExecCurrentId()-1. >= 0 ? aLoop->getExecCurrentId()-1. : 0. ); + } +} + +//! Returns the progress bar percentage. +/*! + * Note : use not null argument of this function only for update original body node of ForEachLoop node. + * + * \param theEngine : the engine of clone node from which we have to update presentation of this node. + */ +double YACSPrs_ForEachLoopNode::getPercentage(YACS::ENGINE::Node* theEngine) const +{ + if ( !theEngine ) theEngine = myEngine; + + if ( !theEngine ) return 0.; + + if ( theEngine->getState() == YACS::INITED || theEngine->getEffectiveState() == YACS::INITED || + theEngine->getState() == YACS::TOLOAD || theEngine->getEffectiveState() == YACS::TOLOAD ) + return 0.; + if ( theEngine->getState() == YACS::DONE ) + return 100.; + if ( ForEachLoop* aLoop = dynamic_cast( theEngine ) ) { + SeqAnyInputPort* aCollection = dynamic_cast( aLoop->edGetSeqOfSamplesPort() ); + if ( aCollection && !aCollection->isEmpty() ) + return 100. / aCollection->getNumberOfElements() * getTimeIteration(); + } + return 0.; +} diff --git a/src/prs/YACSPrs_ForEachLoopNode.h b/src/prs/YACSPrs_ForEachLoopNode.h new file mode 100644 index 000000000..18b20a78e --- /dev/null +++ b/src/prs/YACSPrs_ForEachLoopNode.h @@ -0,0 +1,40 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSPRS_FOREACHLOOPNODE_H +#define YACSPRS_FOREACHLOOPNODE_H + +#include "YACSPrs_LoopNode.h" + +class YACSPrs_ForEachLoopNode : public YACSPrs_LoopNode { + public: + YACSPrs_ForEachLoopNode( SUIT_ResourceMgr*, QCanvas*, YACS::ENGINE::Node*); + virtual ~YACSPrs_ForEachLoopNode(); + + /* reimplement functions from QxGraph_ActiveItem */ + virtual void showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos = QPoint()) {} + + virtual int rtti() const; + + virtual void updatePorts(); + + virtual void nextTimeIteration(YACS::ENGINE::Node* theEngine=0); + virtual double getPercentage(YACS::ENGINE::Node* theEngine=0) const; +}; + +#endif diff --git a/src/prs/YACSPrs_IfNode.cxx b/src/prs/YACSPrs_IfNode.cxx new file mode 100644 index 000000000..4d40396f4 --- /dev/null +++ b/src/prs/YACSPrs_IfNode.cxx @@ -0,0 +1,129 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 +// + +#include "YACSPrs_IfNode.h" +#include "YACSPrs_Def.h" + +#include "SUIT_ResourceMgr.h" + +#include + +/*! + Constructor +*/ +YACSPrs_IfNode::YACSPrs_IfNode( SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACS::ENGINE::Node* theNode ): + YACSPrs_InlineNode(theMgr, theCanvas, theNode) +{ + setNodeColor(IFNODE_COLOR); + setNodeSubColor(IFNODE_SUBCOLOR); + + setStoreColor(nodeColor()); + setStoreSubColor(nodeSubColor()); + + myTitlePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_TITLE_RARROW" )); + moveBy(0, 2*TITLE_HEIGHT); +} + +/*! + Destructor +*/ +YACSPrs_IfNode::~YACSPrs_IfNode() +{ +} + +int YACSPrs_IfNode::rtti() const +{ + return 0;//YACSPrs_Canvas::Rtti_IfNode; +} + +QPointArray YACSPrs_IfNode::constructAreaPoints(int theW, int theH) const +{ + int aCorner = 2*TITLE_HEIGHT; + + QPointArray aPnts(5); + QPoint p((int)x(), (int)y()); + aPnts[0] = p + QPoint(-NODEBOUNDARY_MARGIN,0); + aPnts[1] = p + QPoint(theW/2, -aCorner) + QPoint(0,-NODEBOUNDARY_MARGIN); + aPnts[2] = p + QPoint(theW, 0) + QPoint(NODEBOUNDARY_MARGIN,0); + aPnts[3] = aPnts[2] + QPoint(0, theH) + QPoint(0,NODEBOUNDARY_MARGIN/2); + aPnts[4] = p + QPoint(0, theH) + QPoint(-NODEBOUNDARY_MARGIN,NODEBOUNDARY_MARGIN/2); + return aPnts; +} + +void YACSPrs_IfNode::drawFrame(QPainter& thePainter) +{ + QRect aRect = getRect(); + QRect aTRect = getTitleRect(); + int aXRnd = aTRect.width()*myXRnd/aRect.width(); + int aYRnd = aTRect.height()*myYRnd/aRect.height(); + + QPen savedP = thePainter.pen(); + thePainter.setPen(NoPen); + + // calculate width and height for acrs + int w = 4*(aXRnd*aRect.width()/100)/3; + int h = 4*(aYRnd*aRect.height()/100)/3; + + // draw chords without pen + thePainter.drawChord( aRect.x(),aRect.y(), w,h, 90*16, 90*16 ); + thePainter.drawChord( aRect.right()-w+1,aRect.y(), w,h, 0*16, 90*16 ); + thePainter.drawChord( aRect.right()-w+1,aRect.bottom()-h+1, w,h, 270*16, 90*16 ); + thePainter.drawChord( aRect.x(),aRect.bottom()-h+1, w,h, 180*16, 90*16 ); + + //thePainter.drawRoundRect(aRect,aXRnd,aYRnd); + int aCorner = 2*TITLE_HEIGHT; + QPoint aP1(aRect.x()+(w-1)/2,aRect.y()); + QPoint aP2(aRect.x()+aRect.width()/2,aRect.y()-aCorner); + QPoint aP3(aRect.right()-(w-1)/2,aRect.y()); + QPoint aP4(aRect.right(),aRect.y()+h/2-1); + QPoint aP5(aRect.right(),aRect.bottom()-h/2+1); + QPoint aP6(aRect.right()-(w-1)/2,aRect.bottom()); + QPoint aP7(aRect.x()+(w-1)/2,aRect.bottom()); + QPoint aP8(aRect.x(),aRect.bottom()-h/2+1); + QPoint aP9(aRect.x(),aRect.y()+h/2-1); + QPointArray aPA(9); + aPA.putPoints(0, 9, + aP1.x(),aP1.y(), aP2.x(),aP2.y(), aP3.x(),aP3.y(), aP4.x(),aP4.y(), + aP5.x(),aP5.y(), aP6.x(),aP6.y(), aP7.x(),aP7.y(), aP8.x(),aP8.y(), aP9.x(),aP9.y()); + thePainter.drawPolygon( aPA ); + thePainter.setPen(savedP); + + // draw arcs + thePainter.drawArc( aRect.x(),aRect.y(), w,h, 90*16, 90*16 ); + thePainter.drawArc( aRect.right()-w+1,aRect.y(), w,h, 0*16, 90*16 ); + thePainter.drawArc( aRect.right()-w+1,aRect.bottom()-h+1, w,h, 270*16, 90*16 ); + thePainter.drawArc( aRect.x(),aRect.bottom()-h+1, w,h, 180*16, 90*16 ); + + // draw line segments + thePainter.drawLine(aP1,aP2); + thePainter.drawLine(aP2,aP3); + thePainter.drawLine(aP4,aP5); + thePainter.drawLine(aP6,aP7); + thePainter.drawLine(aP8,aP9); + + // draw title pixmap + int x = aRect.x()+aRect.width()/2-myTitlePixmap.width()/2; + int y = aRect.y()-(aCorner-NODE_MARGIN)/2-myTitlePixmap.height()/2; + QRect aTPRect(aRect.x()+aRect.width()/2-aCorner/3, aRect.y()-(aCorner-NODE_MARGIN)/2-aCorner/3, + 2*aCorner/3, 2*aCorner/3); + thePainter.drawPixmap(aTPRect,myTitlePixmap); + + // draw bounding nodes' polygon if node is currently selected + if ( isSelected() ) drawBoundary(thePainter,3); +} diff --git a/src/prs/YACSPrs_IfNode.h b/src/prs/YACSPrs_IfNode.h new file mode 100644 index 000000000..089b62005 --- /dev/null +++ b/src/prs/YACSPrs_IfNode.h @@ -0,0 +1,45 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSPRS_IFNODE_H +#define YACSPRS_IFNODE_H + +#include "YACSPrs_InlineNode.h" + +class YACSPrs_IfNode : public YACSPrs_InlineNode { + public: + YACSPrs_IfNode( SUIT_ResourceMgr*, QCanvas*, YACS::ENGINE::Node* ); + virtual ~YACSPrs_IfNode(); + + /* reimplement functions from QxGraph_ActiveItem */ + virtual void showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos = QPoint()) {} + + virtual int rtti() const; + + virtual QPointArray constructAreaPoints(int theW, int theH) const; + + virtual int getCorner() const { return 0; } + + protected: + virtual void drawFrame(QPainter& thePainter); + + private: + QPixmap myTitlePixmap; +}; + +#endif diff --git a/src/prs/YACSPrs_InlineNode.cxx b/src/prs/YACSPrs_InlineNode.cxx new file mode 100644 index 000000000..101f5517f --- /dev/null +++ b/src/prs/YACSPrs_InlineNode.cxx @@ -0,0 +1,292 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 +// + +#include "YACSPrs_InlineNode.h" +#include "YACSPrs_Def.h" + +#include + +void drawText2(QPainter& thePainter, const QString& theText, + const QRect& theRect, int theHAlign = Qt::AlignAuto) +{ + int flags = theHAlign | Qt::AlignVCenter; + QRect r(theRect.x() + TEXT_MARGIN, theRect.y(), + theRect.width() - 2*TEXT_MARGIN, theRect.height()); + + QWMatrix aMat = thePainter.worldMatrix(); + if (aMat.m11() != 1.0) { + // for scaled picture only + QRect r1 = aMat.mapRect(r); + QFont saved = thePainter.font(); + QFont f(saved); + if (f.pointSize() == -1) { + f.setPixelSize((int)(f.pixelSize()*aMat.m11())); + } + else { + f.setPointSize((int)(f.pointSize()*aMat.m11())); + } + thePainter.save(); + QWMatrix m; + thePainter.setWorldMatrix(m); + thePainter.setFont(f); + thePainter.drawText(r1, flags, theText); + thePainter.setFont(saved); + thePainter.restore(); + } + else { + thePainter.drawText(r, flags, theText); + } +} + + +/*! + Constructor +*/ +YACSPrs_InlineNode::YACSPrs_InlineNode(SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACS::ENGINE::Node* theNode, const bool& thePortUpdate): + YACSPrs_ElementaryNode(theMgr, theCanvas, theNode) +{ + setNodeColor(INLINENODE_COLOR); + setNodeSubColor(INLINENODE_SUBCOLOR); + + setStoreColor(nodeColor()); + setStoreSubColor(nodeSubColor()); + + QRect aTRect = getTitleRect(); + myXRnd = 50*aTRect.height()/aTRect.width(); + myYRnd = 50; + + if ( thePortUpdate ) { + //updatePorts(); // will be called in moveBy(...) function + moveBy(2*HOOKPOINT_SIZE,0); + } + + update(); +} + +/*! + Destructor +*/ +YACSPrs_InlineNode::~YACSPrs_InlineNode() +{ +} + +int YACSPrs_InlineNode::rtti() const +{ + return 0;//YACSPrs_Canvas::Rtti_InlineNode; +} + +QPointArray YACSPrs_InlineNode::constructAreaPoints(int theW, int theH) const +{ + int aCorner = getCorner(); + + QPointArray aPnts(5); + QPoint p((int)x(), (int)y()); + aPnts[0] = p + QPoint(aCorner, 0) + QPoint(0,-NODEBOUNDARY_MARGIN); + aPnts[1] = p + QPoint(theW, 0) + QPoint(NODEBOUNDARY_MARGIN,-NODEBOUNDARY_MARGIN); + aPnts[2] = aPnts[1] + QPoint(0, theH) + QPoint(0,NODEBOUNDARY_MARGIN); + aPnts[3] = p + QPoint(0, theH) + QPoint(-NODEBOUNDARY_MARGIN,0); + aPnts[4] = p + QPoint(0, aCorner) + QPoint(-NODEBOUNDARY_MARGIN,0); + return aPnts; +} + +int YACSPrs_InlineNode::getInfoHeight() const +{ + return getTitleHeight() + NODE_SPACE + + getStatusHeight() + NODE_SPACE + + getTimeHeight(); +} + +QRect YACSPrs_InlineNode::getTitleRect() const +{ + return QRect((int)x()+NODE_MARGIN+getCorner(), (int)y()+NODE_MARGIN, + width()-3*NODE_MARGIN-getCorner()-getPixMapWidth(), getTitleHeight()); +} + +QRect YACSPrs_InlineNode::getStatusRect() const +{ + return QRect(getTitleRect().x(), getTitleRect().bottom()+NODE_SPACE, + getTitleRect().width(), getStatusHeight()); +} + +QRect YACSPrs_InlineNode::getTimeRect() const +{ + return QRect(getStatusRect().x(), getStatusRect().bottom()+NODE_SPACE, + getStatusRect().width(), getTimeHeight()); +} + +QRect YACSPrs_InlineNode::getWholeRect() const +{ + return QRect(getTimeRect().topLeft()+QPoint(3,3), getTimeRect().bottomRight()-QPoint(3,3)); +} + +QRect YACSPrs_InlineNode::getPercentRect() const +{ + int aPercentageW = (int)(getWholeRect().width()*( (getStoredPercentage() < 0) ? getPercentage() : getStoredPercentage() )/100.); + return QRect(getWholeRect().topLeft(), getWholeRect().bottomLeft()+QPoint(aPercentageW,0)); +} + +int YACSPrs_InlineNode::getCorner() const +{ + return NODE_MARGIN + getInfoHeight(); +} + +void YACSPrs_InlineNode::drawTitleShape(QPainter& thePainter) +{ + // draw information: title, status, time + QPen savedP = thePainter.pen(); + thePainter.setPen(thePainter.brush().color().dark(140)); + + // title + thePainter.drawRoundRect(getTitleRect(),myXRnd,myYRnd); + // status + thePainter.drawRoundRect(getStatusRect(),myXRnd,myYRnd); + // time + thePainter.drawRoundRect(getTimeRect(),myXRnd,myYRnd); + + // draw progress bar + thePainter.setPen(NoPen); + + QBrush savedB = thePainter.brush(); + + thePainter.setBrush(savedB.color().light(130)); + thePainter.drawRect(getWholeRect()); + + if ( getPercentRect().width() > 1 ) { + thePainter.setBrush(savedB.color().dark(160)); + thePainter.drawRect(getPercentRect()); + } + + thePainter.setBrush(savedB); + + // draw texts + thePainter.setPen(Qt::white); + + drawText2(thePainter, QString(myEngine->getName()), getTitleRect(), Qt::AlignLeft); + drawText2(thePainter, myStatus, getStatusRect(), Qt::AlignLeft); + drawText2(thePainter, myTime, getTimeRect(), Qt::AlignLeft); + drawText2(thePainter, QString::number(( (getStoredPercentage() < 0) ? getPercentage() : getStoredPercentage() ))+QString("%"), getTimeRect(), Qt::AlignRight); // percentage + + thePainter.setPen(savedP); + + // draw pixmap + thePainter.setBrush(NoBrush); + + int aXRnd = getTitleRect().width()*myXRnd/getPixmapRect().width(); + int aYRnd = getTitleRect().height()*myYRnd/getPixmapRect().height(); + thePainter.drawRoundRect(getPixmapRect(),aXRnd,aYRnd); + QRect aPRect = getPixmapRect(); + aPRect.setX(aPRect.x()+PIXMAP_MARGIN+2); + aPRect.setY(aPRect.y()+PIXMAP_MARGIN); + aPRect.setWidth(aPRect.width()-2*PIXMAP_MARGIN); + aPRect.setHeight(aPRect.height()-2*PIXMAP_MARGIN); + thePainter.drawPixmap(aPRect,myStatePixmap); + + thePainter.setBrush(savedB); +} + +void YACSPrs_InlineNode::drawFrame(QPainter& thePainter) +{ + QRect aRect = getRect(); + QRect aTRect = getTitleRect(); + int aXRnd = aTRect.width()*myXRnd/aRect.width(); + int aYRnd = aTRect.height()*myYRnd/aRect.height(); + + QPen savedP = thePainter.pen(); + thePainter.setPen(NoPen); + + // calculate width and height for acrs and chords + int w = 4*(aXRnd*aRect.width()/100)/3; + int h = 4*(aYRnd*aRect.height()/100)/3; + // draw chords + thePainter.drawChord( aRect.right()-w+1,aRect.y(), w,h, 0*16, 90*16 ); + thePainter.drawChord( aRect.right()-w+1,aRect.bottom()-h+1, w,h, 270*16, 90*16 ); + thePainter.drawChord( aRect.x(),aRect.bottom()-h+1, w,h, 180*16, 90*16 ); + + // draw polygon + int aCorner = getCorner(); + QPoint aP1(aRect.x(),aRect.y()+aCorner); + QPoint aP2(aRect.x()+aCorner,aRect.y()); + QPoint aP3(aRect.right()-(w-1)/2,aRect.y()); + QPoint aP4(aRect.right(),aRect.y()+h/2-1); + QPoint aP5(aRect.right(),aRect.bottom()-h/2+1); + QPoint aP6(aRect.right()-(w-1)/2,aRect.bottom()); + QPoint aP7(aRect.x()+(w-1)/2,aRect.bottom()); + QPoint aP8(aRect.x(),aRect.bottom()-h/2+1); + QPointArray aPA(8); + aPA.putPoints(0, 8, + aP1.x(),aP1.y(), aP2.x(),aP2.y(), aP3.x(),aP3.y(), aP4.x(),aP4.y(), + aP5.x(),aP5.y(), aP6.x(),aP6.y(), aP7.x(),aP7.y(), aP8.x(),aP8.y()); + thePainter.drawPolygon( aPA ); + thePainter.setPen(savedP); + + // draw arcs + thePainter.drawArc( aRect.right()-w+1,aRect.y(), w,h, 0*16, 90*16 ); + thePainter.drawArc( aRect.right()-w+1,aRect.bottom()-h+1, w,h, 270*16, 90*16 ); + thePainter.drawArc( aRect.x(),aRect.bottom()-h+1, w,h, 180*16, 90*16 ); + + // draw line segments + thePainter.drawLine(aP1,aP2); + thePainter.drawLine(aP2,aP3); + thePainter.drawLine(aP4,aP5); + thePainter.drawLine(aP6,aP7); + thePainter.drawLine(aP8,aP1); + + // draw corner + savedP = thePainter.pen(); + thePainter.setPen(NoPen); + QBrush savedB = thePainter.brush(); + thePainter.setBrush(savedB.color().dark(120)); + + thePainter.drawChord( aRect.x()+aCorner-w+1,aRect.y()+aCorner-h+1, w,h, 270*16, 90*16 ); + + QPoint aP9(aRect.x()+aCorner,aRect.y()+aCorner-h/2+1); + QPoint aP10(aRect.x()+aCorner-(w-1)/2,aRect.y()+aCorner); + QPointArray aPAC(4); + aPAC.putPoints(0, 4, aP1.x(),aP1.y(), aP2.x(),aP2.y(), aP9.x(),aP9.y(), aP10.x(),aP10.y()); + thePainter.drawPolygon( aPAC ); + + thePainter.setBrush(savedB); + thePainter.setPen(savedP); + + thePainter.drawArc( aRect.x()+aCorner-w+1,aRect.y()+aCorner-h+1, w,h, 270*16, 90*16 ); + + thePainter.drawLine(aP1,aP2); + thePainter.drawLine(aP2,aP9); + thePainter.drawLine(aP10,aP1); + + // draw bounding nodes' polygon if node is currently selected + if ( isSelected() ) drawBoundary(thePainter,2); +} + +QString YACSPrs_InlineNode::getToolTipText(const QPoint& theMousePos, QRect& theRect) const +{ + // Check if the tooltip for ports is needed + if (getBodyRect().contains(theMousePos, true) || getGateRect().contains(theMousePos, true)) + return YACSPrs_ElementaryNode::getToolTipText(theMousePos,theRect); + + // Return tooltip text for node + QString aText = QString(""); + aText += QString("Name: %1\n").arg(getEngine()->getName()); + aText += QString("Type: %1\n").arg("Inline node"); + theRect = getTitleRect(); + theRect = theRect.unite(getStatusRect()); + theRect = theRect.unite(getTimeRect()); + theRect = theRect.unite(getPixmapRect()); + return aText; +} diff --git a/src/prs/YACSPrs_InlineNode.h b/src/prs/YACSPrs_InlineNode.h new file mode 100644 index 000000000..d581a905a --- /dev/null +++ b/src/prs/YACSPrs_InlineNode.h @@ -0,0 +1,55 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSPRS_INLINENODE_H +#define YACSPRS_INLINENODE_H + +#include "YACSPrs_ElementaryNode.h" + +class YACSPrs_InlineNode : public YACSPrs_ElementaryNode { + public: + YACSPrs_InlineNode( SUIT_ResourceMgr*, QCanvas*, YACS::ENGINE::Node*, const bool& thePortUpdate=true ); + virtual ~YACSPrs_InlineNode(); + + /* reimplement functions from QxGraph_ActiveItem */ + virtual void showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos = QPoint()) {} + + virtual int rtti() const; + + virtual QPointArray constructAreaPoints(int theW, int theH) const; + + virtual int getInfoHeight() const; + + virtual QRect getTitleRect() const; + virtual QRect getStatusRect() const; + virtual QRect getTimeRect() const; + + virtual QRect getWholeRect() const; + virtual QRect getPercentRect() const; + + virtual int getCorner() const; + + virtual QString getToolTipText(const QPoint& theMousePos, QRect& theRect) const; + + protected: + virtual void drawTitleShape(QPainter& thePainter); + virtual void drawFrame(QPainter& thePainter); + +}; + +#endif diff --git a/src/prs/YACSPrs_Link.cxx b/src/prs/YACSPrs_Link.cxx new file mode 100644 index 000000000..76073e623 --- /dev/null +++ b/src/prs/YACSPrs_Link.cxx @@ -0,0 +1,901 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 +// + +#include "YACSPrs_ElementaryNode.h" + +#include "YACSPrs_Link.h" +#include "YACSPrs_Def.h" + +#include "SUIT_ResourceMgr.h" +#include "SUIT_Session.h" + +#include "CAM_Application.h" + +#include + +/*! + * =========================== YACSPrs_Link =========================== + !*/ + +YACSPrs_Link::YACSPrs_Link( SUIT_ResourceMgr* theMgr, QCanvas* theCanvas ): + QObject(theCanvas), + myMgr(theMgr), + myCanvas(theCanvas), + myHilighted(false), + mySelected(false), + mySelectedItem(0) +{ + myColor = myMgr->colorValue("YACSGui", "link_draw_color", LINKDRAW_COLOR); + myZ = 0; +} + +YACSPrs_Link::~YACSPrs_Link() +{ + // TO DO : check commented code if link is deleted + //for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) { + //(*it)->hide(); + //delete *it; + //} + + myPoints.clear(); +} + +void YACSPrs_Link::show() +{ + if (myPrs.isEmpty()) createPrs(); + + for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) { + (*it)->show(); + } +} + +void YACSPrs_Link::merge() +{ + // save z of the link + double aZ = ( !myPrs.isEmpty() ? myPrs.first()->z()-1 : 0 ); // the first item is a point + + // remove old presentation + for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) { + (*it)->setCanvas(0); + delete *it; + } + myPrs.clear(); + + // display a new one + show(); + + // restore z of the link + setZ(aZ); +} + +void YACSPrs_Link::updatePoints(QCanvasItem* thePointItem) +{ + if ( thePointItem == myPrs.first() || thePointItem == myPrs.last() ) return; + + YACSPrs_Point* aPoint = dynamic_cast( thePointItem ); + if ( aPoint ) + { + std::list::iterator it; + int id = 1; + for ( it = myPoints.begin(); it != myPoints.end(); it++, id++ ) + if ( id == aPoint->getIndex() ) { + (*it).setX((int)(aPoint->x())); + (*it).setY((int)(aPoint->y())); + break; + } + } +} + +void YACSPrs_Link::setHilighted(bool state) +{ + myHilighted = state; + QColor aHilightColor = myMgr->colorValue("YACSGui", "link_hilight_color", LINK_HILIGHT_COLOR); + setColor(myHilighted ? aHilightColor : myColor); + if (!myPrs.isEmpty()) { + bool disp = myPrs.first()->isVisible(); + if (disp) { + for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) { + (*it)->hide(); (*it)->show(); + } + myCanvas->update(); + } + } +} + +void YACSPrs_Link::setSelected(bool state) +{ + mySelected = state; + setColor(mySelected ? LINK_SELECT_COLOR : myColor); + if (!myPrs.isEmpty()) { + bool disp = myPrs.first()->isVisible(); + if (disp) { + for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) { + if ( YACSPrs_Point* aPoint = dynamic_cast( *it ) ) aPoint->setSelected(state); + else if ( YACSPrs_Edge* anEdge = dynamic_cast( *it ) ) anEdge->setSelected(state); + (*it)->hide(); (*it)->show(); + } + myCanvas->update(); + } + } +} + +void YACSPrs_Link::setColor(const QColor& theColor) +{ + for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) { + YACSPrs_Point* aPoint = dynamic_cast( *it ); + if ( aPoint ) { //if ((*it)->rtti() == YACSPrs_Canvas::Rtti_Point) { + aPoint->setColor(theColor); + } + YACSPrs_Edge* anEdge = dynamic_cast( *it ); + if ( anEdge ) { //if ((*it)->rtti() == YACSPrs_Canvas::Rtti_Edge) { + anEdge->setColor(theColor); + } + } +} + +void YACSPrs_Link::setSelectedObject(QCanvasItem* theItem, const QPoint& thePoint) +{ + mySelectedItem = theItem; + mySelectedPoint = thePoint; +} + +QString YACSPrs_Link::getToolTipText() const { + return QString(); +} + +void YACSPrs_Link::remove() { + delete this; +} + +void YACSPrs_Link::addPoint() { + if ( mySelected ) setSelected(false); + + YACSPrs_Edge* anEdge = dynamic_cast( mySelectedItem ); + if ( anEdge ) { + int anIndex = 1; + QCanvasItemList::Iterator it; + for (it = myPrs.begin(); it != myPrs.end(); ++it) { + if ((*it) == anEdge) break; + } + if (it != myPrs.begin()) { + --it; + YACSPrs_Point* aPoint = (YACSPrs_Point*) (*it); + anIndex = aPoint->getIndex()+1; + if (anIndex < 1) anIndex = 1; + } + // TO DO : add point coordinates to link engine + if ( myPoints.empty() ) + myPoints.push_back(mySelectedPoint); + else { + std::list::iterator it; + int id = 0; + for ( it = myPoints.begin(); it != myPoints.end(); it++, id++ ) + if ( id == anIndex-1 ) break; + myPoints.insert(it, mySelectedPoint); + } + + merge(); + myCanvas->update(); + } +} + +void YACSPrs_Link::removePoint() { + if ( mySelected ) setSelected(false); + + YACSPrs_Point* aPoint = dynamic_cast( mySelectedItem ); + if ( aPoint ) { + // TO DO : remove point coordinates from link engine + QPoint aP((int)(aPoint->x()), (int)(aPoint->y())); + myPoints.remove(aP); + + merge(); + myCanvas->update(); + } +} + +bool YACSPrs_Link::isFirst(QCanvasEllipse* thePoint) +{ + bool aRet = false; + if ( !myPrs.empty() + && + myPrs.first()->x() == thePoint->x() && myPrs.first()->y() == thePoint->y() ) aRet = true; + return aRet; +} + +bool YACSPrs_Link::isLast(QCanvasEllipse* thePoint) +{ + bool aRet = false; + if ( !myPrs.empty() + && + myPrs.last()->x() == thePoint->x() && myPrs.last()->y() == thePoint->y() ) aRet = true; + return aRet; +} + +void YACSPrs_Link::setMyZ(double z) +{ + myZ = z; +} + +double YACSPrs_Link::getMyZ() +{ + return myZ; +} + +void YACSPrs_Link::setZ(double z) +{ + for (QCanvasItemList::Iterator it = myPrs.begin(); it != myPrs.end(); ++it) + if ( dynamic_cast( *it ) ) (*it)->setZ(z+1); + else if ( dynamic_cast( *it ) ) (*it)->setZ(z); +} + +double YACSPrs_Link::z() +{ + if ( !myPrs.empty() ) return myPrs.first()->z(); + return 0; +} + +QPoint YACSPrs_Link::getConnectionPoint(YACSPrs_Port* thePort) +{ + QPoint aCP; + + YACSPrs_InOutPort* anIOPort = dynamic_cast( thePort ); + if ( anIOPort ) + { + aCP = anIOPort->getConnectionPoint(); + if ( anIOPort->isGate() ) + aCP += QPoint( ( anIOPort->isInput() ? -LINKPOINT_SIZE/2-(NODEBOUNDARY_MARGIN+1) : + LINKPOINT_SIZE/2+(NODEBOUNDARY_MARGIN+1) ), 0 ); + } + else + { + YACSPrs_LabelPort* aLPort = dynamic_cast( thePort ); + if ( aLPort ) aCP = aLPort->getConnectionPoint(); + } + + return aCP; +} + +void YACSPrs_Link::addPoint(const QPoint& thePoint, const int& theIndex) +{ + YACSPrs_Point* aPoint; + if (myPrs.empty()) { + aPoint = new YACSPrs_Point(myCanvas, this, theIndex); + aPoint->setColor(myColor); + aPoint->move(thePoint.x(), thePoint.y()); + } + else { + YACSPrs_Point* aPrev = (YACSPrs_Point*) myPrs.last(); + + YACSPrs_Edge* anEdge = new YACSPrs_Edge(myCanvas, this); + anEdge->setColor(myColor); + myPrs.append(anEdge); + + aPoint = new YACSPrs_Point(myCanvas, this, theIndex); + aPoint->setColor(myColor); + aPoint->move(thePoint.x(), thePoint.y()); + + aPrev->setOutEdge(anEdge); + aPoint->setInEdge(anEdge); + } + myPrs.append(aPoint); +} + +void YACSPrs_Link::createPrs() +{ + QColor aHilightColor = myMgr->colorValue("YACSGui", "link_hilight_color", LINK_HILIGHT_COLOR); + setColor(myHilighted ? aHilightColor : myColor); +} + +/*! + * =========================== YACSPrs_PortLink =========================== + !*/ + +YACSPrs_PortLink::YACSPrs_PortLink( SUIT_ResourceMgr* theMgr, + QCanvas* theCanvas, + YACSPrs_InOutPort* theInputPort, + YACSPrs_InOutPort* theOutputPort ): + YACSPrs_Link(theMgr, theCanvas), + myInputPort(theInputPort), + myOutputPort(theOutputPort) +{ + printf("Construct YACSPrs_PortLink\n"); + if (myInputPort) myInputPort->addLink(this); + if (myOutputPort) myOutputPort->addLink(this); +} + +YACSPrs_PortLink::~YACSPrs_PortLink() +{ + if (myInputPort) myInputPort->removeLink(this); + if (myOutputPort) myOutputPort->removeLink(this); +} + +void YACSPrs_PortLink::moveByPort(YACSPrs_Port* thePort, bool theMoveInternalLinkPoints, QRect theArea) +{ + YACSPrs_InOutPort* aPort = dynamic_cast( thePort ); + if ( aPort ) + { + QPoint p = getConnectionPoint(aPort); + + if ( theMoveInternalLinkPoints ) + { + // choose and collect only those points from myPoints, which is inside of theArea + std::map anIndex2MovePointMap; + int id = 1; + for ( std::list::iterator it = myPoints.begin(); it != myPoints.end(); it++, id++) + if ( theArea.contains(*it,true) ) anIndex2MovePointMap.insert(std::make_pair(id,*it)); + + if ( !anIndex2MovePointMap.empty() ) + { + QCanvasItemList::Iterator it = myPrs.begin(); + for (it++; it != myPrs.end(); ++it) { + if ( YACSPrs_Point* aPoint = dynamic_cast( *it ) ) { + if ( anIndex2MovePointMap.find(aPoint->getIndex()) != anIndex2MovePointMap.end() ) { + int dx=0,dy=0; + if ( myInputPort && myInputPort == aPort ) { + dx = p.x() - (int)(myPrs.first()->x()); + dy = p.y() - (int)(myPrs.first()->y()); + } + if ( myOutputPort && myOutputPort == aPort ) { + if ( getInputPort()->getNode()->isSelfMoving() ) { + // move internal points if moveByPort function didn't call yet for the input port of this link + // (because we have to move internal points only once on moving link by input or output port) + dx = p.x() - (int)(myPrs.last()->x()); + dy = p.y() - (int)(myPrs.last()->y()); + } + } + aPoint->moveBy( dx, dy ); + } + } + } + } + } + + if ( myInputPort && myInputPort == aPort ) { + myPrs.first()->move(p.x(), p.y()); + return; + } + if ( myOutputPort && myOutputPort == aPort ) { + myPrs.last()->move(p.x(), p.y()); + return; + } + } +} + +void YACSPrs_PortLink::moveByPort(YACSPrs_Port* thePort, int dx, int dy) +{ + YACSPrs_InOutPort* aPort = dynamic_cast( thePort ); + if ( aPort ) + { + if ( myInputPort && myInputPort == aPort ) { + myPrs.first()->moveBy(dx, dy); + return; + } + if ( myOutputPort && myOutputPort == aPort ) { + myPrs.last()->moveBy(dx, dy); + return; + } + } +} + +QString YACSPrs_PortLink::getToolTipText() const { + QString aText; + if (myInputPort && myOutputPort) + aText = myOutputPort->getEngine()->getNode()->getName() + QString(" : ") + + myOutputPort->getName() + QString(" => ") + + myInputPort->getEngine()->getNode()->getName() + QString(" : ") + + myInputPort->getName(); + return aText; +} + +void YACSPrs_PortLink::remove() { + // for update ports' value after link deletion (only for YACSPrs_InOutPort, i.e. YACSPrs_PortLink) + /*QString aValue; + YACSPrs_InOutPort* aPort = dynamic_cast( myInputPort ); + if ( aPort ) { + if (aPort->getEngine()->IsParam() || myInputPort->getEngine()->IsInLine()) { + aValue = QString(aPort->getEngine()->ToString()); + } + }*/ + + YACSPrs_Link::remove(); + + // for update ports' value after link deletion (only for YACSPrs_InOutPort, i.e. YACSPrs_PortLink) + /*if ( aPort && !aValue.isEmpty() ) { //&& GraphLevel() == 0 + aPort->setValue(aValue); + }*/ + + myCanvas->update(); +} + +void YACSPrs_PortLink::createPrs() +{ + // create without internal points now + if ( myInputPort ) addPoint(getConnectionPoint(myInputPort),0); + + int i = 1; + for ( std::list::iterator it = myPoints.begin(); it != myPoints.end(); it++, i++ ) + addPoint(*it, i); + + if ( myOutputPort ) addPoint(getConnectionPoint(myOutputPort),myPoints.size()+1); + + // the first and last points is smaller than an internal points + if ( QCanvasEllipse* aFP = dynamic_cast( getFirstPoint() ) ) aFP->setSize(LINKPOINT_SIZE/2, LINKPOINT_SIZE/2); + if ( QCanvasEllipse* aLP = dynamic_cast( getLastPoint() ) ) aLP->setSize(LINKPOINT_SIZE/2, LINKPOINT_SIZE/2); + + YACSPrs_Link::createPrs(); +} + +void YACSPrs_PortLink::setHilighted(bool state) +{ + QColor aHilightColor = myMgr->colorValue("YACSGui", "hook_hilight_color", HOOK_HILIGHT_COLOR); + QColor aDrawColor = myMgr->colorValue("YACSGui", "hook_color", HOOK_COLOR); + QColor aColor = state?aHilightColor:aDrawColor; + + // hilight hooks + if (getInputPort()) { + YACSPrs_Hook* aHook = getInputPort()->GetHook(); + if (aHook) aHook->setColor(aColor); + } + if (getOutputPort()) { + YACSPrs_Hook* aHook = getOutputPort()->GetHook(); + if (aHook) aHook->setColor(aColor); + } + + // hilight link + YACSPrs_Link::setHilighted(state); +} + +void YACSPrs_PortLink::setSelected(bool state) +{ + QColor aSelectColor = myMgr->colorValue("YACSGui", "hook_select_color", HOOK_SELECT_COLOR); + QColor aDrawColor = myMgr->colorValue("YACSGui", "hook_color", HOOK_COLOR); + QColor aColor = state?aSelectColor:aDrawColor; + + // select hooks + if (getInputPort()) { + YACSPrs_Hook* aHook = getInputPort()->GetHook(); + if (aHook) { + aHook->setSelected(state); + aHook->setColor(aColor); + } + } + if (getOutputPort()) { + YACSPrs_Hook* aHook = getOutputPort()->GetHook(); + if (aHook) { + aHook->setSelected(state); + aHook->setColor(aColor); + } + } + + // select link + YACSPrs_Link::setSelected(state); +} + +/*! + * =========================== YACSPrs_LabelLink =========================== + !*/ + +YACSPrs_LabelLink::YACSPrs_LabelLink( SUIT_ResourceMgr* theMgr, + QCanvas* theCanvas, + YACSPrs_LabelPort* theOutputPort, + YACSPrs_ElementaryNode* theSlaveNode ): + YACSPrs_Link(theMgr, theCanvas), + myOutputPort(theOutputPort), + mySlaveNode(theSlaveNode) +{ + printf("Construct YACSPrs_LabelLink\n"); + if (myOutputPort) myOutputPort->addLink(this); + if (mySlaveNode) + { + mySlaveNode->addLabelLink(this); + mySlaveNode->setMasterPointColor(theOutputPort->Color()); + } + myColor = theOutputPort->Color();//LABELLINKDRAW_COLOR; +} + +YACSPrs_LabelLink::~YACSPrs_LabelLink() +{ + if (myOutputPort) myOutputPort->removeLink(this); + if (mySlaveNode) mySlaveNode->removeLabelLink(); +} + +void YACSPrs_LabelLink::moveByPort(YACSPrs_Port* thePort, bool theMoveInternalLinkPoints, QRect theArea) +{ + YACSPrs_LabelPort* aPort = dynamic_cast( thePort ); + if ( aPort ) + { + QPoint p = getConnectionPoint(aPort); + + if ( theMoveInternalLinkPoints ) + { + // choose and collect only those points from myPoints, which is inside of theArea + std::map anIndex2MovePointMap; + int id = 1; + for ( std::list::iterator it = myPoints.begin(); it != myPoints.end(); it++, id++) + if ( theArea.contains(*it,true) ) anIndex2MovePointMap.insert(std::make_pair(id,*it)); + + if ( !anIndex2MovePointMap.empty() ) + { + QCanvasItemList::Iterator it = myPrs.begin(); + for (it++; it != myPrs.end(); ++it) { + if ( YACSPrs_Point* aPoint = dynamic_cast( *it ) ) { + if ( anIndex2MovePointMap.find(aPoint->getIndex()) != anIndex2MovePointMap.end() ) { + int dx=0,dy=0; + if ( myOutputPort && myOutputPort == aPort ) { + dx = p.x() - (int)(myPrs.last()->x()); + dy = p.y() - (int)(myPrs.last()->y()); + } + aPoint->moveBy( dx, dy ); + } + } + } + } + } + + if ( myOutputPort && myOutputPort == aPort ) { + myPrs.last()->move(p.x(), p.y()); + return; + } + } +} + +void YACSPrs_LabelLink::moveByPort(YACSPrs_Port* thePort, int dx, int dy) +{ + YACSPrs_LabelPort* aPort = dynamic_cast( thePort ); + if ( aPort ) + { + if ( myOutputPort && myOutputPort == aPort ) { + myPrs.last()->moveBy(dx, dy); + return; + } + } +} + +void YACSPrs_LabelLink::moveByNode(YACSPrs_ElementaryNode* theNode) +{ + if ( mySlaveNode && mySlaveNode == theNode ) { + QPoint p = getConnectionMasterPoint(); + myPrs.first()->move(p.x(), p.y()); + return; + } +} + +void YACSPrs_LabelLink::moveByNode(YACSPrs_ElementaryNode* theNode, int dx, int dy) +{ + if ( mySlaveNode && mySlaveNode == theNode ) { + myPrs.first()->moveBy(dx, dy); + return; + } +} + +QString YACSPrs_LabelLink::getToolTipText() const { + QString aText; + if (myOutputPort) + aText = /* + QString(" : ") + */ + myOutputPort->getName() + QString(" => ") + + QString("node \"") + + mySlaveNode->getEngine()->getName() + QString("\""); + return aText; +} + +void YACSPrs_LabelLink::remove() { + // TO DO : remove slave node from the switch case or loop body + + YACSPrs_Link::remove(); + myCanvas->update(); +} + +QPoint YACSPrs_LabelLink::getConnectionMasterPoint() +{ + if ( mySlaveNode ) + return mySlaveNode->getConnectionMasterPoint() + QPoint(0,HOOKPOINTMASTER_SIZE/4-LINKPOINT_SIZE/2); + else + return QPoint(); +} + +void YACSPrs_LabelLink::createPrs() +{ + // create without internal points now + if ( mySlaveNode ) addPoint(getConnectionMasterPoint(),0); + + int i = 1; + for ( std::list::iterator it = myPoints.begin(); it != myPoints.end(); it++, i++ ) + addPoint(*it, i); + + if ( myOutputPort ) addPoint(getConnectionPoint(myOutputPort),myPoints.size()+1); + + // the first and last points is smaller than an internal points + if ( QCanvasEllipse* aFP = dynamic_cast( getFirstPoint() ) ) aFP->setSize(LINKPOINT_SIZE/2, LINKPOINT_SIZE/2); + if ( QCanvasEllipse* aLP = dynamic_cast( getLastPoint() ) ) aLP->setSize(LINKPOINT_SIZE/2, LINKPOINT_SIZE/2); + + YACSPrs_Link::createPrs(); +} + +void YACSPrs_LabelLink::setHilighted(bool state) +{ + QColor aHilightColor = myMgr->colorValue("YACSGui", "hook_hilight_color", HOOK_HILIGHT_COLOR); + + YACSPrs_LabelPort* anOutputPort = getOutputPort(); + if (anOutputPort) { + QColor aHookColor = state?aHilightColor:anOutputPort->storeColor(); + YACSPrs_Hook* aHook = anOutputPort->GetHook(); + if (aHook) aHook->setColor(aHookColor); + } + + if (getSlaveNode()) { + QColor aMasterColor = state?aHilightColor:anOutputPort->storeColor(); + getSlaveNode()->setMasterPointColor(aMasterColor); + } + + YACSPrs_Link::setHilighted(state); +} + +void YACSPrs_LabelLink::setSelected(bool state) +{ + QColor aSelectColor = myMgr->colorValue("YACSGui", "hook_select_color", HOOK_SELECT_COLOR); + + YACSPrs_LabelPort* anOutputPort = getOutputPort(); + if (anOutputPort) { + QColor aHookColor = state?aSelectColor:anOutputPort->storeColor(); + YACSPrs_Hook* aHook = anOutputPort->GetHook(); + if (aHook) { + aHook->setSelected(state); + aHook->setColor(aHookColor); + } + } + + if (getSlaveNode()) { + if ( getSlaveNode()->getMasterPoint() ) getSlaveNode()->getMasterPoint()->setSelected(state); + QColor aMasterColor = state?aSelectColor:anOutputPort->storeColor(); + getSlaveNode()->setMasterPointColor(aMasterColor); + } + + YACSPrs_Link::setSelected(state); +} + +/*! + * =========================== YACSPrs_Point =========================== + !*/ + +YACSPrs_Point::YACSPrs_Point(QCanvas* theCanvas, + YACSPrs_Link* theLink, + const int& theIndex): + QCanvasEllipse(theCanvas), + myLink(theLink), myIndex(theIndex), + myInEdge(0), myOutEdge(0), myMoving(false), mySelected(false) +{ + setSize(LINKPOINT_SIZE, LINKPOINT_SIZE); + setZ(-1); +} + +bool YACSPrs_Point::isMoveable() +{ + if ( !myInEdge || !myOutEdge ) return false; + return true; +} + +void YACSPrs_Point::hilight(const QPoint& theMousePos, const bool toHilight) +{ + if ( mySelected ) return; + + // process the hilighting depending on mouse position + if (YACSPrs_Link* aLink = getLink()) + aLink->setHilighted(toHilight); +} + +void YACSPrs_Point::select(const QPoint& theMousePos, const bool toSelect) +{ + // unhilight the item under the mouse cursor + hilight(theMousePos, false); + + if (YACSPrs_Link* aLink = getLink()) + aLink->setSelected(toSelect); +} + +void YACSPrs_Point::showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos) +{ + if ( !getLink() ) return; + + getLink()->setSelectedObject(this, theMousePos); + + // construct popup menu + QPopupMenu* aPopup = new QPopupMenu(theParent); + aPopup->insertItem(QObject::tr("MSG_DEL_POINT"), getLink(), SLOT(removePoint())); + + CAM_Application* anApp = ( CAM_Application* )(SUIT_Session::session()->activeApplication()); + if ( !anApp->activeModule() ) return; + if ( anApp->activeModule()->moduleName().compare( anApp->moduleTitle( "YACSGui" ) ) !=0 ) return; + + if (theEvent->button() == RightButton) aPopup->exec(theEvent->globalPos()); +} + +QString YACSPrs_Point::getToolTipText(const QPoint& theMousePos, QRect& theRect) const +{ + if (YACSPrs_Link* aLink = getLink()) + { + theRect = QRect(theMousePos.x(), theMousePos.y(), MARGIN, MARGIN); + return aLink->getToolTipText(); + } +} + +bool YACSPrs_Point::arePartsOfOtherItem(QxGraph_ActiveItem* theSecondItem) +{ + if ( YACSPrs_Point* aPoint = dynamic_cast( theSecondItem ) ) { + if ( getLink() == aPoint->getLink() ) return true; + } + else if ( YACSPrs_Edge* anEdge = dynamic_cast( theSecondItem ) ) { + if ( getLink() == anEdge->getLink() ) return true; + } + return false; +} + +int YACSPrs_Point::rtti() const +{ + return 0;//YACSPrs_Canvas::Rtti_Point; +} + +void YACSPrs_Point::setInEdge(YACSPrs_Edge* theEdge) +{ + myInEdge = theEdge; + theEdge->setFromPoint(this); +} + +void YACSPrs_Point::setOutEdge(YACSPrs_Edge* theEdge) +{ + myOutEdge = theEdge; + theEdge->setToPoint(this); +} + +void YACSPrs_Point::moveBy(double dx, double dy) +{ + QCanvasEllipse::moveBy(dx, dy); + + if ( getLink() ) getLink()->updatePoints(this); + + if (myInEdge) myInEdge->setFromPoint(this); + if (myOutEdge) myOutEdge->setToPoint(this); + + if ( getLink() && !getLink()->isEmptyPrs() ) { + //resize canvas view if mouse is outside + int w = (int)(x()+dx) + width() + GRAPH_MARGIN; + int h = (int)(y()+dy) + height() + GRAPH_MARGIN; + if (canvas()->width() > w) w = canvas()->width(); + if (canvas()->height() > h) h = canvas()->height(); + if (canvas()->width() < w || canvas()->height() < h) canvas()->resize(w, h); + } + //if (myIndex > 0 && isMoving()) { + // myLink->getEngine()->ChangeCoord(myIndex, (int)x(), (int)y()); + //} +} + +void YACSPrs_Point::setColor(const QColor& theColor) +{ + setBrush(theColor); +} + +/*! + * =========================== YACSPrs_Edge =========================== + !*/ + +YACSPrs_Edge::YACSPrs_Edge(QCanvas* theCanvas, + YACSPrs_Link* theLink): + QCanvasLine(theCanvas), + myLink(theLink), + myStartPoint(0), myEndPoint(0), mySelected(false) +{ + setZ(-2); +} + +bool YACSPrs_Edge::isMoveable() +{ + if ( myStartPoint && ( myLink->isFirst(myStartPoint) || myLink->isLast(myStartPoint) ) + || + myEndPoint && ( myLink->isFirst(myEndPoint) || myLink->isLast(myEndPoint) ) ) + return false; + return true; +} + +void YACSPrs_Edge::hilight(const QPoint& theMousePos, const bool toHilight) +{ + if ( mySelected ) return; + + // process the hilighting depending on mouse position + if (YACSPrs_Link* aLink = getLink()) + aLink->setHilighted(toHilight); +} + +void YACSPrs_Edge::select(const QPoint& theMousePos, const bool toSelect) +{ + // unhilight the item under the mouse cursor + hilight(theMousePos, false); + + if (YACSPrs_Link* aLink = getLink()) + aLink->setSelected(toSelect); +} + +void YACSPrs_Edge::showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos) +{ + if ( !getLink() ) return; + + getLink()->setSelectedObject(this, theMousePos); + + // construct popup menu + QPopupMenu* aPopup = new QPopupMenu(theParent); + aPopup->insertItem(QObject::tr("MSG_ADD_POINT"), getLink(), SLOT(addPoint())); + + CAM_Application* anApp = ( CAM_Application* )(SUIT_Session::session()->activeApplication()); + if ( !anApp->activeModule() ) return; + if ( anApp->activeModule()->moduleName().compare( anApp->moduleTitle( "YACSGui" ) ) !=0 ) return; + + if (theEvent->button() == RightButton) aPopup->exec(theEvent->globalPos()); +} + +QString YACSPrs_Edge::getToolTipText(const QPoint& theMousePos, QRect& theRect) const +{ + if (YACSPrs_Link* aLink = getLink()) + { + theRect = boundingRect(); + return aLink->getToolTipText(); + } +} + +bool YACSPrs_Edge::arePartsOfOtherItem(QxGraph_ActiveItem* theSecondItem) +{ + if ( YACSPrs_Point* aPoint = dynamic_cast( theSecondItem ) ) { + if ( getLink() == aPoint->getLink() ) return true; + } + else if ( YACSPrs_Edge* anEdge = dynamic_cast( theSecondItem ) ) { + if ( getLink() == anEdge->getLink() ) return true; + } + return false; +} + +int YACSPrs_Edge::rtti() const +{ + return 0;//YACSPrs_Canvas::Rtti_Edge; +} + +void YACSPrs_Edge::setFromPoint(YACSPrs_Point* thePoint) +{ + myStartPoint = thePoint; + setPoints((int)(thePoint->x()), (int)(thePoint->y()), endPoint().x(), endPoint().y()); +} + +void YACSPrs_Edge::setToPoint(YACSPrs_Point* thePoint) +{ + myEndPoint = thePoint; + setPoints(startPoint().x(), startPoint().y(), (int)(thePoint->x()), (int)(thePoint->y())); +} + +void YACSPrs_Edge::setColor(const QColor& theColor) +{ + setPen(QPen(theColor, LINKEDGE_WIDTH)); +} + +void YACSPrs_Edge::moveBy(double dx, double dy) +{ + // for moving segment of link + if (myStartPoint && myEndPoint) { + myStartPoint->setMoving(true); + myStartPoint->moveBy(dx, dy); + + myEndPoint->setMoving(true); + myEndPoint->moveBy(dx,dy); + } +} diff --git a/src/prs/YACSPrs_Link.h b/src/prs/YACSPrs_Link.h new file mode 100644 index 000000000..0a8d8f006 --- /dev/null +++ b/src/prs/YACSPrs_Link.h @@ -0,0 +1,261 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSPRS_LINK_H +#define YACSPRS_LINK_H + +#include "QxGraph_ActiveItem.h" + +#include +#include + +class SUIT_ResourceMgr; + +class YACSPrs_Port; +class YACSPrs_InOutPort; +class YACSPrs_LabelPort; +class YACSPrs_ElementaryNode; + +class YACSPrs_Link : public QObject { + Q_OBJECT + + public: + YACSPrs_Link( SUIT_ResourceMgr*, QCanvas* theCanvas); + virtual ~YACSPrs_Link(); + + void show(); + void merge(); + + std::list getPoints() const { return myPoints; } + void setPoints(std::list thePoints) { myPoints = thePoints; } + void updatePoints(QCanvasItem* thePointItem); + + bool isEmptyPrs() const { return myPrs.isEmpty(); } + + virtual void setHilighted(bool state); + virtual void setSelected(bool state); + void setColor(const QColor& theColor); + + virtual void moveByPort(YACSPrs_Port* thePort, bool theMoveInternalLinkPoints=false, QRect theArea=QRect()) {} + virtual void moveByPort(YACSPrs_Port* thePort, int dx, int dy) {} + + void setSelectedObject(QCanvasItem* theItem, const QPoint& thePoint); + + virtual QString getToolTipText() const; + + bool isFirst(QCanvasEllipse* thePoint); + bool isLast(QCanvasEllipse* thePoint); + + QCanvasItem* getFirstPoint() const { return myPrs.first(); } + QCanvasItem* getLastPoint() const { return myPrs.last(); } + + void setMyZ(double z); + double getMyZ(); + + void setZ(double z); + double z(); + + public slots: + virtual void remove(); + + void addPoint(); + void removePoint(); + + QPoint getConnectionPoint(YACSPrs_Port* thePort); + + protected: + void addPoint(const QPoint& thePoint, const int& theIndex = -1); + virtual void createPrs(); + + SUIT_ResourceMgr* myMgr; + QCanvas* myCanvas; + QCanvasItemList myPrs; + + std::list myPoints; //for read/write from/to xml + + QColor myColor; + + private: + bool myHilighted; + bool mySelected; + + QCanvasItem* mySelectedItem; + QPoint mySelectedPoint; + + double myZ; +}; + +class YACSPrs_PortLink : public YACSPrs_Link { + + public: + YACSPrs_PortLink(SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACSPrs_InOutPort* theInputPort, YACSPrs_InOutPort* theOutputPort); + virtual ~YACSPrs_PortLink(); + + virtual void moveByPort(YACSPrs_Port* thePort, bool theMoveInternalLinkPoints=false, QRect theArea=QRect()); + virtual void moveByPort(YACSPrs_Port* thePort, int dx, int dy); + + virtual QString getToolTipText() const; + + virtual void remove(); + + YACSPrs_InOutPort* getInputPort() const { return myInputPort; } + void setInputPort(YACSPrs_InOutPort* thePort) { myInputPort = thePort; } + + YACSPrs_InOutPort* getOutputPort() const { return myOutputPort; } + void setOutputPort(YACSPrs_InOutPort* thePort) { myOutputPort = thePort; } + + virtual void setHilighted(bool state); + virtual void setSelected(bool state); + + protected: + virtual void createPrs(); + + private: + YACSPrs_InOutPort* myInputPort; + YACSPrs_InOutPort* myOutputPort; +}; + +class YACSPrs_LabelLink : public YACSPrs_Link { + + public: + YACSPrs_LabelLink(SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACSPrs_LabelPort* theOutputPort, YACSPrs_ElementaryNode* theSlaveNode); + virtual ~YACSPrs_LabelLink(); + + virtual void moveByPort(YACSPrs_Port* thePort, bool theMoveInternalLinkPoints=false, QRect theArea=QRect()); + virtual void moveByPort(YACSPrs_Port* thePort, int dx, int dy); + + void moveByNode(YACSPrs_ElementaryNode* theNode); + void moveByNode(YACSPrs_ElementaryNode* theNode, int dx, int dy); + + virtual QString getToolTipText() const; + + virtual void remove(); + + YACSPrs_LabelPort* getOutputPort() const { return myOutputPort; } + void setOutputPort(YACSPrs_LabelPort* thePort) { myOutputPort = thePort; } + + YACSPrs_ElementaryNode* getSlaveNode() const { return mySlaveNode; } + void setSlaveNode(YACSPrs_ElementaryNode* theNode) { mySlaveNode = theNode; } + + virtual void setHilighted(bool state); + virtual void setSelected(bool state); + + QPoint getConnectionMasterPoint(); + + protected: + virtual void createPrs(); + + private: + YACSPrs_LabelPort* myOutputPort; + YACSPrs_ElementaryNode* mySlaveNode; +}; + +class YACSPrs_Edge; + +/*! Link point presentation. + */ +class YACSPrs_Point : public QxGraph_ActiveItem, public QCanvasEllipse { + + public: + YACSPrs_Point(QCanvas* theCanvas, YACSPrs_Link* theLink, const int& theIndex = -1); + ~YACSPrs_Point() {} + + /* reimplement functions from QxGraph_ActiveItem */ + virtual bool isMoveable(); + virtual void beforeMoving() {} + virtual void afterMoving() {} + virtual void hilight(const QPoint& theMousePos, const bool toHilight = true); + virtual void select(const QPoint& theMousePos, const bool toSelect = true); + virtual void showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos = QPoint()); + virtual QString getToolTipText(const QPoint& theMousePos, QRect& theRect) const; + virtual bool arePartsOfOtherItem(QxGraph_ActiveItem* theSecondItem); + + YACSPrs_Link* getLink() const { return myLink; } + void setIndex(int theIndex) { myIndex = theIndex; } + int getIndex() const { return myIndex; } + + void setInEdge(YACSPrs_Edge* theEdge); + void setOutEdge(YACSPrs_Edge* theEdge); + + void moveBy(double dx, double dy); + void setColor(const QColor& theColor); + + void setMoving(bool b) { myMoving = b; } + bool isMoving() const { return myMoving; } + + void setSelected(bool b) { mySelected = b; } + + virtual int rtti() const; + + private: + YACSPrs_Link* myLink; + int myIndex; + bool myMoving; + + YACSPrs_Edge* myInEdge; + YACSPrs_Edge* myOutEdge; + + bool mySelected; +}; + +/*! Link edge presentation. + */ +class YACSPrs_Edge : public QxGraph_ActiveItem, public QCanvasLine { + + public: + YACSPrs_Edge(QCanvas* theCanvas, YACSPrs_Link* theLink); + ~YACSPrs_Edge() {} + + /* reimplement functions from QxGraph_ActiveItem */ + virtual bool isMoveable(); + virtual void beforeMoving() {} + virtual void afterMoving() {} + virtual void hilight(const QPoint& theMousePos, const bool toHilight = true); + virtual void select(const QPoint& theMousePos, const bool toSelect = true); + virtual void showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos = QPoint()); + virtual QString getToolTipText(const QPoint& theMousePos, QRect& theRect) const; + virtual bool arePartsOfOtherItem(QxGraph_ActiveItem* theSecondItem); + + YACSPrs_Link* getLink() const { return myLink; } + + void setFromPoint(YACSPrs_Point* thePoint); + void setToPoint(YACSPrs_Point* thePoint); + + void moveBy(double dx, double dy); + void setColor(const QColor& theColor); + + void setMoving(bool b) { myMoving = b; } + bool isMoving() const { return myMoving; } + + void setSelected(bool b) { mySelected = b; } + + virtual int rtti() const; + + private: + bool myMoving; + YACSPrs_Link* myLink; + + // for moving segment of link + YACSPrs_Point* myStartPoint; + YACSPrs_Point* myEndPoint; + + bool mySelected; +}; + +#endif diff --git a/src/prs/YACSPrs_LoopNode.cxx b/src/prs/YACSPrs_LoopNode.cxx new file mode 100644 index 000000000..bfc8387be --- /dev/null +++ b/src/prs/YACSPrs_LoopNode.cxx @@ -0,0 +1,359 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 +// + +#include "YACSPrs_LoopNode.h" +#include "YACSPrs_Def.h" + +#include "SUIT_ResourceMgr.h" + +#include + +#include +#include + +using namespace YACS::ENGINE; + +/*! + Constructor +*/ +YACSPrs_LoopNode::YACSPrs_LoopNode( SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACS::ENGINE::Node* theNode, const bool& thePortUpdate ): + YACSPrs_InlineNode(theMgr, theCanvas, theNode, false) +{ + setNodeColor(LOOPNODE_COLOR); + setNodeSubColor(LOOPNODE_SUBCOLOR); + setBracketColor(LOOPNODE_BRACKETCOLOR); + + setStoreColor(nodeColor()); + setStoreSubColor(nodeSubColor()); + myStoreBracketColor = myBracketColor; + + myTopPixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_TITLE_RARROW" )); + myBottomPixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_TITLE_LARROW" )); + + if ( thePortUpdate ) { + //updatePorts(); // will be called in moveBy(...) function + moveBy(3*TITLE_HEIGHT/2, 3*TITLE_HEIGHT/2); + } +} + +/*! + Destructor +*/ +YACSPrs_LoopNode::~YACSPrs_LoopNode() +{ +} + +void YACSPrs_LoopNode::select(const QPoint& theMousePos, const bool toSelect) +{ + if ( toSelect ) + { + // unhilight the item under the mouse cursor + hilight(theMousePos, false); + + bool isOnPort = false; + if (getBodyRect().contains(theMousePos, true) || getGateRect().contains(theMousePos, true)) + { + // process ports + QPtrList aPortList = getPortList(); + for (YACSPrs_Port* aPort = aPortList.first(); aPort; aPort = aPortList.next()) { + if (aPort->getPortRect().contains(theMousePos, true)) { + isOnPort = true; + if ( aPort != mySelectedPort ) + { + if ( mySelectedPort ) + { + mySelectedPort->setSelected(false); + mySelectedPort->setColor(mySelectedPort->storeColor(), false, true, true); + } + else + { + setSelected(false); + setBracketColor( myStoreBracketColor ); + setNodeSubColor( storeSubColor(), true ); + } + aPort->setSelected(true); + aPort->setColor(aPort->Color().dark(130), false, true, true); + mySelectedPort = aPort; + } + break; + } + } + } + + if ( !isOnPort ) + { + if ( mySelectedPort ) + { + mySelectedPort->setSelected(false); + mySelectedPort = 0; + } + + if ( storeSubColor().dark(130) != nodeSubColor() ) + { + myStoreBracketColor = myBracketColor; + setStoreSubColor( nodeSubColor() ); + + setSelected(true); + setBracketColor( bracketColor().dark(130) ); + setNodeSubColor( nodeSubColor().dark(130), true ); + } + } + } + else + { + if ( mySelectedPort ) { + mySelectedPort->setSelected(false); + mySelectedPort->setColor(mySelectedPort->storeColor(), false, true, true); + mySelectedPort = 0; + } + else { + setSelected(false); + setBracketColor( myStoreBracketColor ); + setNodeSubColor( storeSubColor(), true ); + } + } +} + +int YACSPrs_LoopNode::rtti() const +{ + return 0;//YACSPrs_Canvas::Rtti_LoopNode; +} + +QPointArray YACSPrs_LoopNode::constructAreaPoints(int theW, int theH) const +{ + int h = theH-1; + + int aCorner = 3*TITLE_HEIGHT/2; + + QPointArray aPnts(8); + QPoint p((int)x(), (int)y()); + p = p + QPoint(-NODEBOUNDARY_MARGIN,0); + aPnts[0] = p; + aPnts[1] = p + QPoint(aCorner, -aCorner) + QPoint(NODEBOUNDARY_MARGIN,-NODEBOUNDARY_MARGIN); + aPnts[2] = aPnts[1] + QPoint(theW, 0) + QPoint(NODEBOUNDARY_MARGIN,0); + aPnts[3] = p + QPoint(theW, 0) + QPoint(NODEBOUNDARY_MARGIN,0); + aPnts[4] = aPnts[3] + QPoint(0, h) + QPoint(0,-NODEBOUNDARY_MARGIN/2); + aPnts[5] = aPnts[4] + QPoint(-aCorner, aCorner) + QPoint(-NODEBOUNDARY_MARGIN,NODEBOUNDARY_MARGIN); + aPnts[6] = aPnts[5] + QPoint(-theW, 0) + QPoint(-NODEBOUNDARY_MARGIN,0); + aPnts[7] = p + QPoint(0, h) + QPoint(0,-NODEBOUNDARY_MARGIN/2); + return aPnts; +} + +void YACSPrs_LoopNode::setBracketColor(const QColor& theColor, bool theUpdate) +{ + myBracketColor = theColor; + if ( canvas() && theUpdate ) + { + canvas()->setChanged(boundingRect()); + canvas()->update(); + } +} + +void YACSPrs_LoopNode::updatePorts() +{ + bool aDisp = isVisible(); + if (aDisp) hide(); + + // ForLoop and WhileLoop nodes have only 1 input port. + // ForLoop : its name is 'nsteps' , + // its type is 'int', + // its value is a number of iterations. + // WhileLoop : its name is 'condition' , + // its type is 'bool', + // its value is a while condition, iteration process breaks when condition switch to false. + // ForLoop and WhileLoop nodes have no output ports, but in presentation we want to display a 'label' port with + // name 'Body'. This 'label' port connects with help of 'case' link to 'Master' hook + // of the node, which is set as an internal node of the loop. + + bool withCreate = false; + if ( myPortList.isEmpty() ) withCreate = true; + + QRect r = getBodyRect(); + int aPRectWidth = (int)(r.width()/2) - 2*PORT_MARGIN; + if ( aPRectWidth < PORT_WIDTH ) aPRectWidth = PORT_WIDTH; + + int ix = r.x() + PORT_MARGIN + 1; + int iy = r.y() + PORT_MARGIN;// + 1; + int ox = ix + aPRectWidth + 2*PORT_MARGIN; + int oy = r.y() + PORT_MARGIN;// + 1; + + ForLoop* aFLoop = dynamic_cast( myEngine ); + WhileLoop* aWLoop = 0; + + if ( withCreate ) + { // create (and update) + // 'nsteps'/'condition' input port (name, type (and value) of the port will set in YACSPrs_InOutPort from port engine) + YACSPrs_InOutPort* anInPort = 0; + + if ( aFLoop ) + anInPort = new YACSPrs_InOutPort(myMgr,canvas(),aFLoop->edGetNbOfTimesInputPort(),this); + else + { + aWLoop = dynamic_cast( myEngine ); + if ( aWLoop ) + anInPort = new YACSPrs_InOutPort(myMgr,canvas(),aWLoop->edGetConditionPort(),this); + } + + if ( anInPort ) + { + anInPort->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT)); + anInPort->setColor(nodeSubColor()); + anInPort->setStoreColor(nodeSubColor()); + myPortList.append(anInPort); + } + + if ( aFLoop || aWLoop ) + { + // get a set of internal loop nodes (in fact in ForLoop and WhileLoop we have only one internal node) + std::set aNodes = aFLoop ? aFLoop->edGetDirectDescendants() : aWLoop->edGetDirectDescendants(); + std::set::iterator aNodesIter = aNodes.begin(); + for (; aNodesIter != aNodes.end(); aNodesIter++) + { // output label port + YACSPrs_LabelPort* anOutPort = new YACSPrs_LabelPort(myMgr,canvas(),*aNodesIter,this); + anOutPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT)); + anOutPort->setColor(nodeSubColor().dark(140)); + anOutPort->setStoreColor(nodeSubColor().dark(140)); + myPortList.append(anOutPort); + myPortHeight += PORT_HEIGHT; + } + } + } + else + { // only update + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + YACSPrs_InOutPort* anInPort = dynamic_cast( aPort ); + if ( anInPort ) + { + if ( !anInPort->isGate() && anInPort->isInput() ) + { // input data (i.e. not Gate) ports + anInPort->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT), !isSelfMoving(), myArea); + iy += PORT_HEIGHT+PORT_SPACE; + } + } + else + { // not YACSPrs_InOutPort => it is YACSPrs_LabelPort => we not need to dynamic cast + aPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT), !isSelfMoving(), myArea); + oy += PORT_HEIGHT+PORT_SPACE; + } + } + } + + // can update gates only after body height will be defined + updateGates(withCreate); + + if (aDisp) show(); +} + +int YACSPrs_LoopNode::maxWidth() const +{ + return YACSPrs_ElementaryNode::maxWidth() - 4*HOOKPOINT_SIZE + ( ( 4*HOOKPOINT_SIZE > 3*TITLE_HEIGHT ) ? 4*HOOKPOINT_SIZE-3*TITLE_HEIGHT : 0 ); +} + +void YACSPrs_LoopNode::drawPort(QPainter& thePainter) +{ + QRect r = getBodyRect(); + r.setHeight(r.height()+1); + + thePainter.drawRect(r); + int x0 = (r.left() + r.right())/2; + thePainter.drawLine(x0, r.top(), x0, r.bottom()); + + int aRRectWidth = (x0 - r.left() - 2*PORT_MARGIN - 2*PORT_SPACE)/3; + int aRRectWidthLabel = x0 - r.left() - 2*PORT_MARGIN; + QRect aTRect = getTitleRect(); + int aXRnd = aTRect.width()*myXRnd/aRRectWidth; + int aXRndLabel = aTRect.width()*myXRnd/aRRectWidthLabel; + int aYRnd = aTRect.height()*myYRnd/PORT_HEIGHT; + + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + YACSPrs_InOutPort* anInPort = dynamic_cast( aPort ); + YACSPrs_LabelPort* anOutPort = dynamic_cast( aPort ); + if ( anInPort && !anInPort->isGate() ) + aPort->draw(thePainter, aXRnd, aYRnd); + if ( anOutPort ) + aPort->draw(thePainter, aXRndLabel, aYRnd); + } +} + +void YACSPrs_LoopNode::drawFrame(QPainter& thePainter) +{ + QRect aRect = getRect(); + QRect aTRect = getTitleRect(); + + thePainter.drawRect(aRect); + + QBrush savedB = thePainter.brush(); + thePainter.setBrush(bracketColor()); + + int aCorner = 3*TITLE_HEIGHT/2; + QPoint aP1(aRect.x(), aRect.y()); + QPoint aP2(aRect.x()+aCorner, aRect.y()-aCorner); + QPoint aP3(aRect.right()+aCorner,aRect.y()-aCorner); + QPoint aP4(aRect.right(), aRect.y()); + QPoint aP5(aRect.x(), aRect.bottom()); + QPoint aP6(aRect.x()-aCorner, aRect.bottom()+aCorner); + QPoint aP7(aRect.right()-aCorner,aRect.bottom()+aCorner); + QPoint aP8(aRect.right(), aRect.bottom()); + QPointArray aPAUp(4); + aPAUp.putPoints(0, 4, aP1.x(),aP1.y(), aP2.x(),aP2.y(), aP3.x(),aP3.y(), aP4.x(),aP4.y()); + thePainter.drawPolygon( aPAUp ); + QPointArray aPADown(4); + aPADown.putPoints(0, 4, aP5.x(),aP5.y(), aP6.x(),aP6.y(), aP7.x(),aP7.y(), aP8.x(),aP8.y()); + thePainter.drawPolygon( aPADown ); + + thePainter.setBrush(savedB); + + // draw top pixmap + QRect aTPRect(aRect.x()+aRect.width()/2-aCorner/3, aRect.y()-aCorner/2-aCorner/3, + 2*aCorner/3, 2*aCorner/3); + thePainter.drawPixmap(aTPRect,myTopPixmap); + + // draw bottom pixmap + QRect aBPRect(aRect.x()+aRect.width()/2-aCorner/3, aRect.bottom()+aCorner/2-aCorner/3, + 2*aCorner/3, 2*aCorner/3); + thePainter.drawPixmap(aBPRect,myBottomPixmap); + + // draw bounding nodes' polygon if node is currently selected + if ( isSelected() ) drawBoundary(thePainter,5); +} + +QPoint YACSPrs_LoopNode::getConnectionMasterPoint() +{ + QRect aRect = getRect(); + return QPoint(aRect.left()+aRect.width()/2, aRect.bottom()+3*TITLE_HEIGHT/2); +} + +bool YACSPrs_LoopNode::checkArea(double dx, double dy) +{ + // for constraint nodes' moving inside the Bloc--> + if ( !myIsInBloc ) return true; + + QRect aRect = boundingRect(); + aRect.moveBy((int)dx, (int)dy); + aRect.setRect(aRect.x() - ( ( 2*HOOKPOINT_SIZE > 3*TITLE_HEIGHT/2 ) ? 2*HOOKPOINT_SIZE-3*TITLE_HEIGHT/2 : 0 ) + NODEBOUNDARY_MARGIN, + aRect.y(), maxWidth(), maxHeight()); + if ( myArea.isValid() && myArea.contains(aRect) ) + return true; + return false; + // <-- +} diff --git a/src/prs/YACSPrs_LoopNode.h b/src/prs/YACSPrs_LoopNode.h new file mode 100644 index 000000000..7a260c7e5 --- /dev/null +++ b/src/prs/YACSPrs_LoopNode.h @@ -0,0 +1,63 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSPRS_LOOPNODE_H +#define YACSPRS_LOOPNODE_H + +#include "YACSPrs_InlineNode.h" + +class YACSPrs_LoopNode : public YACSPrs_InlineNode { + public: + YACSPrs_LoopNode( SUIT_ResourceMgr*, QCanvas*, YACS::ENGINE::Node*, const bool& thePortUpdate=true ); + virtual ~YACSPrs_LoopNode(); + + /* reimplement functions from QxGraph_ActiveItem */ + virtual void select(const QPoint& theMousePos, const bool toSelect = true); + virtual void showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos = QPoint()) {} + + virtual int rtti() const; + + virtual QPointArray constructAreaPoints(int theW, int theH) const; + + virtual void setBracketColor(const QColor& theColor, bool theUpdate=false); + virtual QColor bracketColor() const { return myBracketColor; } + + virtual void updatePorts(); + virtual int getCorner() const { return 0; } + + virtual int maxWidth() const; + + virtual QPoint getConnectionMasterPoint(); + + // for constraint nodes' moving inside the Bloc--> + virtual bool checkArea(double dx, double dy); + // <-- + + protected: + virtual void drawPort(QPainter& thePainter); + virtual void drawFrame(QPainter& thePainter); + + private: + QPixmap myTopPixmap; + QPixmap myBottomPixmap; + + QColor myBracketColor; + QColor myStoreBracketColor; +}; + +#endif diff --git a/src/prs/YACSPrs_ServiceNode.cxx b/src/prs/YACSPrs_ServiceNode.cxx new file mode 100644 index 000000000..9f90904e1 --- /dev/null +++ b/src/prs/YACSPrs_ServiceNode.cxx @@ -0,0 +1,264 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 +// + +#include "YACSPrs_ServiceNode.h" +#include "YACSPrs_Def.h" + +#include + +#include + +#include +#include + +using namespace YACS::ENGINE; + +void drawText1(QPainter& thePainter, const QString& theText, + const QRect& theRect, int theHAlign = Qt::AlignAuto) +{ + int flags = theHAlign | Qt::AlignVCenter; + QRect r(theRect.x() + TEXT_MARGIN, theRect.y(), + theRect.width() - 2*TEXT_MARGIN, theRect.height()); + + QWMatrix aMat = thePainter.worldMatrix(); + if (aMat.m11() != 1.0) { + // for scaled picture only + QRect r1 = aMat.mapRect(r); + QFont saved = thePainter.font(); + QFont f(saved); + if (f.pointSize() == -1) { + f.setPixelSize((int)(f.pixelSize()*aMat.m11())); + } + else { + f.setPointSize((int)(f.pointSize()*aMat.m11())); + } + thePainter.save(); + QWMatrix m; + thePainter.setWorldMatrix(m); + thePainter.setFont(f); + thePainter.drawText(r1, flags, theText); + thePainter.setFont(saved); + thePainter.restore(); + } + else { + thePainter.drawText(r, flags, theText); + } +} + + +/*! + Constructor +*/ +YACSPrs_ServiceNode::YACSPrs_ServiceNode(SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACS::ENGINE::Node* theNode): + YACSPrs_ElementaryNode(theMgr, theCanvas, theNode) +{ + myServiceHeight = TITLE_HEIGHT; + myComponentHeight = TITLE_HEIGHT; + myMachineHeight = TITLE_HEIGHT; + + setNodeColor(SERVICENODE_COLOR); + setNodeSubColor(SERVICENODE_SUBCOLOR); + + setStoreColor(nodeColor()); + setStoreSubColor(nodeSubColor()); + + //updatePorts(); // will be called in moveBy(...) function + moveBy(2*HOOKPOINT_SIZE,0); + + update(); +} + +/*! + Destructor +*/ +YACSPrs_ServiceNode::~YACSPrs_ServiceNode() +{ +} + +int YACSPrs_ServiceNode::rtti() const +{ + return 0;//YACSPrs_Canvas::Rtti_ServiceNode; +} + +int YACSPrs_ServiceNode::getInfoHeight() const +{ + return getTitleHeight() + NODE_SPACE + + getServiceHeight() + NODE_SPACE + + getComponentHeight() + NODE_SPACE + + getMachineHeight() + NODE_SPACE + + getStatusHeight(); +} + +int YACSPrs_ServiceNode::getServiceHeight() const +{ + return myServiceHeight; +} + +int YACSPrs_ServiceNode::getComponentHeight() const +{ + return myComponentHeight; +} + +int YACSPrs_ServiceNode::getMachineHeight() const +{ + return myMachineHeight; +} + +QRect YACSPrs_ServiceNode::getServiceRect() const +{ + QRect aPMRect = getPixmapRect(true,true); + int width = getTitleRect().width() - aPMRect.width() - NODE_MARGIN; + return QRect(aPMRect.right() + NODE_MARGIN, getTitleRect().bottom()+NODE_SPACE, + width, getServiceHeight()); +} + +QRect YACSPrs_ServiceNode::getComponentRect() const +{ + QRect aPMRect = getPixmapRect(true,true); + int width = getTitleRect().width() - aPMRect.width() - NODE_MARGIN; + return QRect(aPMRect.right() + NODE_MARGIN, getServiceRect().bottom()+NODE_SPACE, + width, getComponentHeight()); +} + +QRect YACSPrs_ServiceNode::getMachineRect() const +{ + QRect aPMRect = getPixmapRect(true,true); + int width = getTitleRect().width() - aPMRect.width() - NODE_MARGIN; + return QRect(aPMRect.right() + NODE_MARGIN, getComponentRect().bottom()+NODE_SPACE, + width, getMachineHeight()); +} + +QRect YACSPrs_ServiceNode::getStatusRect() const +{ + QRect aPMRect = getPixmapRect(true,true); + int width = getTitleRect().width() - aPMRect.width() - NODE_MARGIN; + return QRect(aPMRect.right() + NODE_MARGIN, getMachineRect().bottom()+NODE_SPACE, + width, getStatusHeight()); +} + +QRect YACSPrs_ServiceNode::getWholeRect() const +{ + return QRect(getStatusRect().topLeft()+QPoint(getStatusRect().width()/3+3,3), + getStatusRect().bottomRight()-QPoint(3,3)); +} + +QRect YACSPrs_ServiceNode::getPercentRect() const +{ + int aPercentageW = (int)(getWholeRect().width()*( (getStoredPercentage() < 0) ? getPercentage() : getStoredPercentage() )/100.); + return QRect(getWholeRect().topLeft(), getWholeRect().bottomLeft()+QPoint(aPercentageW,0)); +} + +/*! + Update service, component, machine +*/ +void YACSPrs_ServiceNode::updateInfo() +{ + +} + +void YACSPrs_ServiceNode::drawTitleShape(QPainter& thePainter) +{ + // draw information: title, service, component, machine, status + int aXRnd = getTitleRect().width()*myXRnd/getServiceRect().width(); + int aYRnd = getTitleRect().height()*myYRnd/TITLE_HEIGHT; + + QPen savedP = thePainter.pen(); + thePainter.setPen(thePainter.brush().color().dark(140)); + + // title + thePainter.drawRoundRect(getTitleRect(),myXRnd,myYRnd); + // service + thePainter.drawRoundRect(getServiceRect(),aXRnd,aYRnd); + // component + thePainter.drawRoundRect(getComponentRect(),aXRnd,aYRnd); + // machine + thePainter.drawRoundRect(getMachineRect(),aXRnd,aYRnd); + //state and time + thePainter.drawRoundRect(getStatusRect(),aXRnd,aYRnd); + + // draw progress bar + thePainter.setPen(NoPen); + + QBrush savedB = thePainter.brush(); + + thePainter.setBrush(savedB.color().light(130)); + thePainter.drawRect(getWholeRect()); + + if ( getPercentRect().width() > 1 ) { + thePainter.setBrush(savedB.color().dark(160)); + thePainter.drawRect(getPercentRect()); + } + + thePainter.setBrush(savedB); + + // draw texts + thePainter.setPen(Qt::white); + + ServiceNode* aSEngine = dynamic_cast( myEngine ); + drawText1(thePainter, QString(myEngine->getName()), getTitleRect(), Qt::AlignLeft); + drawText1(thePainter, QString( "Service: ") + QString( aSEngine ? aSEngine->getMethod() : "..." ), getServiceRect(), Qt::AlignLeft); + drawText1(thePainter, QString( "Component: " ) + QString( aSEngine ? aSEngine->getComponent()->getName() : "..." ), getComponentRect(), Qt::AlignLeft); + drawText1(thePainter, QString("Machine: ..."), getMachineRect(), Qt::AlignLeft); + + int aMidX = getTitleRect().right()-getTitleRect().width()/2; + thePainter.drawLine(aMidX, getStatusRect().top()+2, aMidX, getStatusRect().bottom()-2); + + QRect aStateRect(getStatusRect().x(), getStatusRect().y(), aMidX-getStatusRect().left(), TITLE_HEIGHT); + QRect aTimeRect(aMidX, getStatusRect().y(), 2*getStatusRect().width()/3, TITLE_HEIGHT); + + drawText1(thePainter, myStatus, aStateRect, Qt::AlignLeft); + drawText1(thePainter, myTime, aTimeRect, Qt::AlignLeft); + drawText1(thePainter, QString::number(( (getStoredPercentage() < 0) ? getPercentage() : getStoredPercentage() ))+QString("%"), aTimeRect, Qt::AlignRight); // percentage + + thePainter.setPen(savedP); + + // draw pixmap + thePainter.setBrush(NoBrush); + + aXRnd = getTitleRect().width()*myXRnd/getPixmapRect(true,true).width(); + aYRnd = getTitleRect().height()*myYRnd/getPixmapRect(true,true).height(); + thePainter.drawRoundRect(getPixmapRect(true,true),aXRnd,aYRnd); + QRect aPRect = getPixmapRect(true,true); + aPRect.setX(aPRect.x()+PIXMAP_MARGIN+2); + aPRect.setY(aPRect.y()+PIXMAP_MARGIN); + aPRect.setWidth(aPRect.width()-2*PIXMAP_MARGIN); + aPRect.setHeight(aPRect.height()-2*PIXMAP_MARGIN); + thePainter.drawPixmap(aPRect,myStatePixmap); + + thePainter.setBrush(savedB); +} + +QString YACSPrs_ServiceNode::getToolTipText(const QPoint& theMousePos, QRect& theRect) const +{ + // Check if the tooltip for ports is needed + if (getBodyRect().contains(theMousePos, true) || getGateRect().contains(theMousePos, true)) + return YACSPrs_ElementaryNode::getToolTipText(theMousePos,theRect); + + // Return tooltip text for node + QString aText = QString(""); + aText += QString("Name: %1\n").arg(getEngine()->getName()); + aText += QString("Type: %1\n").arg("Service node"); + theRect = getTitleRect(); + theRect = theRect.unite(getServiceRect()); + theRect = theRect.unite(getComponentRect()); + theRect = theRect.unite(getMachineRect()); + theRect = theRect.unite(getStatusRect()); + theRect = theRect.unite(getPixmapRect()); + return aText; +} diff --git a/src/prs/YACSPrs_ServiceNode.h b/src/prs/YACSPrs_ServiceNode.h new file mode 100644 index 000000000..fe1556588 --- /dev/null +++ b/src/prs/YACSPrs_ServiceNode.h @@ -0,0 +1,61 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSPRS_SERVICENODE_H +#define YACSPRS_SERVICENODE_H + +#include "YACSPrs_ElementaryNode.h" + +class YACSPrs_ServiceNode : public YACSPrs_ElementaryNode { + public: + YACSPrs_ServiceNode( SUIT_ResourceMgr*, QCanvas*, YACS::ENGINE::Node* ); + virtual ~YACSPrs_ServiceNode(); + + /* reimplement functions from QxGraph_ActiveItem */ + virtual void showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos = QPoint()) {} + + virtual int rtti() const; + + virtual int getInfoHeight() const; + virtual int getServiceHeight() const; + virtual int getComponentHeight() const; + virtual int getMachineHeight() const; + + virtual QRect getServiceRect() const; + virtual QRect getComponentRect() const; + virtual QRect getMachineRect() const; + virtual QRect getStatusRect() const; + + virtual QRect getWholeRect() const; + virtual QRect getPercentRect() const; + + virtual void updateInfo(); // update service, component, machine + + virtual QString getToolTipText(const QPoint& theMousePos, QRect& theRect) const; + + protected: + virtual void drawTitleShape(QPainter& thePainter); + + private: + int myServiceHeight; + int myComponentHeight; + int myMachineHeight; + +}; + +#endif diff --git a/src/prs/YACSPrs_SwitchNode.cxx b/src/prs/YACSPrs_SwitchNode.cxx new file mode 100644 index 000000000..815edce9e --- /dev/null +++ b/src/prs/YACSPrs_SwitchNode.cxx @@ -0,0 +1,291 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 +// + +#include "YACSPrs_SwitchNode.h" +#include "YACSPrs_Def.h" + +#include "QxGraph_Canvas.h" +#include "QxGraph_Prs.h" + +#include "SUIT_ResourceMgr.h" + +#include + +#include + +using namespace YACS::ENGINE; + +/*! + Constructor +*/ +YACSPrs_SwitchNode::YACSPrs_SwitchNode( SUIT_ResourceMgr* theMgr, QCanvas* theCanvas, YACS::ENGINE::Node* theNode ): + YACSPrs_InlineNode(theMgr, theCanvas, theNode, false) +{ + setNodeColor(SWITCHNODE_COLOR); + setNodeSubColor(SWITCHNODE_SUBCOLOR); + + setStoreColor(nodeColor()); + setStoreSubColor(nodeSubColor()); + + myTitlePixmap = myMgr->loadPixmap( "YACSPrs", QObject::tr( "ICON_TITLE_RARROW" )); + + //updatePorts(); // will be called in moveBy(...) function + moveBy(2*HOOKPOINT_SIZE,2*TITLE_HEIGHT); +} + +/*! + Destructor +*/ +YACSPrs_SwitchNode::~YACSPrs_SwitchNode() +{ +} + +int YACSPrs_SwitchNode::rtti() const +{ + return 0;//YACSPrs_Canvas::Rtti_SwitchNode; +} + +QPointArray YACSPrs_SwitchNode::constructAreaPoints(int theW, int theH) const +{ + int aCorner = 2*TITLE_HEIGHT; + + QPointArray aPnts(5); + QPoint p((int)x(), (int)y()); + aPnts[0] = p + QPoint(-NODEBOUNDARY_MARGIN,0); + aPnts[1] = p + QPoint(theW/2, -aCorner) + QPoint(0,-NODEBOUNDARY_MARGIN); + aPnts[2] = p + QPoint(theW, 0) + QPoint(NODEBOUNDARY_MARGIN,0); + aPnts[3] = aPnts[2] + QPoint(0, theH) + QPoint(0,NODEBOUNDARY_MARGIN/2); + aPnts[4] = p + QPoint(0, theH) + QPoint(-NODEBOUNDARY_MARGIN,NODEBOUNDARY_MARGIN/2); + return aPnts; +} + +void YACSPrs_SwitchNode::updatePorts() +{ + bool aDisp = isVisible(); + if (aDisp) hide(); + + // Switch node has only 1 input port: its name is 'select', + // its type is 'int', + // its value is a number of active case (i.e. the case to execute) + // Switch node has no output ports, but in presentation we want to display a switch cases with + // its IDs (the number of cases and its IDs are set by user at creation process of switch node ) + // as a 'label' ports. Each 'label' port connects with help of 'case' link to 'Master' hook + // of the node, which is set to this case ID. + + bool withCreate = false; + if ( myPortList.isEmpty() ) withCreate = true; + + QRect r = getBodyRect(); + int aPRectWidth = (int)(r.width()/2) - 2*PORT_MARGIN; + if ( aPRectWidth < PORT_WIDTH ) aPRectWidth = PORT_WIDTH; + + int ix = r.x() + PORT_MARGIN + 1; + int iy = r.y() + PORT_MARGIN;// + 1; + int ox = ix + aPRectWidth + 2*PORT_MARGIN; + int oy = r.y() + PORT_MARGIN;// + 1; + + if ( withCreate ) + { // create (and update) + // 'select' input port (name, type (and value) of the port will set in YACSPrs_InOutPort from port engine) + Switch* aSEngine = dynamic_cast( myEngine ); + if ( aSEngine ) + { + YACSPrs_InOutPort* anInPort = new YACSPrs_InOutPort(myMgr,canvas(),aSEngine->edGetConditionPort(),this); + anInPort->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT)); + anInPort->setColor(nodeSubColor()); + anInPort->setStoreColor(nodeSubColor()); + myPortList.append(anInPort); + + // get a set of internal case nodes + std::set aNodes = aSEngine->edGetDirectDescendants(); + std::set::iterator aNodesIter = aNodes.begin(); + + // get default node + Node* aDefaultNode = aSEngine->getChildByShortName(Switch::DEFAULT_NODE_NAME); + + int aMinCaseId, aMaxCaseId; + aMinCaseId = aMaxCaseId = aSEngine->getRankOfNode(*aNodesIter); + // a list of case nodes ordered from minimum to maximum case id + std::list aCaseNodes; + for (; aNodesIter != aNodes.end(); aNodesIter++) + { + if ( *aNodesIter == aDefaultNode) continue; + + // less than min => push front + if ( aMinCaseId >= aSEngine->getRankOfNode(*aNodesIter) ) { + aCaseNodes.push_front(*aNodesIter); + aMinCaseId = aSEngine->getRankOfNode(*aNodesIter); + } + // in the middle + else if ( aMinCaseId < aSEngine->getRankOfNode(*aNodesIter) + && + aMaxCaseId > aSEngine->getRankOfNode(*aNodesIter) ) { + std::list::iterator aCaseNodesIter = aCaseNodes.begin(); + for (std::list::iterator anIt = aCaseNodesIter; + anIt++ != aCaseNodes.end(); + aCaseNodesIter++, anIt = aCaseNodesIter) { + if ( aSEngine->getRankOfNode(*aNodesIter) >= aSEngine->getRankOfNode(*aCaseNodesIter) + && + aSEngine->getRankOfNode(*aNodesIter) <= aSEngine->getRankOfNode(*anIt) ) { + aCaseNodes.insert(anIt,*aNodesIter); + break; + } + } + } + // more than max => push back + else if ( aMaxCaseId <= aSEngine->getRankOfNode(*aNodesIter) ) { + aCaseNodes.push_back(*aNodesIter); + aMaxCaseId = aSEngine->getRankOfNode(*aNodesIter); + } + } + aCaseNodes.push_back(aDefaultNode); + + int heightIncr = 0; + std::list::iterator aCaseNodesIter = aCaseNodes.begin(); + for (; aCaseNodesIter != aCaseNodes.end(); aCaseNodesIter++) + { // (in fact we have to get from user number of switch cases) + // output label ports + YACSPrs_LabelPort* anOutPort = new YACSPrs_LabelPort(myMgr,canvas(),*aCaseNodesIter,this, + true,aSEngine->getRankOfNode(*aCaseNodesIter)); + anOutPort->setPortRect(QRect(ox, oy+heightIncr, aPRectWidth, PORT_HEIGHT)); + anOutPort->setColor(nodeSubColor().dark(140)); + anOutPort->setStoreColor(nodeSubColor().dark(140)); + if ( *aCaseNodesIter == aDefaultNode) anOutPort->setName(Switch::DEFAULT_NODE_NAME); + myPortList.append(anOutPort); + heightIncr += PORT_HEIGHT+PORT_SPACE; + } + + myPortHeight += aNodes.size()*PORT_HEIGHT + (aNodes.size()-1)*PORT_SPACE; + } + } + else + { // only update + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + YACSPrs_InOutPort* anIOPort = dynamic_cast( aPort ); + if ( anIOPort ) + { + if ( !anIOPort->isGate() && anIOPort->isInput() ) + { // input data (i.e. not Gate) ports + anIOPort->setPortRect(QRect(ix, iy, aPRectWidth, PORT_HEIGHT), !isSelfMoving(), myArea); + iy += PORT_HEIGHT+PORT_SPACE; + } + } + else + { // not YACSPrs_InOutPort => it is YACSPrs_LabelPort (output!) => we not need to dynamic cast + aPort->setPortRect(QRect(ox, oy, aPRectWidth, PORT_HEIGHT), !isSelfMoving(), myArea); + oy += PORT_HEIGHT+PORT_SPACE; + } + } + } + + // can update gates only after body height will be defined + updateGates(withCreate); + + if (aDisp) show(); +} + +void YACSPrs_SwitchNode::drawPort(QPainter& thePainter) +{ + QRect r = getBodyRect(); + r.setHeight(r.height()+1); + + thePainter.drawRect(r); + int x0 = (r.left() + r.right())/2; + thePainter.drawLine(x0, r.top(), x0, r.bottom()); + + int aRRectWidth = (x0 - r.left() - 2*PORT_MARGIN - 2*PORT_SPACE)/3; + int aRRectWidthLabel = x0 - r.left() - 2*PORT_MARGIN; + QRect aTRect = getTitleRect(); + int aXRnd = aTRect.width()*myXRnd/aRRectWidth; + int aXRndLabel = aTRect.width()*myXRnd/aRRectWidthLabel; + int aYRnd = aTRect.height()*myYRnd/PORT_HEIGHT; + + YACSPrs_Port* aPort; + for (aPort = myPortList.first(); aPort; aPort = myPortList.next()) + { + YACSPrs_InOutPort* anInPort = dynamic_cast( aPort ); + YACSPrs_LabelPort* anOutPort = dynamic_cast( aPort ); + if ( anInPort && !anInPort->isGate() ) + aPort->draw(thePainter, aXRnd, aYRnd); + if ( anOutPort ) + aPort->draw(thePainter, aXRndLabel, aYRnd); + } +} + +void YACSPrs_SwitchNode::drawFrame(QPainter& thePainter) +{ + QRect aRect = getRect(); + QRect aTRect = getTitleRect(); + int aXRnd = aTRect.width()*myXRnd/aRect.width(); + int aYRnd = aTRect.height()*myYRnd/aRect.height(); + + QPen savedP = thePainter.pen(); + thePainter.setPen(NoPen); + + // calculate width and height for acrs + int w = 4*(aXRnd*aRect.width()/100)/3; + int h = 4*(aYRnd*aRect.height()/100)/3; + + // draw chords without pen + thePainter.drawChord( aRect.x(),aRect.y(), w,h, 90*16, 90*16 ); + thePainter.drawChord( aRect.right()-w+1,aRect.y(), w,h, 0*16, 90*16 ); + thePainter.drawChord( aRect.right()-w+1,aRect.bottom()-h+1, w,h, 270*16, 90*16 ); + thePainter.drawChord( aRect.x(),aRect.bottom()-h+1, w,h, 180*16, 90*16 ); + + //thePainter.drawRoundRect(aRect,aXRnd,aYRnd); + int aCorner = 2*TITLE_HEIGHT; + QPoint aP1(aRect.x()+(w-1)/2,aRect.y()); + QPoint aP2(aRect.x()+aRect.width()/2,aRect.y()-aCorner); + QPoint aP3(aRect.right()-(w-1)/2,aRect.y()); + QPoint aP4(aRect.right(),aRect.y()+h/2-1); + QPoint aP5(aRect.right(),aRect.bottom()-h/2+1); + QPoint aP6(aRect.right()-(w-1)/2,aRect.bottom()); + QPoint aP7(aRect.x()+(w-1)/2,aRect.bottom()); + QPoint aP8(aRect.x(),aRect.bottom()-h/2+1); + QPoint aP9(aRect.x(),aRect.y()+h/2-1); + QPointArray aPA(9); + aPA.putPoints(0, 9, + aP1.x(),aP1.y(), aP2.x(),aP2.y(), aP3.x(),aP3.y(), aP4.x(),aP4.y(), + aP5.x(),aP5.y(), aP6.x(),aP6.y(), aP7.x(),aP7.y(), aP8.x(),aP8.y(), aP9.x(),aP9.y()); + thePainter.drawPolygon( aPA ); + thePainter.setPen(savedP); + + // draw arcs + thePainter.drawArc( aRect.x(),aRect.y(), w,h, 90*16, 90*16 ); + thePainter.drawArc( aRect.right()-w+1,aRect.y(), w,h, 0*16, 90*16 ); + thePainter.drawArc( aRect.right()-w+1,aRect.bottom()-h+1, w,h, 270*16, 90*16 ); + thePainter.drawArc( aRect.x(),aRect.bottom()-h+1, w,h, 180*16, 90*16 ); + + // draw line segments + thePainter.drawLine(aP1,aP2); + thePainter.drawLine(aP2,aP3); + thePainter.drawLine(aP4,aP5); + thePainter.drawLine(aP6,aP7); + thePainter.drawLine(aP8,aP9); + + // draw title pixmap + QRect aTPRect(aRect.x()+aRect.width()/2-aCorner/3, aRect.y()-(aCorner-NODE_MARGIN)/2-aCorner/3, + 2*aCorner/3, 2*aCorner/3); + thePainter.drawPixmap(aTPRect,myTitlePixmap); + + // draw bounding nodes' polygon if node is currently selected + if ( isSelected() ) drawBoundary(thePainter,3); +} diff --git a/src/prs/YACSPrs_SwitchNode.h b/src/prs/YACSPrs_SwitchNode.h new file mode 100644 index 000000000..654842b0a --- /dev/null +++ b/src/prs/YACSPrs_SwitchNode.h @@ -0,0 +1,47 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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 YACSPRS_SWITCHNODE_H +#define YACSPRS_SWITCHNODE_H + +#include "YACSPrs_InlineNode.h" + +class YACSPrs_SwitchNode : public YACSPrs_InlineNode { + public: + YACSPrs_SwitchNode( SUIT_ResourceMgr*, QCanvas*, YACS::ENGINE::Node*); + virtual ~YACSPrs_SwitchNode(); + + /* reimplement functions from QxGraph_ActiveItem */ + virtual void showPopup(QWidget* theParent, QMouseEvent* theEvent, const QPoint& theMousePos = QPoint()) {} + + virtual int rtti() const; + + virtual QPointArray constructAreaPoints(int theW, int theH) const; + + virtual void updatePorts(); + virtual int getCorner() const { return 0; } + + protected: + virtual void drawPort(QPainter& thePainter); + virtual void drawFrame(QPainter& thePainter); + + private: + QPixmap myTitlePixmap; +}; + +#endif diff --git a/src/prs/resources/YACSPrs_images.po b/src/prs/resources/YACSPrs_images.po new file mode 100755 index 000000000..6136825f0 --- /dev/null +++ b/src/prs/resources/YACSPrs_images.po @@ -0,0 +1,27 @@ + + +#### Icons for YACS module presentations #### + +msgid "ICON_STATUS_NO" +msgstr "no_status.png" + +msgid "ICON_DISABLED" +msgstr "disabled.png" + +msgid "ICON_STATUS_RUNNING" +msgstr "running.png" + +msgid "ICON_STATUS_WAITING" +msgstr "waiting.png" + +msgid "ICON_STATUS_DONE" +msgstr "done.png" + +msgid "ICON_STATUS_ABORTED" +msgstr "aborted1.png" + +msgid "ICON_TITLE_RARROW" +msgstr "right_arrows.png" + +msgid "ICON_TITLE_LARROW" +msgstr "left_arrows.png" diff --git a/src/prs/resources/YACSPrs_msg_en.po b/src/prs/resources/YACSPrs_msg_en.po new file mode 100755 index 000000000..7cd3c7949 --- /dev/null +++ b/src/prs/resources/YACSPrs_msg_en.po @@ -0,0 +1,23 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2007-03-12 16:44+0300\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + + +#### YACSPrs popups #### + +msgid "MSG_ADD_POINT" +msgstr "Add Point" + +msgid "MSG_DEL_POINT" +msgstr "Delete Point" diff --git a/src/prs/resources/aborted1.png b/src/prs/resources/aborted1.png new file mode 100755 index 0000000000000000000000000000000000000000..8275b929c1242a790519e81f332dd25c40fab0ac GIT binary patch literal 5765 zcmW+)c{o)47r%FQ8S6xaY-8t@W<-U08S0fb#u{2EDYDFr(O4Q;Dvb)GR4SFF zdMPo?DA_9tl`Tt)%5E^sZ~Fal?s@L_dCs}#e$M_)r+Vy=!>VHe0FZNYb@7(+?SBY^ zl0HwEj-*JLOqA=sXaJB^{zD*e^*Ua9h&b%@j}rh?Tu4~)x+r}o2Dy6w0{~|?004sp z080`n{{{dtBmnqM1AxD|0H79`>)#~RuCn6h;Kd`WXs=IIjD)jMzYL6a;=yi1Tmq9Y!LJW@7(;e^IKY`2&JLF)>a`61~@k{ zSbvt6&!a4}a1=?H5(NNV?lbP<)Re-nz5CQQ6d2Jmg~lt^``3qxmcFY9%xDbp^0JC1 zk)9+86(NPBWm^oqO2uv-fTyNkyvQV^5txRP1k(NaUwwk8`LWhM%B&GXq^2mj{Vx`V zA%?0W+^<}?7xDR*eKZ~#9mTJ0PHdU_@kWn5Xy!)}FNyPq%?v&QjuHiK2t{P3zN&yT zpu|xZmY2q41)jV@GC7G9RZ&jzZEdlrU0G-st)(iwrNnE)r{njlbV!Z=$p}Y>7R(%b zcgGR~RtX1RWf79d@h_*;zShuPnM{s340TBRQU+yAi4=urhF*1bB}IuPkIsDidBBvH z_^Q~D{hbL{q;x}En04Gz-m!PL&8HYG5RE5}U&$NR>2j7ZwGlCn%`$jAD#VsbWHMlA zv|yr$9P^vLq>CEWzP&9IDV4|K^^>#I|BxB+S;Id{K|=iiOy${^wkkWKmBU||80m^3iWvOFqEpK6d+oe*&ra(4j^y_ zd(gc7vbbJ85C}(kaB}}DopeLDa6xkgMHVbwMSU3eudx(|Ookic=|5Xx4<0n^n=n(9 zNaoL<&IH1SNFbc8<6GbWZ`CBGfq_ZHaa5qZ^w{e!yZ=kQF6EpL5~0hS_)M7b?l5`Y zzKdGEw=}RA5~i|Z3D_pbZW)6naq4^ZQ&>XOd^_0Y?atq#CaZT- zpSlNONTc0l=UnH57@|9jeJ(%U@O5WnvJ}0(HJ#q~cnlv4X`0f8T%(d3VSX4^rLu$f zXT`uNELFr4^!jl4dbt-VymdC(&vTEbe(f3qoLD=fW zZ*GOh8`Trm;Mach7LcE)j*h6)`ueDdEPYnLl|xk(VZiS>J1h;{4V5a62L%N&F8qwr zMYh?N>PWKt>;7-wc2AAoGvI%FyZViJz!Ln}Coknm@U-q=U3}`*Q6?zBLU@nRs007P z)QOs5hHRM!KPZY)Q)~9gT(VkPV)S8f29g}_Rtn^#d->s~E

wZP}>LM=4Tn1c5;A zD2=(h4M0H#|0KUW!3)0#S64jh3JP{zAcL^9T-@vzhf;Gi_7Zsg8Z6|4KgCuolI<|8 z=Yb8$ID@v)J$--lWGpSK?9o_VZ6#$7DUfJ&@Xu3Pxe;_C5@qQfvCiHIlp<$1{&N0~ zC)!Gbc@fjKX2zcsBi|m3m5tF*_U2{x@TFD9J>u4p4~3h-&?s64_#ToJn|S%o)W!Tz z6)eq8+*QYTGL_b0Aw=*F38G&D_J*%QGF-K8^*ZDqFOGjYm#RRhgCD5X;2UDr$H7<B%5@3^R9~$0zK?_n~Jn1r` z87HCVtHTxTh{|Mmm9YW!VS*UrVZuM%CPTf3HCz!>8tb#YAvb`?Feum(kaG3J;+HI) ztyu#vEW5I^fmfUK%XOMy->1F9ml1oC5>swpvgBi8;brN5tKztPuu^wKAIJJWUj@cPn=tO(e^G&$GSwc)KDRd)$Ga!%3kW)(vslQ2Wa1` z#lvvH-TxvR&i%BM{){TB`LCS8F78!URu>dyJxn82v_kW5lMg5AbQ{Fdp%6u>w_0xSE_~o?WvGL1dIxKq)f) zO=vlJ=6DQ(fwwBkX=@YW9?2O;bAp5M>zRhGsI;c)8bT~{A4l$S8@%5Ucyh8HzPoWR z5!G|_5d)l2^sOF1g%&LG`M_lpUO$?9i*ix)Jo}!s9Z|rLf-_wnqw!%xFPyZ%3SFDJ z8&O&Y$;b;t#q;nJnxwHsWeeKwFO4BhGlu*j|oWChxJ|)w@Vnkc#~V=?GaTx+tH-r`OIcHT$i^EiUGjlw(mT& zQ*`g#6I>1Jp`w}?z0TEHexQ^Uq7*n)FHu}A-?p6^UH%U9d}v`^&AD8k#bQVQQ1I?% zsc2If>q!CR+=vvHwT>!LFC)vSJM22q^60*Dr!OeDWIjPH9F6^PcGm6~XM{PQpOq7OW{+R8xi@ zZL&1S&Z_;ECmpPN*F-e^+RVGZU;Ys-yS4kH!d~;*IQqGUw>%|hd4y_NPY^Y4HniOO z*bXI$cuYx9Y<|nFlPRBoz~V7{Ceuggg?bW}3G-?cyBdzb}(x0SB;x{~pot)%!jTGiRnhy0JS4%`D3+(#)IBt6GpGdugKS zRRz*i6W*5_$HyOh$HCm07#*#$Dq*klBSlof0{PY53ll0)|cjTxeqdz*MA@pvi+RT~?fHas_mikiqN z*mk|);|Xh4X||!DQ12G>A@Vn{{WF>EI_OMMm@#kjJ1+m|GAHI8e>w8=$CmQAGpeM^ zx)B?w?m(P6;`qSF#`3tm8+`{pk^RAw{`+$acmy+0DA>O%`Ix3FNaFZe2kr@)Df zaug&>(qN*mOFjjQW`3%(Fh!aqQW@T_-oJ_8)+po)7Sw7VGSa>9T=#>FfVnK@Wj93G zMEmod&{59z?BErZUPk;XcevBP3pP&XZ~u&q;!mBpPfA#uyEc4>RH7m1*wjEY(nk5b zYB!WoU77kOBe>(4?c=Cd`T~{NZdSzncR|OMFJ6{;)7fhBipIMve}S4kF-VUUM$Nwu zrLmN5d^79fMh>nqcfTBP-pvQ~*4;y^N(ZW7ATIT?oHYi3VUF<2&9{2DUitljQ4t5j zlbDcr^Gj&rktsr5*hUn>_bCWoZ|o$R=w{tmoJ!vZxnrMFI~{{!7st`Db3cC<)emvk z=6_grL4NEkoh0z0!}=!7%zdVL0&3`$K0D+H7QZDyjJ)8s@wQ|tc;^6NIOb zlPIw5-Urn<0Ye`b6`)rh$AK1St5p!yJmE=i0O9KQ(XXRVU>WfIf`as6GyM`B&gMvr zG?scRm8A1hg~e-_EXDOa_q_A<;SUNR5BUgR;<65$oo;nxzw*qo5Q~@42M6%q&RL3{ z{S#=Hm}K8g@}O;60*|F92dzmeZNuPyxpM{Iai|xu>qIt?usRNwUtd9Yx=R=%WQrl` zak=K*?6oDWw{Jrc;|`(Y5@=UiGFRzOH3`vE9Gb9U8aFXv_A-ar@6;w(vK~=BOXB3= zPq!}fbJx@a|C!Yj9(UK`?d)O+@|u1^+L4@>M57RhGweUar6I?I4Bg~h%jij{@NZik z7ZyG%vmMc)mItd(r4<{*%Q+{Ey09J2n8B)qL2St+2jXx<`iBN<6PwEuJARky$p@>GMWdTmU2r0%hjd(EHnCL-^4zIRLt4QKyI*w`eOEyB|+D^`wAs za`#hnO@|kF-&vAH?>?t{<3_eN$w!#=^qfE(_rdYO8e!Ce_%tfW*^_;#`ZaXSF=@!+ z=O8(Sd2s<0d``%DdQTqe8;sU>(|n zWXrOFF4V*K6J~}%&AakDc=wK?+I06tSsykt39*YlVc7eoyhFR$QPFetFn5b>YCy-O z=g`c_XV5QG0))Xm6o=B?&GQ?Li+aZTV z57^-z`cR?VTkz>+x#R8?5AF4~nQfFTcxc&9rak)sq?Gp3fL%V`-cq_5%68TW;)ADAHudZ#ua zxtHsbR^@gDNcSpf_S}$|-O$7C5nwqs@*W$Bp~193lr^9DQ{8n11p6rB8W$6?3;x_ zbtzYc$HA8kTF+PBj$a|6@6F^Oe)O#SuSNL7IA^MxoOwfI-Pe76`LtXh5Ai6WSLY6U zJe@nA@}jC^`&(fBs?QO#i4bi#PslAi{QR^G|5l9&h)Jecy*YbVBI$o@Cp*5Y?(Bi! zeS|qR_u}sfK%?lhQ_+WE4ekWu%g$?8O3&q9ocnytm9_&_W6D?eV{S-3Dyzx&9aInc z=flR%4PMdd-pFW0FYfH6=EK|$(WaMn$`MKfuLQ-Z(7d_R!VRg%G_1iAZ zw=;~;cqH-Nejfl8(EChobXc-dQB#EKCb zt=<((F-2JQ588L;XXe1uH{SHKwo6pmaUV9_=mK;YH~zS}srvA05L^X(zJmepAvTwh z+>}%!C-J}Aibsu#^X_l!Ki#llM+68+pCt9?Q!?{HW^c1y zj=6_Z&QK9wuR1DtG$r}~bV8<;Ow~iD z=_N0rU|(F|1bM6As>EwY={ja=n33Z%$q!uietAU-r|X-%{Z~e{B93)?b1Ys_HX~>6 z7TwOjb*tWd=n%g;g@TtMZxC>}k|OC==N3AdCPVy<5(T&>8)^7Vu*F6UO5ta7!%pdG}1LQ z>l_*y0**S;Lu1#(_JY-wMS`8ZeS_f_{jhf^#AcV7PyWWINxW_Nr#3U>$)6!O`_VK+ zyNy`78LK{yF)cUrI5~mon;$O%ThOhdr+52>BG%)UiT;08FW^)qHvc z-pA~4Rx%VD)qL#^nYyFmqlH6=no`r*A3kvQO@5_8|%N=yD9K^+>P literal 0 HcmV?d00001 diff --git a/src/prs/resources/aborted2.png b/src/prs/resources/aborted2.png new file mode 100755 index 0000000000000000000000000000000000000000..c1d7ef124e8b8fe8a4d92300a0fb84cd41f803c3 GIT binary patch literal 5585 zcmW+)c{r5a8-8auV=%JKpiCP|GGj|*7Q5ohhl+?9BwM9K2s493$Wm!Y8AaL3q`hQ@ zkzFXVWS1pL)(~cX^Zouf?{mG|bFOpFecjJ}KS>V%SWBUlQ2+o)+1gk*ilfzkLjo?o zUf4exFAm6H8`ls3kd*sxfPkD_toR}H4Aq_r0MBkjt^a#de2@3GakK}3$lU7k-o*C>q zI$2!!^55J$cXp}J3{(^0-V%sUB1CN)DaOa>l1M1eu|sweMd^O-tnb=Qjc-3XINur( z@fba=)?PQk9-FJx!JA(+j`|Jr2f!H0KBG>_xeLLBB?RK8BEi901o=F*`g@3nX0Vpp zJbBpMGi{$Dglmh2oUDhG4W&d8#owKEGrPF7nWnj;W=_UO8spsqLdk2|qo&?ODp(L9 zM2$>0AppfZ)%9J=kyOI&CttBzu54~kY&l=ON8A!^!Q1QAUz&xbV^KQCKaRNB|p z7R_cIQ6mxhg&S)?dc@Ymwe%D%wYq zLMpiW^@0BX4$S89bpw8Wd5oX9;K!u-_%neTMS>_}>MZ}FZ*$J#r2iHp+@nWm_p&l1 z<~#`G^Ft;2hoWPN-qxtmhj{=&1Mfc&&Li%uVV)p>sFi7caxIxdzw&RKf?=iC<@eS zKN(BQl5enp78dH1L$BoWkWP_^vTYqzNZlZdA#Z1K2NX{ht#01ElabNUKs|PQbXpk( zQ8`@^6@}KwBi)W#8<%XjaNpqTSI5l${&XvqXY9o3$iad4=r$e$5o*1S0vR`HIL}dq zYo8~Xe~b|yZ`DbpX_sAI*c3*vn5O2RS$KG#Hnr>WtHP9&XBqL(u2zKMckKR3hDf5X zPZ%dp@XYT;Wu2r5Hzmc0v&fM=Y`_o-MQwj3exA@%+q$*n5f-Bjor$d!3GZ$9IGV0>|iy`CL0DP5%A2k{}rMQ)SF-ckHZ}Fz>o2~+i5VHwzCzHW2QSko z2NOr+JHK$jN?BK{c63>BZ_F^5zz$yy>UgNYv2_RS#EATpcc@PIHP%ZE*U(tXXK=T} zD}LnaaK8kGQUFC)rh6!q^#IR zU50uu8l?l`E$eb}0#q6s^X03iU|MCs<~9A}5V?Bnk?Lye<7q*P6>FMT3G%s+EbSAd zD4_6`mW`~W)(Mh#qZR(wb84g*65n05L$yar6~8)ux0I~30=7>{C}-|WD!(T*UlJUW zF+iB4awX5HWx8o*Yni;5Y~F{zjlfVihOgsZ-b0(W$!q8eV2T3K_Mo7Lm+{KR({Po> zxRhGfccB;kVaeKxOp?qaYS@E9%>n@S_G&EC79w?7OrTTyKw*4w9y@((sG2kdif39u z;MV^ghh!C#?t6DUas0L) zjrf+Ws5_$N$=!l4ua95{qm9A0L~VG!cPmFTBlWW}ki9bcD<Qhf7(G-aqz}`VnTV$P zat$nr@xFy$x8oB>)1!sI;h8Z~zry45mAq;636Qsqwt&xXs%ge+&DL|u`&#DKyUB3B zj{<&O6QYhF%p;3%M!i1Ro}N`)Pwy(R?uEOE>1o=Y z)>ZwG-aO}q8O@n2m(k6wbg!SA?DphLe#C9$cIzf0vvp@k?oGj)pTdGw^!h{+?Qv1) z=ULfifdwM8dZd4PXUKUi!J|{z{F9RZYOx%_4PWrVi-U>@t(1uLZ6Shv@GH%G;a8Hw z5_SiEz`3}HAjF*zy$45Hkr;{*Bmu@wr3}~S-9>v=o$|(v+=Rdr6a+t4O0jHLHgnII zPIzT%5|z!m+oiyMCj@z)!j?@gzfb1N!?VNImX`MmO1smlkIm!_F>r%b9@5fS(zas> zI(adA8-GDath6B#esErb*0Sk6Jdp`aj$U1gANf*G=9fv@8Kj6tetj;_qj#;7X{dy$ z$?>eyg!U$;A;5|xlf2$U2I>iZ4`J*Xtk(DEhlDJrx=vaqYI$ zNVK?~;0Qq}>75JX>jnu*=l=m9>glY!diKah*Hua!(?4!fW|v>@IL^mn{NHcj`ZGjL ztsZJcd;J;o??GYw3#yRPMieU`cwS-Vj?$trz^3byIt78i0zu+X%*CXUnUD5-rby<~{_}$* zXjX`5*!72+!v;e0;|9$B)%NAbRpuwZrSPNbThMoC;u^0Q)hhvAeQS?5?{vUxjI;#* z9gU(@!;$Qxp7-@~KfKt&u4E9SHW!kqZUc8&adCI(qLHiUS6M&M6^?bo3kk?6ZADt< z?W|5Fd`ge2Av81nGcn+uFo5tSy1%)Uo^Nz!tGQX{u7q!w_v==Q=CGw4;k26Jl>+vn}@|g@r)T>W28r*rIE<6=VtGdK#;v z@*#>R?Xvsnneh1;Ex}586#4>P5_?NN2q&$2@8jH0B_Cr;cNaC6tywJZ8)?>HRm~wD z13oc8M&EflOK<-YMsGMW@F{qva|c{e(F%U0bRV}$tNQ?R>za~sH0S%~m>8@ycQ2!m z7?rrBd?oXM8u^5;=RCQj35Ly>p&e%9w;H$PDx95=qir6rp~}t1Kc_tS#sn?P1XR5% z*=l~cUo{xW#{Q*NY&^5%--6db!Q82MHqURC3;qMZn@X0S323EwXbFq!bkL&&k%-D#P#c7U3IX;t`tYD2 znYKtva5Cg2wI`7v&WpVqf8DdmQMkz;1*@IL6J}R z`h<$0S!swlUVEAISj05tgUfDHU<4HtJ%TSYLdoS=T!o^IT2Y^HMTXc3EW{TTq2un~ zkmN?!Gz8E0=>}hlHO}SajDPDM8fGFCTF8t|P!^Jrk+6*t29gZlZv_vN_QUZdh$_wk zRwomTa30(I3oFjAih;a(8ACw@`f{T2o17rnXk7ChMml`2L|hlayu?3!t^bf6+J1bv z@r^PQ2s-&qiitpZR&o1=sh_jrzj2ab)oeDkh9u-N6=s?b-NYS*DbhEf^b5wRey76N!3n zJY)V7`J+pLpgYxe?BtJ|9NVgV-KX!pA=c`NQCkX%L8?j`Q;(%(6=+iK>Qkp()k6*P zkT*h3uAq-k5;DGrc%7r~I%M}k-!W}to!*f0qXbKF8h;RzZrx7W*RA2Y91;?dxHaTw zX^iKCIsUYUT_u=HhaCjs@cX8=D2YU_GQ-TzZv~avSh;VGdwJJcExVdezjO2=Pc9p1 zU>`r|deY_8G~Hb~cjiS?NcJQPf9!}z0QcP+|id9dQ3v-Rcn z>W)D?rZ79B{N{%k1qQoBIQ+qN@?piR9l;mUja>$PEKUt4Ci}+E<1!}JXo4J3 zqRX*mwa{9XE#c|T%Tq#~_LQ27Vl@yi9n?%k)WTRU5}i-YPiC^tzH+p5bNpOvf(J;i zBvs0MnH>%HftLI6>P{3`!CuJZZ1RB817rD|1TOY5L)E znmYyDjS+MIB9SnkzI6J9i2mjEf8=>u`H#vaYOALzXl$aqwAAnF>Fhd&11aJ7LlJiS zOSu+Uio-Qs>bz$U-$?&hH44@qw5uVPVG{(`Ol|RHmeAv;ua#a6h2;k!kjR7&I-WUI zf9J<^{Vsv0+sJ-$K@Fu1l+hs&I1$(Qq#>vWsuDzOy{sv0t!wG$8j%`XA)`dMCSH@$3F8v-bfm1n@p70L?|Qqw_MCL7qy0=laj&OMFY5jkaV173 zLGBhp{3B(i_fnhhcca@wx&1*w^9HlC`nYJ1=;giUiz9+vpg zvB09dA+dY7$mdslI`QI|)$jaEeo4>u{_L~ZzPhxiA=nVR{&T!5m%}7e6(x%n7Id)^ zsJ(g=!vK7nH=}yA`>1%Uy?T<5^R9HYp-VkZv&Ak^o+NAQm=f)z5u z&+DiWR}q$Vu%mqk_~7FW%Hr<>;cb=QID6v{8tBScdq9AoVF_x*rJtg?mq6!L_*P|Sd3!xSJ2q91mF{C@2BW^fY zZ2HfRrK#zu#;jsq*g+zyhY>W&+1%*)9roY^wVq=uncy_~HLBan6bk|eKo$+Jf7~c3 z@i>>0<9r!kMDLbyb&ghk!a_EU1^yvLg)cVUJ)n@g zjWz+|)R4U(t7cKWlaY&$k#I0kOy@OIT-H>3{@2 z3gm<%8rJQxEQAFm*_#GWi)RJoP=91KtO=wN?1UOLhr1KExshMVh z+>GQe!p_IazG5M&Ku~ZE3qxn>``st6FD221t`2u#-lpU-`Wi0h9%Z%t+wUQz^Y1RF zsmm5<;Q5?S^@x&lkaS0>@MLKUAl50{X+K{*Xz$2SzwzVXB?D4M40Q7>QJJUI*S50x~K06m2Adbbp%<%z^Ms zE(|UALOFz~u6?d(j8=HyZJdfWgOv5XdHKatYWlpm8Q9r2$k`7D zW~Cl`PRYUp=VM<1B+F@i9z+7~4idmafueNTgc~!}R?D>1?N+F*as7g5h`m7`r+7-~ zMOQ2MWtx)l%wF`z4Zn<93hZ@M>^o5Zd$_!D z%)``bp?T>iI%`hJpOBhuwz6S;Q6`GFMf}Hb(lK^i6(@E2-^@!HPUxWUF)hev()NN5 z{qGX72UY7tN&OQXZthxIVegzAp6N0tpUKO3go}B2FgBxxxt6S720Bv5;6hOqe?9$d z^AwJhvz5<*vp2=xVlUhxHbB1bbFlO05QcH~uc|elLk< zO8hdUO79AQqW-$b5UmS1?~wzhohSLJqhjj`0ZKBmev<##JrTEG0b9#|ES{RtV*dyD C?j|n) literal 0 HcmV?d00001 diff --git a/src/prs/resources/aborted3.png b/src/prs/resources/aborted3.png new file mode 100755 index 0000000000000000000000000000000000000000..97f99905281bb4fbbc2af5aaa67a09f0bca7d435 GIT binary patch literal 5573 zcmW+)dpwiv8-KRP4z{t$Y38(2QciR34eeo0MJ!1u*$7L#iMOJ}Gh*DUp~H)g zN{mU4S-mQqFeJ(wQMAnV+xz?Dey-2`JfHi1?(hA*uJ7l%u47DpZ#5hR2LOQDMjwwr zrSt)F^;ud}x zJwmo9UwW&U9*U4jfB*b_>vP}2gmr{mr)re0WhcA7H330_^8UI}JpZp|8k zWT>3S*k?(s%?ddh5P)OL|rZWs6b7K&5`xd@!GBv&Ch&DB4Udc(((jpnt-Cd+| z*DSSJd$R-Zm|OL+Q>VDxbLY6+Y*Z^6WokAIeSr=SK8gCJkcgTul+m5`%9orqIj;_J z0Pajg97-Jmw$NGk6QV$Ly8$&n8-weJf`~SaDJ{a8UpAoVpX&s|-@Dvga5yby7k~n= zFf#knB`){O87}t(J~K3Q`K+KHd^tC+X13Sn1DiF#=@c@N7MJL5;KXYCpUj5@kDc1;$zGOx-F0yP&W3y7`^SF}dhFCO;AdX_~XTCVHW-)p78p}6=;`UL=?YWc>PJ|*^jKq})2!Cp?JcrMX6(XZ zJv^wSb9}Q8fQX`8bcbdi0v2DnNS)y4FcO{RR$Zw2QiiNy4M(#QFMxgyYX}5QXi`lp zUfj>vGORr8E97{eO#0knYDzmXfE(Dhv`8SFwX&goc!cWoq7pM*d~fb>`vQG&tHyco z0?B3<+!(|3yR1`emQNn~-Q6Otglf+s3%GOoujR|N|3e?vWEWFgCtGp`$<&@Q$@L-O{Y%TZJs*?&Clmu&NsU|8;&t&CfDjiN5335$^TNs=Th)FAn1kIC>(4 zWv;^AcLy7d##0aAa=EGJCFXa3^D7OmY*kY_Xi=p4uiy2w^u=-PpD!{4F;!wzC7Bte z9)$g;{xQP-g5LQ{EW{jm`d(0}P$HtLw535ks=fPHR#IT#irLeUxmgO>O)^T1L%dbp zv`PRWbcBk)K(gHbau4)x$xk{rr_O<-91p`lfa|#rp z$dp+j+<;OeTXFsnWfoOpk^dctMQ%>t=B7$!9z;f)$LT)&^#Rz+atG02C-KmGTNg1b zfqZwWD24GT~qDqQOk2&Znxlkpy)63`?F&Gq~ zijDaqf&=kQ&zIjbH|3NgHmxb!0)92N&#o;;;Y_qN{az~FZi`T+R3_JTPhq4=|D0!B z@k{f2X*u~$jo!-?sEr;yOhw%a6yb#@=0CcMH>58e&LL`%3=9f`z_q!O-aLiy_Df6t z+~>Zn4z$Zi=ZbbQf7F;0F2hx)vEkZg2FO*ltfZ|dev_iay+w=mSuSf(iSw*O;3I;W zLfGrQAat^C@Co6jFu!8<{evJivI8sB6l*_6x2HkeS@PyyXPSHU-CT7N8NgDHBTZqh zM74JNU&N3{X5WE3n#8~wcJrYEH+=3MRJ!|}zN2O_5TP|qiaN#b^;}{^YF_F?Aajqk z)=w)m(fp5siBz@YYnWHn$ z*`J&_r_uA*^#)tpwL1;ho3sWplYrjFaLmYwsw7334b6pzZZqa=mg`%>xk)-ogzKkf z{x+J}z^eHJhbxU`%8VRWZ2lzVszs**Bk!TKWxjDzWOakWmU=BHUHQ+lT>l;=3;Ts| zPtzi1Rdt9G~L{S@?uNDatpDGO5i3b;y^1g38@Ua4t4Uxg!8&i z|7g}a)L$>Iy-^0Jc7xDe@8a8LD*BX}{~AFNc2=sv5mG^xWBRO`tsMC^Ae|Rh@ZpZ> z;nx5a4yh`PgmmN~?Lx6;hfqMgSw1$zh|(##_6ZIlyz7njjte5`Q)?wzhkUq6z-B{E zu1tO9@+Ge?jz{_Eowi;fqh8+V5Hj(3l=08vS#*$22V-l&N_#j(+>T_r>s5Q=UmnrREnrx> z`QBE*h=Wp-l|Z`t)~?kYsmzFSdx+do`UZ`q#`!&5VsyPJ;~K&|XnTFPElmq_?U~p4 z@(1$>!+=6tMyN_QxS6{_eL#0#d4d*m@F716K$*?!lQqr`xhK7~u7FaB4kI8K>A$F3 zH%g-^6C167FN|kSrRCviyQ<16J;-FgS9;{60hTXR2-w~2k$7!#sI6Bi!OS37*fa#H zOV`6uic~8+E2bSKR7Nni_7VfP5|lm@eGjC?mkKn9I0FPH)f}b8WU^T^VA9QV)Q=gP zb~H9~6Rzb5DbwHSK5MfpiweY03R+`0m%I9wBT%iuOR)XUGnh20^D)ghaWOiXmlOuR7RV~9rZWNhDM zo5u8|^ODbfWr9{Iy;hj6e)HoXa8x>P9Jxm?saU2;0cwppeL4Fiu6G@OcS7TlE0j|C zE)H{-f@`=y-1}9gvbmd{J(l|C{{8zkHgDdH*3r@7M+oyjpS6x4Z%CJQ%t%C-L?M7z zYrj!wtA9=5)PHrT{IVQt$zogb-Z1CAllHFItz;u8+!$25NDq0(>9~y4E-G_VC1{yZ zd%C)C?NmoQJG=W7;_D4koTVQf`tHneJbWV9mAB(jk%a+L3Ha|hPyEFUPN(rV8&gx$ z6nI#bJh7IT$ZCCOI$cP!fD3mtG_O(9A}KZKyanuqyQuJ~9@h;#j=&HO$F(e@)y}_I z%?VCD7F6353-tt;{M~%D3+V|1k#6SD$x{veW@pODsVquRWik)<_Wgr>b}p&2Dm#bM zDps5)u4k7nC0Y1DS6&L85DV z`uN?a-?KA+y32VvCx$ILCNzQw#r#f1&dn*I2}Z~B`imZ~WviY{s^{@A3wnp)p0E%c z21^}-rHX|NQbQ=lKt!V$DwY;?dFZG@m%NkwQ?J-|prOfQZV+(Z<75FUcKf!F`^qIc z6^va;;uR=aRk z^TRDfe(!}{j3_C6-NBC^q~wZ?HZi&lvUVn7@uKWG z1^lT$f@ZwCDSK5dY7IYe@$yFk;n88Cj%n?-hW#MO%K&zV|MSUL81v9P>39w%&pv(t zNrhP(iCU20W)_!?de=9^Wywaj3p4IcVrhf5FGduL1%nFBWn;9lM~_~~>8UY`%~t}A zZVXP^eNya=OJe2TsIHR-_)A)9Vtd!$RvbR;M;`I_Cn(NZMEz=xM`amn_s(QIU5nNC z;QgXG68a*rI^e5#J;*@4%^yHyIXw*u-pOVLjiDp0_<29(2%4r}T4GsW^&RwPXM^BW zIh}W6j?Et&d{3aK%c4VShcy`6ADA-!%Cl#FGiIc|J;1MjxkEUBOxTjiX-eu<>5z+N z7W?S@hZFA!$)6k9r8d4g7b(Y2T;`hGxVO1fGF{e8xUoG0@ip{GFv(0#j5p1dOGk|# ziu+%)cbl2VqOS|jS}SaVik4z&$k(^R-jNQqmSA`}4(ZE-o4Er5q)JwKa#o)Bn_gA( z0+9;OpnJZ&3ed~UtR%-Lc#@H_0=v8S_VPfa%Ja)oq4?tg{FJ~~mu{=2eS_9hrYLj^ zE;-ZE7l8~}k|T6(D#$f8#d;;yN1oTFyhs*AQLRcHf9kCxZAkkiN*rxJgbuJy=l7Mt zMyUCpayfT*owAVQ{`*_1897u_ES#5Q6rNWMs|Gkb$NXwNK0O475~}hrA?4kjHnget z-9kYH;Z}~qU55?lKp9jdx(#h@8=KW*Wm0TI^-f1%sTUE+3*WZ$7Z;jrXJ+edFK$pf zXFJrigyJCK&n46NXLmySgN;(u)T(;B#v_<80pa^_2Int$460MZlgYFP!|dFA zoye3$b=zFUXJW<6r5~!N*Rv3J4!=6|&`3|u6n*rl>BH5{X{hYC8R)|A0#DttW+;xL z7m7w38Zw18G%OwjN1d}Wersj*wh>efIDnn|vop}fB26lsct7p&`hA&`{NH=Ab@@98 zcgD%wx08CC2pXqsA-vqS=iCy^ZvU|;Yz@GM)E?cPvh-y&h&SJT4`p&UVYzvCOXA%4 zcG{7rYd5oke|3|L51rr^XKREMDp1-tSobpI?qMs3nlc9za5dpd^An!##Z0*jk?>K9 z@!O(UZWNhybNlZF-P5a}MW>=|R4!t$4e1v?1kYw>lFpydU!nd|)PoFt%?lFUVc3{M zfDL=!SsLuRgIU!&GjVLSsM6eu(7pXUcxEYxeHEo-qxHGC$O|K z#coc*6Sb1Z7{C3;RL^qn;q7?&Rz#PlX^X$lO3X>uV{`2c{+K-{nf){^gptt~GKNcY zERdMP27BHk%!E*M|1_Pnf99Gt$As8;UWfBTA}S1be(hLj5fz<1;1r`8tw2Za-Ai4< zTtR0kmY#B|?Uc#-Yppwn`pjwJ;a6K`zK`x>O~|83S}erj!ff_PmNTm%8*iLxL-6qG z1fp`Xm)rSr*^1P#e&;Yj32JR#im3n3$2!8@xenEJl7NM{AcVoVeK`Jr|ZV7K*} zfosc(>e51l{lOVt`>#F$@ek9E{2Hb+7>2E}mv;%%LF<)NUF%3z;z4EmAUAwSC`|le zRzcYp=QgF!*!z?VVyM8W*CiqNkc6vp8J}s|cLd$fGq1EUT zG79A@v>RK&c=hu&^=rPE(iA%oBykunc~Y}Xn-p)7ac|K65H5VEr_Es4?$D3@Icxl! zS{g?^W;bHX_O$p%?mF>&$Mkp1%$zR#r+Ej0tisM*rcgw@cwt*_c>lt3Ph?=fO1p9K zV8C9pNRh@*VR&kIaLc7R=3p55>Dfeim*2}oT}o`!&f%U_CFl2OsIMR=UVG90Z|S!- z>s1FJ>wzmVQy7B_4-Wd|2CS!=?7cWSp_$j^ZoowG|H*d6&pfksw?dTKUe$-)NV&oP zI9$5@_<(9ug7LG;G_r%2=fkbSn$oXxoE!~sZOSf*>+4GO!PsMuhe^|w9zW}>j?bJ7 zI4|??A<^#fmrgz9a_i~X3xy*@##1lU$*sv+e&2r3?N_@@dM|E^>$gBBw38kzlzCN` zJ}yjYMq>Xk4`u8~cOm4u(szmj&!cW_@-}+3yX}?4D@x%V*j;(;TDuzMooq?J$g>&5 zkN!Pejv=AzhMF->8oMOq_Fn~UiUQMu?my8k-(>hp?T2xO&gobZBJgFalTb~LSg5$<7Nh{-b7HhA^wjFc) z*psD0^9za8C|m6@z&)voKpcYql!YL>UN>bn{p7Pb~EF@4B^Ko12HMe z6Q||Rq1u={#hH}AkwQ(9;>GDk94B74$QD8%T5BQ1vAPu{Pgguvb!=Y**R0Z@c>gXi z!LxmBYHjw2e{?H5W0~4bwT4y(Vi-W@oO5D!BjdL5U!F1o>S6J^5UoY1#QWz#g7M#ir znlr{2AC==9pDQb{kiu)u^5wVIXRcz$7@#b{e2Bf0X=zJ6IU~~9w9(!Bxkq6f6jO14 zQQJ`A#3WoeBR^R=3HNeZFg4Y{{Wn^ BlsW(a literal 0 HcmV?d00001 diff --git a/src/prs/resources/disabled.png b/src/prs/resources/disabled.png new file mode 100755 index 0000000000000000000000000000000000000000..d1b1420fd641861acf12b8a51ceb7264a33f0deb GIT binary patch literal 5791 zcmV;Q7GUX#P)zFz-co3-wRlyA zdUXt}Txn@-ty=1}B9)3#ytRmML0dq12zZew50L;#APFJwoV-rXb3fK|&e=cq+UKn7 zoIrq3>lj&M%&|`PT6?ZJfBXBs`F->IR)jHzW5=O~Jci&Hm}6j$fjI`|7?@*Vj)6G_ z<`|e`V2*(~b{uku-@r5Tz>2gj1xo2>^V91-upSryHUp0U52v4-w2?XgR)cYY%YhGh zQm#0&y`3d(ZOkte$OE=9^w~B^l2DCfw$y42#WDS1$n#;y3sFR5%)P)}z(c@r29kLz zAidRKrU0LCq`dBu-dYoWfk8k4 z`e*}sE5UrZE0??GgD0H82WQTt-LgBC^ zvfct9{|)%+%D%pj+)8MyM3CT^HLJW?B|Agg8W%8cpQ$ zU<^^ELPcx74Qzt%0@nZm5U1@8*`K2Y<_il;rR(lqzMOW~9sh7LFzZG}xMSBYe!PD_ zl_c2%>`raOzSK@k100~YUCQ3Gayb^;HVdW1qaB4u9 z!cngmjyPISvXU|xnEQ9{=H@M1cy45*A9xyA14K=IH4nTMI0cyBBjwy{Iy-5X5}`Fh zN=Op4>!RbBq*^5o0=`}E_+NnQfNCl|(d&itW^K%;PibrW@?Fc99|8q9$R_OdeZIYQ zE83VJ02?xc)TzY8=>)Q^3Ty|Sts1lAp;|4s!S|25uu#BQ7Q(U+LV%RWTn;HEr$!NL z;EZy82+zM!f9K7BneSQFy+2&Ooau$aq&H;29PfD??|D45f4`fmPc5B%kb1SXO!Lzg zr0Ni*s`jTh^!5@rVi_SYLVyr;K!6ED78t`5aIS(Ufdfr;=7<2j88FxV^=YRqy>RN( z!`{%mlFVso!GWG9hled-T{`hf+RDIK=HJz{H30qKmd?&C2+@uZ0x9cIvUWjAY|kSX zMYIDi7?V#|D)V|B!8Z!#Jqt^vuYYy%Vx&0KOx?3<7Y68d-9z9kE|oYChR3ffm-E0g zDUgx0jizwQ88|iI@$cmGw>X}+0x8GEBh=b#^Lz@T8>GvKWYCM(ScY z1pFeSl1H>kiL0*eGBak(cvBX5G6(LlhxfDliGUxScOETiI1ohVG%J zHEDRCcMkix@5lIlj16$bhi7552A%#Ehb-um2$D>VovIHej1*Cz2z(6&-u>R=x%tKo zT=|1%_}HA!el())!3%hr72>bcDRy#iM~`|P-JZ1k51Nvmyh!`!*te!~Ed+0pvqm3bYZk4sC5vBMdGN1C@P>5=O8Fb zK^#M>X-9n606Nx42})UnejAlajp5-jJg887Tw() z2r-CJU5t(n;MXFw60~=;^XWfZ!2PA&eD}W1{9#`oT4{tO$k`SZZ8O!j`9CL~$W?#2 z31!cl+i>>l-lb*TJw>_b!Evo?R7B5)MKuhop&RIB#NuJP7B-j+|A2d?qKsq!-dQ4 zsehw=;>%%FX8kKSvS-gT2;IfWCw!bmbIt`|)ia-E@17SJ8CG2QM~k@p&PQn9vxj&0 z^pL~}5g;rJ?KsS9Y2miHbGiENE&Q*Z9+a=ixekfa*wR8vLruUv#c5pgce8=b{NeBI zXZ4FW^X&6qN9hWkoe6PRAKV8oeP(=&W0ii^uDgwOo9-s(X)b%;vj;)hx%Wrh|In97 zR9z7oeroC`nKbsOruUC9||EF+GgGB%-d5L_hVeI%+&5n=2ZW!uB-+Wj;^P{wr=3N7~dwS9XJFt9)1 zr%#;8*{9#Y?Aa$EL|v`M!89AD(Mms3DuSRMxm2q$p4$dM zr96lb9!7UFw0{myKKDP#<%cubc+Upncv32X%og^ruk&c7yx)`nNPKA_6 zDY1-UkMHyKfdl+}bT6x(xr%|oHFS2@aO`A4Rmy{@eQ3va1uB^^6iXH_=d2~~qg0wo zwQQ3_6RWGzbqxuE2&E#`PcC zNdP0*Gk7Pj?EE5UFa9i-Ui=UjF1w4q<37UJ*eK;OAIpxYm2JjG1fRI_-&t`{2Y>tW z%lvw95FusVm2W7w)>uhGR4(($En8T0MIOf~a?*?s69y532V5!@k%{0T4s+O+#IZc$ z*c-og?&7a;_8EW0@0|Y?+#CeK#2nk(W>Txh#F50ZT%@HA^7iUBrb(4-nP+rlglf62 zIyL`gY^#7)wF!7Cq+A|D#T~?n&-VUb@T+wnCX%M^v+L3okE;LW|Ln9F`T2U%T;^rQCGu68`PM590d?S zLQHrpjUaV={{$e4EBL_}R_bnU+WtfQARy%Fj^yQoA&m0 zKHAmAgWtHHotw_&skOgLZ_nA(s;vwSwq?d)kg|mf-}XhiN(+f<6Jbh{7;3%&qXB_d zGUK1-2?LGe)FpM}EBB(c9Cu~Y<+={10ch%Rix{oE#2NGcf&PKp864h(>pFOzm)TKL zNMR$SWNP>M0L+>BDYowZe~b>cvGlZmA_zuUxA9I21&_|wcLDH^pZgNOU+HA-w02CA z)Wz2rR2+jb!Vku1DU|5!>SfOCi`ln- z14El%7$4)Q^H$Q@)o%K+`*B{}@FSvRLd`z# z-n#+#*)Oi)g|)vT2u5(7Jj$~sg2>NYy$stHlt-tqf3Lx>4U;H=N)$$n;yMmfx)%}n z0p;3y!Z5&+Ih6K^lM1cHUZN;MN(*Bg!mxr6F_z^bWWv;*KK}kgzhb4`%KWx=tTf^_ zNkXg?5BK+T$KJjC`AH`+JM)`sZ>Wu5}&sAh(b$(n@fn}VZvw!aa=*` z7-K@ZIy<@k+Vy;@Ybp!6r(orBXk)O10HqkMR=91?9^QX`Cx5zb9YGj^G2=OqoZ}!o zkBi(qV>fN!$3J-(uTUlMW1=vjRsoe5Dz!oUU=Yi;iQ|YksS-yaVOV9XJVq2(ke0yr zeX6wzVOS;%N9yx)Y=qD_Ij~Y~v(8#p_^ah_>q|Gq4BFI4)B%EU7>H>j=~?DbY`6IGqr12`m&2A4gdkR`?kNkwOr>~y-3VLb8t=HMNDvq>HgQq| zW3U~ITuze9*;K1lv`)|_!I%UuSHQMp-Ih}CTS$pE8m+;yY>F){2m$-{jWoc_$auX9 zfkUxa#PbwhzJL^Ur^|6%+?>SA8$3_qIxPt4pjF*)+fEKkdf3(!Y?!Wgimz;$xib_;DK2RG+{FvM|$F}m(9xDLf) zi6pLT&%XU5b>kZZ3NJM}Zq7nVLA4qqL=j^^Ye5tlgm93;#>;_L^;IxQG+IFzYHZ6z zm@d3rfh*qs2sfR47Beglq=k@@L~9aYXRX2~o_>bE{nl*u^w&49lvb$NaQayV2KLAN z&0_=nMNbc=S|t$z+p@5Pz;<1(Qi^~0;Rr@`bLkZ$7~O?!6_A!8jwM1u&T~K-EX&4m zT#T+egGLK-u1C(D$ZA-YMHGSUOsveJo}B*;+1}D_5@;15vd1 zHMT_B-rwF{SXnBOC{_1wltPCgs#ar2Yrd2ui~@b0q*$=Xd6EOWLkev+)v<)2o+60S zvXO%}9i@a~tF*>O580_Pb$=e((#?b^Ku>xu0fokL-n4}$fKwNBbX@wt+uwe0g3TC$ zbki2CQ9_{8PIQu(r}pmM^6}NHPpoNuYnm^5txf6QeP=#@_MhbQKpJOf5-7o8+Q8!j18={mx0mBmk62`W z4w<_8B8qryU||2%t5+`tKAEORvI#Z+Rh|(7JJ-c=d#`0pKi-&eDB0G0>;t}2AIm*y zDkg4BxGABR{X5%gRw^MfQ>dt$I;u|6eBgjKru@qT2bNqmb0)5o$n;lj7%D9U`@)dx z)~spW7lxaGy{QUSkDxUMJpzn97snTzY*}Ns4{*T>vqv2*R{=(5o` zo|#_SmKGpZG6QZNcmgZ|F6xqU=82ZYbRiB4rV4zcuBVR!t1?iksibBTd!y;|vdO*i ztf)xUXtGtwI!ppiq%fVd+Oie+vx}!qyX5AjOK~#Wfz4$gQIhc3{{1{UFu>0a9N<6{ zZA=qxW2u3ZY4xTAPIZNtzsPl2<~S_2tno4srPM)vH=x{5H@2&QM^n2Jq?bn1m8k*4 z&(zLLnko~SWm#sHX*tPC)C{KqrU-NZpF4lbl=t0o_Sxe#GOtxQ^wQWE>&s(#yh=bP z@TpnF;s92kN~4ORAuS`B zN{S$pzgCBv+tDaaY)+1E2Y#`BY|Q%CZQJGtT621-R5!{;0nC`z+@B=esuWx6QgUxv z1Ji)gSbZ8$hMS-yM^f={w5m4EB#<^G#ytM?;9&0i+qci&P%a~YX`Y9b+Mm}0=A}61 z-=m0IqKFN~JQ~5Bz{W}3i}I^T$`L_18Z~$gd(`lt8^*X1X0)a4IA9U5*pqVMxt*Py zQz~H@!yM168(YUANfLJWKBG}YIgZ&71gr}~*2gh{F`Lu4?uCre%sQfeX2~B-p){7` z*IkEqG>Q|O;drS*Zq0xxrk^#yEdb`GuEF%wnD?gr4Q4#woxs*qJ)| z4g*ItmA&hXq{NvBIG7~(Yc40#hp8X_jlF#$GTw9+kekBDWuW9Hk(%cCO=U{pqYQvB zBOMJ1dBaljp8=*hu98hLnUk?G&Lr_!GZ>wjbXJ|>%x6dSwVeN~H{8S|@mLmymAUq6 zHbylWV9jsgi(Ic|gR;^jC%Klj4SJGL<+u9Pzax3}kp!=ky(Ie9zASp|zhXN4_QA2^ d7?>kJ{sZ@umgAB@43q!>002ovPDHLkV1hGYFp>ZO literal 0 HcmV?d00001 diff --git a/src/prs/resources/done.png b/src/prs/resources/done.png new file mode 100755 index 0000000000000000000000000000000000000000..8ca1d00900fbea19409efd2ad8bd85168741a0fc GIT binary patch literal 5854 zcmX9?dpwiv|G&3;2e#Ri#fHZwIiJQP9oQyG5~4>^Pv(3`(Md$MS(b{ZBze@Pbds{7 zCq2cciO8v<=-?csLXN}i{_Xkx?$_(OKCk=!<8ysJ*L8p1@AvgN?d!c+1EY%p06=4l zhnt_uy8k!SP^$T$&A>^OQBUyLbr=A!TK^3gP*_A#eMCgDwy^-<;knes?H5(=)G!af zZ2)lG7y!6@0GNkV_B#L^r2)Vw8vxc70Dw;Xh2WPe@7g=IxUqI5eGFAV5JP4rMF6lm z2VF!Lj0t3;aCktIc>~4=0YrPWv=0Da4!SfafC<>)Pu?7t==+AVpnzIGE!27z*fFn$pzq<=j(YFz>*;DT^@y~$$?IQs3sli(xv`!D4r?d!@sTR$`SRk!`TR( zl&mbT_JN#b`lvoGSh_g*_4U8q?{Y5tjILE;%zmTK#4Kk5Ft>}``H2}#JtOe7m&ZTz zNPH#(a-k`di}=8EsfbAi2o9rHy;Phs20Z=(F#7K9+SEueGyr8n6(HVn5~#|BnVJ5= z6+1&moA6%{7$st$HxQl~syc}sgo3$X!UPCL7`0!WeZ#4F(kDKl9%F*2T#KwSdS z7#j|=2!Yo}X`@U`64`xXUN^f_Dpf3vG&F!IV-ZoNzZd{<0beH($!&wkZjOK&H8K{} z^vpJ;i`&hn%OJ)%QQ723o24LFBBUu4Q^apq)<~K22t3hkXaIz$8TM60^WYr4$|_XR zVrbMh*4Wybs;GN&nG&--1%}Xk{K<~ai{NRQ{i#q+UFdHZZ%_pY50@bGt%HjVR=sS2 zYR$2GT$UhwOBzRtq-$w`QNAbN?f}DD(J^lytUX!`a zKGoq`z@~=Zxf`&H#a|&vn9AX1Seh}@pbTV_t;L61P;pE@L)J#=vog0fd^s~F@4rmQ zg^y5f@<2_dSI5Coi66VzOyj``Wle^5r7&i>8C2Uj$B2e$;CK>vAgR^2G14F zY{u3VF`Liq7`cd3EjvJ*njG{r5b<}yK*8WR!#6e=`5+(SW4k%HO1Ov#i!>IL2SYT4 zTzUEI->1F~zC0XHVQ&2{$qVRLRiNuZeI=v?ue?Or@ks%Dvfag=+jIqLXU;DzQe?74 zA-PAg)F`@Z`ARC2c~*8a3G~m;mAwAfBfU83qm#VLIV*0y4GD!mPA2j8-+*u!&*!bo z;-z+AKD(o4ezW%qyehjqbaQzEyBltWldyCTKs82>x06U?JqvZdJC7F@n@y2qjW^0Y z>=#GB9>aZ2HYIsJ%Ax=4Q6d7DZrox8m02yz0Cg3PNP-s%ZoYt0MN!mQWzw_)kE?A<7 zbmAkoIU`?J7 z`xkB%JJhhrw==G8VywjnH4Y?SXkPO~JIt)~ZCKTz-+%D`eqse$TE=d$2P>9i=|;~r zwTa>WAci79HSIK0p6jqM(FG8iH(@uBE#B=tlkrL2a4_BVC$4sxXZRJuTRn1l)5Nb& z6qKW*2{p3*n={uBcgJ5jGR{D02bkDJ&-S}DdB*v2l!iCUU}{thIDA>(i7XRndK~Cp zzI{L3x%KtgYN>!&ll$h3grnq_X`c*u7uOzF2m4x)TX^Yz8wUHwUtVmE)-|iVckTDT zgT0)DUvndE9Pc~Au3SH?W#uloWmM*wwOru3!%H#CqK%O&(2;TeMXTM3o1gh%Tg6t+ zPZ7%Y*Qe(l3T%f9%v4}OL^ca03?9HuY=#Sac~9uOC^`$ftt8?|Lu9x_h$!_3dEk``@+# z9}1`16$8W-ME`$mw|#63U4 z*T1zPM`CazyFsy8uifx}e?|4a`Vz0zWcPYb026m~&5N|e#7LC-78?P2PD0aPJCWWm zI~9zxvhrf*(7_nrt=b*xZr;WWjxr)?@|&e>Y<~_pzgf~kUDe#0TXeHg6u+ujTHlHz zRE_s4(<{2}>ru#KuxGl`N5fOqpM=L;^$tly);(>$3XKlaO|e7ERDA6ATg-o!^K+lK zcm6cQY_PXqI+a3nL3%BU+L$eOHcQ}{2Q-+5^^J}(SO6Nf?I1&EDhp2 zrWm3xJll5eJm%_l>c2>gCNr;fId{5ZY{Nixb~eA8Ok%PL+y$Cfy9-W@8+21NgrBT? z{Cb@HV9)V}33;tf0uSTYX8Q`|?JSale?AjQD-Y&|C(PzX=KA-+ZrcyRm$YbKzaUXf zjbY`a)~jitCyT=y_J-x#jpzC`?QTz4MwIYT%in~R{fCAbK~shhXYQzhmN zpkg7ra)jsL ejZTkAycq9@-p;&@z#2nBfjQOx7Q>LA}nH7P#V-2@h!;D?~w4j!E z<^g&~GzU_mH{f8S`}y^W*I?Mg>}@l@CSM-&=bfKip{q$-fwkt?D>u>pc*xHn~>I1^ZWOc zJlveIjm`Vq_+U?+B#pcNTAa=RJJo77*Yb;cM6oTIJ3oyGZi+ zZc-8#Nx!oPrqf#1ZudzdN|#f_$VI(9yLoU_2N%4VUmnbn!6yjfi7&99DOdR@Oq_e4 zo&&Xqh5huTU26Dr2@a|XyQLE^Hn5K7W@3p>(tl28KFv<56lw0>fTe2@^ww)dI|yNc zDZG1;zMnEqpN8$x<~?flVaLK+w0Qr5qFXM9=3se84V>kNfFNs`Uz2TR-Xz}Kw}u*F zbm7^5xY5GpMVJOe_i<4rETh!)R7IS9>8Qd^$~}n4w|S0h53tkHx^98Gw5jWi9((Q4 zsqcg3r?~rtIv$7J#LRh^MxIZ*#ljyBzPYdSCAe@L@jrFB2q`g(Af;FnIWW9I=w&fw3;xu8JOe#9&?mqS4$Kw2z$MDF3 zGf-})W#5tyWH`-Ko!Ya$S;MCp7n}o6&8FI+{E`6}0z*pK zx1KDxX6_v>c+C)p)f#{gp^yOybzwYMP0vFn=RoO0%FvJ-rSo%y(}Y{B#Ffnu;YKkG zeF%$$UBr}>0`TY~7mp(qv==X-(@up;h=c5^3_u&s~20{f4sD@Vb>=Hufo&Om8vR2fC7516f zwRX{#mup}94P6iG#A8uw)sLaDe0Ra$b3188H64v2vtNzuh|l#2gJbpre`d{vvNil{ z^>l*XS-}Tf)y0!esTEH|PAk^xAqOqY_U23;1MIs=$n1Qq$)b zpY-B{3@AKlYC&E0Ea!4%b_Rbs#~9WOn$;a5BeR;I(oF3v3<0;soks0XLhOcip%}8)iU;cd9MpC z6;cvjF%bQnB{i>05c$9t)`WxuX3r?XKC@Tn2={XQ*HMJsCIP1vpBbkxj0mvMKbsG|*yennF$x{yQgc)TX9E z_2R%0npopq>XmHtkeOycZpO4(>)t&utLZv&Wyf>!P{|jPf%7$W&y`Zw3+Gu|dSGS4 zv(-y|055s8yW$k?cH8|B+G-51By(KIz1zR0Y7am-E=jHv?;mkszh3}te(vI43k`)O ze`CllMqMV^?CplP>T-Cn3HkR;B0WbQ2oh;D7qdm$67rHQRJ@vMRN0wT9Sc|CfIp6| zr6aaz36mR7onm>pQLJXC=aVNy?@rUV*22QdbkxfpR*_xO(weB&cN?h|W%UzNAEE^7 z39}phmO1Q8$9(*{Z?q2vS_HC;lEuVZrEx8}B3syyH}`6 zv0uB&2R!s9XPhJbbw$#y)XXG&-@3$aHc@1>nlN>+TsgIZ)s5cqmD-GX*>{P{ zQSz3W>eQ@vD`{Npo-R#`JI9BILg8U}ygMq9ipt(dH|%UN4W7wO~jcA zX!DG*v;3@kP^2_z-#~3{G&S?lcm3Xij8N*HFU!hN?$K_XSGZLZ>Vwjhr7&NocSh6E%y7lFU%tE@9{G88NG7$-%-abtDeG( z!nbo;+{5%&FcN~tW-dYedw!@p--~Zw)36YCbITZTqs=mgd(HGQLaRG`Aj_wvu50!8 z9`E58{pHq2X&*^8w^KDAztaCQQ#iWHa{GKM^PIq%wR`8J4>8K=L)omEsqu&1>aa>p zBip)Mx42EhH@}|?UqZaY8(3@f=vQ3{UiSB=uooFDmTq@!3OW*4&NHeQuO z=|}g5JnLmYCLAhdpG-uv3)Fq207CQ`7XX|LA$@cwDj-Rx-(PR-Yx#Zqrz?-f$29)a zd)iz-#x3ueb^tiO?L_@pYG%Ceb|bPefRcQP_XV{EHyW)D${HPOWx&j;S(J?FQA2J z=m++rH^V)XG2Ir4;nPEp3 z`>TVaxE=0XAYEg}R`8+jk+IEcXXc9!t9l;=_e#kR#pE}r>rfb(*zmqk+7Pws#a_SJ zAgxD)&mc^r5=3ZDhHr@T{F8VFS$r|<=Z>HiEH5cedqR&Y1@7m?DT)(M+*9?Ufi0W7 K-5$8I)Bg{I^LqUN literal 0 HcmV?d00001 diff --git a/src/prs/resources/left_arrows.png b/src/prs/resources/left_arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..dd80ce9416f2ba61420ca2de2a3a317fc157f10f GIT binary patch literal 2407 zcmV-t37GbYP)y|0XByVwfz7903CEi zSad^gZEa<4bO1wgWnpw>WFU8GbZ8({Xk{QrNlj4iWF>9@00_%TL_t(2&+V9Na8t(> z$N!Qn*?QX;S=SFR*iewc5w8GdGPf|HU??t$1A#PVig`cAL!moLNXK?`VydE3?paj6H-+`3?cpt!YO1A*O)rsv7U_EWzE(KbwmOKEBB}pYI0Nw%c zdKA(QpeRb56u_1k;>rPZCk$!r^leRyNiUOhA#Q}(WUh^PZXtlh6l^|W$nPvxOE&;R zOOi@%N0w?4h1~*RMVYfq0ic)JWWLUF>>dEKDC}tfug1j?ruF;%iFTVkj^)^N0KWn- zgMuyuP!ah(9>8BDA<0K!S(xUz_W+cYIm=Q2Olgs|G_f4}0f5OAc0Yhp!Vqt)B{s?B z@*ZERzT^Sq#Sk|Yz|k^inF&_li})`tAD18B7?y=!j^aW9wgIRtbC&r5`ql6(MtjMz4?co!dCw>@^ z2j)g`Z4ra32t#;SF)S1c`R<4AzwT9ehjfnWPJ8h~!VvFML1M95lEUF|p510|y(YU> z*l28=03e?d5HAsiTn2zkS1%RXZFbF(+ z+9pug9RNPxCT==_D*$l$>&vt2J@v|}j4IZl za!jQd{0u-fVTk?G)k}qLzq{|A2Ml$WbH8fq(0h2wgdQmRdtmt zxqI^bC-x^;pz##=j!UMOu1TvAlkHyFO9>3zy5)_h8z=bWYFZQpWuRz^-SB0|05Wt+{)t zximS3xN-pd2t%4q{q0o2?bO@7_x0G<%b(z%PZ4(zz%s%RubNT6YYW@I~uaVst^?m?O+O;}=G zQfu%S{tzQb7IsW|m`DvK*_9 zDbQ>(H`yNB4jCC^Txuvaz1Uj(P|xds6P-!`RI(g9!{_r|5rV?6)5Gawmo_gwEe%OO zrWk&IWA4UT<3^7=BM8E&ZpqzD^S+s<=ll?3V=>gT%K+&OJ+ZK^tb zo$qYg*`6M`r!Wd@0Pr$l2v=2I^>dw0H?h^zdTEzwmp&*DE{ahMtXX|)^-M`v^5aK= zNB=n1>zK`^vCWSWl>0jhho=(SpqxRwHCoMHLy93_;!UafE&0vbfc8KXmIL4x%dv9` z@(Z@M^X>bM8sm`J-^{+5>B>AsFSC6G+!dH&4ytnCK3 z%DsSgP;~k9aqjZDOi>g|98VlK?y2t$IFoV4Z&%t^&?+OskkD5bzFH;(g%=$@ho>UD z!stH0 zYK}g)KmZu_!myf=Lq>j{XiRL>hP3j+rowapt7(q_W|KKIderC*GMVh6N~J0)xlwW; zfloLQ#m0BA!9cJk6bkJ~SEfIn)iO&e5ha_y*XveQb(PGiaCWQ6sR(tHOf1JL0SJU4 z!Om>m^}1ZA)9GB(XHCalLm9b-$_Ya}o!NbV-1o0=f1|kLWkUX6dGBL6R>pFy=6~h^ Z^Pl=gx}6yt#Ebv{002ovPDHLkV1oP!cVYkl literal 0 HcmV?d00001 diff --git a/src/prs/resources/no_status.png b/src/prs/resources/no_status.png new file mode 100755 index 0000000000000000000000000000000000000000..9a3067c7b4d7228a82cb9cc6eba05bf16a07db0e GIT binary patch literal 5809 zcmb7I`9G9h*uQ7)*>Gd*V;_`=GQ)`SWX4jdh*XSH#;#qd9ttx<#t;z+QAUqSrA$g` z!7!738BZxK_Og`9RvE_J?>z74{RiG3u5*3PIiKq~pL3n-T<3hhX+Ar)C@bnI0sx@A z)x+Iat~dWDIE=hKv3BIVTq#6*1jGPX=kpyPYm_& z^#XviD*=F&3;+^Xt|tNDGzkE{G5}yh0RZS6&k1@Z_pZHatGmnY*bgC67^Vs>1SkL@ zqUfRe5HuhY1E~Ob+CPY75I~8e1VaFTpy-htf&cfE$PqYm68UhWW)Xr+-R-Hg8aCus zf-{GSbxNXhtXPNLQmUpMv4?^H5bl+%U~t5OxMPSBQstnAXOPB5L&YN_$W)vXKh>ta zv2l95+n7^X&$Ror^gDCdFgtN^Zj}&CtXue|BdmmB2SnZj%*ZvG)W|Yh_S!TXKyu$A z%oIiID?B|<%W`rc7hm5YK(h45#u3k;I77a3Xo80h8*vIE(DGT*pD^r=y800lmm&B1{BSAbFqgHZr-m08+{q_EBD zWOf6VZW{wW+fvFF;*_ncKt;J(VcyOANoiDh_z--xqLo?YBzFlW=7Pghz42V zErtyCl7__tQ4?lu#us*gw@Sfk@gsG}tY}#)>YX*Qu2VoV_Sgf=s1jw$ufp=E@{_sG zI*7t->(|@24}(~@u7>!8^=x(+6sE88COmn0_SN*4?vim@csDOxv^{FQ30hP^v$hn7 zRvc7>!ps<%H^FTQjz|vT5MZ&p%Z_Bt#&kIlWeUp0^<@|p8bJ27^2y$%_=NTT_mr-% zyjW6*S~|qo=Ax>}x4G1IUT3i0uH!kgWOxvU+u6Pj*#;6-z2W*& zBU%$NYa?ppQ4kC>PtA54|JH|PX_iPZ726vBnf^8vmC+E%6{Amnbdtwlt03wG$?o`G zB}nri!%bPArb5tFQ6UXTzG~@Hmg1Ao%CL|3EGa86Q%8)&Q`1UUd%J3vVYvAr6MlS| z#WsVg!G5<7wD=5mgL;AcMX>O=xJ~y45=UfNC=@(5-?-5(QbD0uQG8h4{@5{}VUtAZ z^119@uoU*^@3MQ3th&14m zKFL{dGTb%mk{YOC7D297qt_%I(MDWRm|%yBy1S>x#=Q%zN~p;O33_@&W8Q)pCED2x ztzxZZg6-1ass1bm&l(Wc`1;ZfEU*d$dmfvIlo?TcWa=LQ6pol(8IiM-@WLtWLVIw# z>reLmf4>Wo{GfuPPdgjCgT7;U=^x`CYfs9{ z7~A!_$%d_$MrbYvZz507D=2Q>b6%XwUvBGa7Z#Fvs!~4qab+&+{^){6zHVKSG#qzP z8;K#@=$!jG7(_DOX%DBg3m0J7@+z^fdAGNNje?y#!@RI})9>!ly^O3Oq}v=2t+r`t zYa{L4e=YdE=pE$bkU-cC?va;LRN84w^aQ-T-9R>n&f@`<0f@Ms*pu zC+im0ic>g;?KQ#!IAXNlNN8s8PRezONxB&od)j#q z2w7LInPiS#OMOIuD7y%vO&J99HJTB?o`MWPx$3V^oy4_AI!LF}@HLP3_~XK-PajCJ zD5Lg=I!0F|4Ug6K(wH<6fW&!{?a~n&MM7eSR`c{yDo*&clBp|$)zBB%6O}Rb zNtu&ye1PG#eqDS#bSESPs;$i>)Wu7hiEAfX1;UkB6~Z0~fmb9W$HSPdo2E~udjT22 z*V2Lniu*nLxa{Qp_z7)Zt>Em04n7%)UV#aTsj_SUzYP4d5&C2FBN#ulD+Cw4AN>~e z1(E+H!Q^YA^0S#H@=N9)jj65pg_%(sVY6zz?h3SqKpL7qLf8>>FwF5x-TC3B<@XG7 zTu&gUyCe}bgt6+5RG7@SyT|%+jC#E*dOmQa@cVc;)b7_EW`Xj1oli|@)N@p8Y=pY~ zD}w2yySm!ZM4 zseVYG4sqEZQYRT-XMsbb&4WWMF#KUjy|Y{IGUA&=MUlW*{bDXwL0I(XcEd?i*Q=2E zVk>l~$4R%!_N%VvCkdhIL11t!yyWoq15cgcxbK!{a7*WQM(p&EGd*x`BVYjV0LjcU zl~hDDSE2<=4OeiAHzd-0+q;c%WFN(|($7Z1iwW1VKbcgB7{~LPeEiRHOsGd49EtUA zyC53ia%g3g-`UxDJ>mTq=U93af@9x`(o(5T@gZWknkuP@_#XX%I@;+5NWq;`$j9{FSldftuE9jIkOevy%dT|+vIPF`4ZYc|$8Ced^}wC^&K|E5Ai zE1d3>U4WoLF} zKMLW;sD}+X1V@xVKc^E2mV$|lUp`hAEu`a(uAJU`#P@CPRQyB_OjG?wyODPlwR?&9 z_s8=omj!I>j>|ryE{LzgySv2wvH1-m(&gY^i#s?;Cp9=J+pUHyaaXtqBp2Q9@^gS1 z>==8*h?KUHEvaW4$y7W|bSkI9#P3c-TC{J3JP}HSzP38-T7kd_`}iEN+U+gLv9Ao-|Lj6AJRAVsxUmfi3`~M5 z2R?zfZ|KTx+&eC>UDCWw4Ct60DJdjN%^=zT=NY^BW!YtR z{+6o^@1GPjG}l5EiSJ~Sf~v1-j+{c4QJc+dBwkfHoIbl~|F)5i?%U8cJ{B?kdp@iN zvVNTK=>qS&#^zY62IXp7R|8H23EsR{t^fw?xak(;^XM}q#}8%fJ@@JR5Gpmfk^Xj5 zP820;ZJqZG*?{t8rTpKdivCXuKldO}_!-}Z-9iVR}bT3*8S#pT75@dNpIGKN%Rko5Z{4Y z>WuW@2+k=zlVk23D_B)k8D-?;t5tS2r(YaAx9Y~b4pi$|-jUD{yy6b>7FKo71)V>v z2;|50f;WxLRvmH-HN@Jw%>nz?wqDn{4px2;KtxXlk(8AP(T9NQBZai#xu`ZZ6jU!`b;i$q#R{=R<<%v$2!sX#)FCk(S!76Yg^#ynF|QJu zTRdPp-_k-Vr`v+C0o5FEesgNbnnI>U34u{SE{-2|SgO>A=)u%25nXuP!yJT8C+%K0+oZ?3dQnjR{eq`=}vNRD{chSDtAxw+^gh?ZPl<98iC5u;U>EfX@M zOqy{&RoO+$yx*$g&3=A9whgaM9ofMx`Uc6ZvoR7%5X^3d+5tL&)b06V`r0sl+y?VE(~l=1J|($w3}|TN zD3gzcfn~w`H|k>x8Va)bmSl=HAkhx`m9Y>K4T3T4Zx_YGEC7jx^erasTyqFmtetR> zDcdW2jP4Cp1-`$$ zo)HezFLsJg4cWUr%Ep6sR}f`K7;nx@Eh_&=Df(!ejJ=!PkDHq^Ug0ggdzv6q%?t~R zlRNNL<}ZZFzlfV#47B2FvX!^lxqWo3;cQ6Jta=sdtFALe(s*MT2iV>GeK>KELa*Y_yHh(gl^^!{~8oyP*@Tf)DCw@$y)z%9BS7G9Y?uuc-;W|1rVs-NI{_p5Jx*0kSZXH|LrWrIg6M)--)) z{4>S-^Jme9O-lrB3F0AHJCpaDQf`{qC;+|&47gqux?ZqQIq*$oac`T8c1lr`|@RoQwh}pxMd(V_*ZFyIPYE7 zlNdIaILsga+D~Q12I%UB_p;)&5&{c#xGPU&1Q~?^-m9;1JjrZq{iRj&;(pe}dJu)T zqtF->t1C1K8?1MpU#$K|zZ`?;eL+Vyd(c?HOLODT>*3`k+_lDqG)m!b!-G}I`G&+_ zS(Q@R8e(gQ^%`Ld_w<7bzhq9T46QVu7qL<$X*zq%xD zfR~;ouO{_!8HIT?46n8PV79_tL-CyVormmP!Cb8k-DthPE#`7^W=jr6Gzro#pA_e_S>_*9znzh#_t-BSz$>J22efEk7Q)*>Vt$u z)B(qNwdcOMYJ{b9-YrX?T2sCyt*x=Nl_tg6`y{&TT4(Ju;4*0=W=WE57;+@??0I8T zlf!qUqPzHm>anO_DtE8XYR1L7t|}@Z6#$2=ToG@_Ple!9$(8X7zrKxDVO8CKCP+-nY%E#?N*Qr`D;kzC zq6@4M!J%<;QvFoYlR}wk-ld>y-*#+So+dSWtP&oX)u#bFLr<8VbyME`&ET1AQe$oe ztNJ(*Fs$tE?v?}bs2qJ#3GLn^mSvO?srOTAS&o<3p2VlId!6~TxGZf8CO2S4{wlrM zTP-o(PVAS>!EkBr@xdyagasdk$9T2NWo4|RMiEgGw{3zz@QRy$;&Mmf_wD*j5U<^`vaD~cMhuXqPBZekx>tVZs|m3-+#;Ff8G zIKE28Q=X)&DT{ElvA`U%t5e z3-dfiv0{UHoT1VGZFwk~rWAIdj5W+oZ$PR%*7G#{K*{E4kMUgwpL(nb62ECoi25x} zxw0B&9OO3og(tWkD$1^QRFiXJ)x}!tqv@s9S~?U`ERQY9)O0kUpPlujZ#X@XhpZ4t zlb zS2xSqQrM%dU1jpHXDM<5F{j%4y5;?(Lk?lj(=YOsYtPh>LngCKuo$}>gF4$Wo4p8W z7JIY)GdZO)aL!b>horGLQ^Z}#AY}h_@xGI5?tP}5&czpP>iKSdYcBn0u7#Jw1^It# tbYiFH|FXY7UNj*9WE6!F4X^+Zxc!y2yVh6yM@}yTTQ}`+f8feU`X72Y7oq?F literal 0 HcmV?d00001 diff --git a/src/prs/resources/right_arrows.png b/src/prs/resources/right_arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..f9e94aa517ee18e99e57331c5ca68bffcb0a5258 GIT binary patch literal 2468 zcmV;V30wAwP)y@0|u6>@m2r;03CEi zSad^gZEa<4bO1wgWnpw>WFU8GbZ8({Xk{QrNlj4iWF>9@00{_5L_t(2&+S-ybQIMY z|LyE#_Bq*Pli5rXAUrB21V|7J0pk@kK;*C*)AHzPw1Gx>#$pfF$5Bg*S~V7n@quVX ztX8UrmmmpNtjwta1X7m(D}ewDAkn@BMyfzTf@s z{l5F%5BNd;JJAu5FaY8JWB@UN7c_xHBz6EHWoQ7<4L}|U|GyFnKo~$oA-IExWE>HR z7S^x)+5v0^uwGfl^@n58!ti*kw9d_bh-T0A?w3?*Le;fn5&Z zF(Q&|Ux$xA&~#v^%k5&d2AgdebV*xYTJjPTa>$npwnw&0{vLn3%k3K1FHvjcuY6?-`fUw=jo-GcW7*$LM$?f; zvmR|!0%s9`7uDD?SH}Ex?v=T_Z7H^%N#iGNRlYqDz&`*O6S3Jn*$u_s;`*`j*ss&l z(=v2A-Ts2Sf~%ToM&O0x0Gib0ZMeD_~J;U})KdL`E@rv)trFcA^JD>+uSKA8!9#rdw zbq+iFfcJqn?P>PQ3Ep`Qz>{ihMt8=>6}}bcjV9yQMx(L4Cbh;5zzJZxhS|!wt#g?% z@|dIPTsi}wOFs}n&&!@*&Z?X*mDNs9)ODGtfrdu@B00Q3O3OJ%m=g#E;Uq6Ieq3%B9hTcGGC@)_Td%HE4ru~ zAt>-dCjg&%K1Rp55FN5Lq%}lh-7)Gw(}5BNYt;Hqgo$)~qyNTYv08rYa=Y{bFSGzi z9>DC3*T%ipO%3AS4nr$R#X(K=PK{cv*09NB`sYBwN68e5yhS<1@nTtuN~4sjsJD#M z60!1RWifpN+pAYnLzTvs9jI=p_SU&nJ6 z0A*U_Xo-HW>U32X%d)H-lRsX4)9PISR%wwlgbf=@E|;7br5}|~QPf7gUjJQfVQsD! zIVw)An{#$fH!HE06fVWB)9DV=-{ZMj^<-)=^@Hk@)u%01%VbHCzSuK-&u23|zsrYu7FS`0A+|M% zxrYHf->>wM_3u`ntnNupPM#W$gkO=O(y@bvgG;r@SwmJ~LED0FIU_eCCdD3emN^d* zk(2}YNF&NOSDdMEb75}0&0#yN)9G3?-y{mTMOx(2d(uCi>zT{g)9iVnVCb`%(`J4_ zMDnE8^+w6mdykxZq?OWBrBYOSDHIGf5s};v;C(gL7PkGN;!K5(m-*~8K8^N@-p$T3 zr@tRTB9d$XKUWF`bwIpTey*J37%n{!3VgO^^qM~tk-Q3^MvYC1CcUxPy||09GNik^ zd#AI^*+4|X19)5`Ahu2xC+i(ihuNBJr5J`el1NVN!F#mGnL?)R^UuvsEL#^!Y8e17-&yIV4>8Fz=mp-s**=Z8cj)c{@rU`@ob5%&FA=V$q{W7*l9 zgX>62N_w|&OkuNT!AeB3Q0qZtikLoMa(0Prh;0ZPlVS%uJ3F7)m%XnNz*B02NztVJ z&NgR&OXBjoyStlaO`r845y=z)Z>zBYep`B>l+NnO>f~%(lUMXUJ|TZX^FW=2hXA~# zR!u|wOM)!R+9`_Kc*oQ`8i+_z z0ki^0?Slua7br$|~MQg<*i)@LdWT%`i9#_0;Fuj@Hq#50pwJ%on zQ5CM?8W#SvUy#NWtR6rxWC+1zHf5)zrtH%=;1U3{zzf0NdNQJq=q<9P^R{uf$^Vx& i7!iq8Ia@zSqWl};U}gm^p3rar0000+EHFupkci+ADnRK@UyVX?}`-{b7) zu82;5hcZ%eJ-w;_k|L-?Iv+U;0BTx)2Mox)i&ab_f++hb0Py@uyyW0@#Xa87*?m6% z#I6MZMiKysAVvHG0Ott+FhT=>Z7cxLi?~LuQ>?Dru*Z>dIQpxv6oN>6Qyv0<)mj@M zdSGNA3yIbMG|3NONg#me2$K7yXOU5`U8gqanX`= zF!fM(xWkxv)0_b9F@w9TpYt1r0$`4_+OtFB4Y?N7s;%&ES4SYZJV+uQFK!*qp7cy< z80djL>SeHW(vB2_`xtG6ftuuv<*)kcnxm$<3G%=`y}p1YsR+e?x5(B%Q59XYFxow7 zQ!p2RmxHz3LThEn5N(FSGlEwTGI0(U>C#cmgZ_-IY<;<0)I25U?@pmZaw`spz=b!> zg3}gwxkfE1=f!6R3QY!xo!e-KKWAN`OQt)a&hAO6AVC^H^YQgvnjWA1sFP9LvNS)s z&ag|pfU%^u-#lq`9e~g@UeQGGJfyY`wl3SvB3vU-w0kk4(&qfkR9x7KL#+`45;uOn z|IdS8yBB{bJ&^#l)Izi2b}~wX416@EkxLS_(nLe%$FG-^KG2z;B)uF<#Za->JFMyh zOAsXBKBJP#-klR3cRl3&F(7zByfx=P9mSh#>lpCB;i}F zWs<}Q*kr85Z)cPA_@@Eh6%Sh-ZrpPJ^QkQx^>kS3l*r8rXMpN%b- z?LhSc?i?D=0Pe>K-_bt0oY=p=baP9~zDhhKl}NIM-(KT*T{9U%4CjIvwr_KLJ~tp* zGNDD_I1qtkY{i=jY;^RS&t9w^t$W{-%ym4hpXEC|hgR4d7X5|Eh0LqZPr^8{x5TrH z7@J2@py=9b-m8{j3##I4;YByHaoCCPRUf9r^Jh~g1yzKp85M%_o@T4ZPfo%HA%avc z;-}xsdZ`h77+yZc{4YlS>4g-gjL${3yvca|kU8i)y@=z5&J2_I&E1n&2f9q+l`CKuZ(V(`YjKmdB(I);k=4C zoEMgnr)PL(ie!_TtFCspy<>c#2l>1IQV0tn4^sPxg( zyFIOhY&rEfPyZ@>z`|UrIG=~rS*fl+oxwcu9YGbeFK%(-A} zJ`c$xn8{(xB(^F+G@xGYt7q*df3O)@veHJeJ2x4&al%(xoOJfAoPV3Q$gU!Oe>;0g z*fkBJcWZ=#y07S1xm@ykGF9Lm6(7sY2P#KF)k&2bZh*Bs*waY@0S(FzUzxWJWa_^o3!2OKg z7qeYuaf|G?a=3{|@0kPPF6rzg;lOkIg1~RzNL>1)Y+=0l4DCxaaH{X3Xy%X3x^?Zx zbagd+Omr_GH4cQkvC}DDhp!2TF*MY59j|G^^CP7A$hhuq3mo_Ro0ypF%*xAp9nHrf zITW;9d->Um(__N*!TR8a5Z1|$S%5PBGB_k|MX6CMqx)k=#cNaEy|y4B>*tQraK8y0 zf<5NO5aU&BOriCL?b{oaPOF>@I!HWC)90&hJm$qTOU`4ulCfTma^y|h(6=d`SJr7n zP~~7xiC8{9df~u<30eVHKqOi|ryTo)KigZF)j;hyywgLm-#3tGzmq3=&KRPoS5p@w zjOfy-1@B-0k3yoltom3=ff-h3&b(;b2SJJMIvk+{cf2ZIG{a=x%mRC6WGy^?t6zIv z>pS7M?sm4IGU3&&jEu!8Nz}86)&Kdh3d4hnKHDhB>EKr$Xq)!uW74r<(#812Wd@qZ zompUsE^O^0=^54G;>4h#fqYUxazZ)pHe67JMCWAl>IIm{h8YV^?VwPHu-odFUe{fm+m_ED zsIQ>o&Hs)<&K~PF5?DE>G$YMl_}ASERyjy{(;eYJs7#p67mf^eqAl3=h}U6WUOkMg zDnY?1Lsn_eT1IlIB|*)bnG30%EXUkB8oZ?+rAh8;bjfrU8Kpq0WBLry7T#|t$95kJ z`nrfCvD(?(*2uZW11V}j8pL?{+$~}AFb3UH;GOI@_siedLEWbd|Y>CXm!zWqCFxVL>XaFjVS{;hZy&*9TGoPc`| z6<|y&Y~j_n)d5fMGe6rFr(Jq@7g_#2@xOl(c8-g7H9tit%8~0JO4TNiuBz^dr1XCJ zLjBO#I54xqOLCWcE>AdBmBj;=)LhKe*!D3%_z*W%bWV+vDVo>A+Jrvch~_0|fqHs+ zNu0Dxw(d`S95d3m<*HZ);CtV8*Pl!o#m$-^9}x^Pf>u<-gD}bZ_!;e3>@_C>wU35<{u4!+&lz-q_SUZJ zP{9#}vcnnm?Q_y*>{7b+hGXg?J# zB_j%%J8qx!{;Ru}Me^Bozo@kISrrzX_g|ZU%guSwK@B!XKKUd_T8>p_Z@*XoO$r1N z3GyZ6Mn6X^;!AO7fUwV?d+9Fad&Ckv$vrO_=@u@KL6yevKC`$$C9T7bf**n zmolz(!R@k$`6V@Rv$79X+l`%#`}usu;beL=q~TQx0qvViO-~jPUvhY{V@A#wEuZ{# zU>{e}jUNZQ^Ls zKTOS!?%uUO?3d=l{O#M_B`Hss3e#xKc8Hl>0Qs*cUG)_<0e#Na*fb>GDMVAgBTtv< zF)yHU)|1tLr|$@ANwc zR!G6^x?@C53C={WcAwcwB^WyMm*`O9fZW&T!4sJJL7s>v##OW=-hpsVJ3);BT~)Y= zy0Zry(eWD|JjTG`8OYCHzfus606f^57Ku=x=6L}s6F9rUy;Y?!0ixGTi56XG;J7)6 zdI>IqT`)MYb_$o4Gl758{FMXL$Ni$|MvyS8o>xx$@CMUt>WC*?b zyAN7=`~bR}y@uH>8fmofUz%Oqz)#+8#1>FPBI7~JioxtTIZoSTmb3pp94;}{vRtTroE^L65F z&D#_9Hz(ewsb%9$d)g0Ek$P{V{VlKioA|Ky;OSePG7Y86lmrd=HQp70%v$?C(c^-V zOQZX2zG)BceJ(#38|vOhE{ajPJQY*%VBdq`jmD_~$hRzQuR!H?eP7F-PM;4EM=!~5 zwCOy~(_ImSXt-isx*jQ*ST)t))pq6ahm0)i{0FY4UwjkC#rKokJ)@3C1nqx$j@dd= zdzKUUYh}Kn@m}37`e>lZ$Lr+1g0}V`-HQm#FEt7S8-dRLdDHTHf@fo-C}I7>boAWs z;%qJ>|56J(>DHNenb{g`UNTftCiEY>@Pia(A^phx*u4xAZyho@Rnf57=ZZelo*r-{-x~E@p#2Xvk zbG&aRLXZ%&Bp%0nuf~z2{!4QzST7C(hWrwQ$N8g8^BDG<1{$V>KU`^jlu(&eAIqX9 zB=zD*0%Yf9_dRGTqn~qFJl{;Eb;Itjys?cOAITkU^&o^j^lqG*pQToaBd8G3^g}Fj zZ~+$v&OjhIi^E18_~IY@`<8D7^m{eolbnKTcYuR~IBXJpXwkxXM3nk?=nf37{Ae#@ zO*P&`^U}4;8u`BwTgJJBv?;h@-lqaDv7*`i5rs6Nb*M&Cz)`(59QjT|pWETBK^>j@ z{Bv|N68&x6XqAwPt2)lXUI{t38+l|83aRU~HrQQ`vHrEyrX=YQhVU*S8Ztb3!p?VT zW*$t+y|xbAnyPC(Y6XDvIMC3LI_m7?# zTWv$2u=OFd-cc*-AxZ)%_KXSvAXx?fn@nk1+fgxiEGM7pHqT3(rEO=8hyG9v`v3>W zWEPQ^5iqx>3Gz8qS;A+r3t@Y0km^GvbS;}C3s_o^fnIm-?b2n{FwBHoAFgfv@BvdF zZ#UDYjd%fCcZt;-kpZQ+j}y))>1Pvl zTB|k!!uKlG(v@303oMcTTPgtLTgfCBGF1Wb3{DXX>ga);w2RjMUhErLz8}<$reig5 z$5e;*?lrLd9nxU+cmqli>zH*D_BIGlaP*}V_~Ja=Ht8EJ9^3X^!;K;x->^oB@#Li2 zWv`ddVRhJQC-r#B zjS5?|lQ^M6H5q0EIK?KQPc>bjK}=O|XBQvxvzu4|t{ik5`0fex`xW0Jet%C#ZqzmC zKB>??GS3`ztEQ5!Gm| zLwW~lJSsH&*4B2YGJDqhN>4QBti5bB{A)NnAGURT`Y<)eaffiR*)B`y6cIgBK~FPg zrEYM-0b-c%-15+|5&Pr|7tCal4{p(%tM?Mkq$c&mbIIl7{y;JO6{_MraofRSG>qo? z%cgEu@T-DP10O1EeGaQ^++{}0Qt|r~!%n}Pea)3{XVhcuxBbR^t-#p9XG_Q6D_3Fr z0`=QgU$c0BV{pezjiK`Plb98^^6Bu%uw5I_H3Y)`E|qT(RF_aMOqyIRL9O+ks3~7^ zb6FK;vHQ)MN8=NB*mo``&+_>LB7=%Q6%w<3_=cw(_U$N7uKF+Y7yzSb`}&j52(~eu z*r-!l_)nzUPJ&-pU2#SiJAR}0%nh4sl`c+{3GOwAg?(DzZ^rQwewg%Dv3X{hxn+ZI z`#!qt=n?OT|MJM&@MeM{r%kp%5?=G>d8A%nUdw*{bN`lf zEbm}h>VcT_>LHKkLw}N2`5q^g^blp?w&S1qk3rDBsh$Cl6zqZP ze@;Ts2z=Yo+Rn;cvbnaO7JXY0=UB>?=fk&te!H_ZCL}_<5RWlCLsFy${q^lx~WR9TI(+FgWjiW5tRqfx4lsSs#Pa zyN7b%`*_GRr(9GALUjhj2z+OzJAm}TZX2zHF0QLL-~Vro1A;>Ox)i#0$vCAP*gW+4 zy64Bdf0tS{FPm=)QPt{P>C7^5d>x~0qElB`VvRpj7G{0={h}+YA@S3)iF{G&t_@Qm z&O01e9LGksyzo0dT{1dwh>fBUznUL3b$8#{G#@l zO7uA?PA!nPdO_2gjL{@#b}Wky52mFhzTHzWt&D7J3hzm?E4zR(hGEbH2fUoh$?|Nz z_wUfD7Eod02(+?RMbjE5_ff&dA0qU)tAqL_DPNgMZS}*OdhUv&6p2vS%aafI%2H=~ po$rbtt`T)w3zQ$oeewep~w2VtAbA_`Aoq)erB zd7_I;H=CviMNf(-8(NG^ovX^c*SSI`jv&@=uuK%l$=uX%}%rf;JI!0pqiitT4K&!lj# z9oqmPWf=glGXX%3XzT<493un37X|>V;Q@eo{6C>jHM1{Lcze=!CJiu^2tpOv2+;u8 z>SBTJ2Wh}53~T@x(k_9S5PSpUj%zET^{vb>>z+P{LqQ#UphOgV-X-Pm1=zpyT?T{`j(A}Mri6w-^; zhJgVWQ<5P=+EG7BWpiq{60~>2bB5$U7oXkM40Qg(f_;4Kg~1C{sAi9JRDt6*P7XPF zBp)^B1zUkPrlR4=p+`(^!+u^7YRqxRL+*8342k{Oip+N!ov%bBy{H2})746SJdH&N z|j)xH^)0A$#~u=Qvy&O2tN3`&AA>&^Me7O;%<5$?@J7wa&jC*Fs+YLRU|W z2yddUol5_pnj4$hwV9Cs95IFT?2KF6gga-)=i?KAH2JLBp-|lpI2>0y(-)__?@=2s zc46)x!D?{%TS!JNuFvlhPNM_&L7hY5P+FwEp0jhED-&~)0%q#)%GsPYZQFQu^64q8 zm*r(#u?4igi+sn_ha;ixGiZX1+NGZ*AN&?^D=>dK1V(RFP=cSz!uZ zow=?%KdUSzXdk3;82U6n$&y%@_j2WseRLpQjrx7LKOfjQj!^ls+De$pN`=Dx#S?Di zgQ~Xmft&7PR%$q~jzQZs(;bQkFJSBU(drFt)>0@NI(bwfMm#^s_gyOLbF3sZqx6_j z3|B?Ln)hsv>s!tUK@E@l{sItMYN zsu$!-0<&3+r1?2h_hO|=F%Q+b+3H*tU)0jwcDxS&J?FnHd>`Cx*PJRxTReCV&e}Ka z1^YHjFyi=xxANHu2=da`PF2qio763&%cfN4(qf=pF8Y?gC`)jz7bH3r1_KuC>oL3o zqK*y>Y`Huk2Bmh0@SqgF`5E4=rEPQa;T}YLcrt zx&i*z!N?nxLX(-%aXarOab{(0uBvsIfehK*?`zSI!V=5xw( zvy!yWp2D|m)P;Qz8Yt4#4Ck83Ryb~u{5$Fs)y(Ja4?tV9L$>d$487HXou!1{5^#B@ zfbY_ZCS{MgJ(Dv_&aq315y?QehVTQYxYrMd@QAf^0P{BjzNizZra( z3$rwpNvWK{xu~a!ykKe<8Ce1iG{;{n=zPY96bUXu;^hY ztH0@pI!pcN8x7%Z&b6@*irsL9<@=mR&g>g+K~xM4`t)R&8+L)}nXZ?6=n>oMru%hFO@#4o2(-8SyB8 zm>6+IgPi3zmnRNQXO6SR*-;dQh&|J7rS z93pDMN`YgX5A>jnG=S>kEkO-&?fX&O%4-&Z?^)5Z*+yJN{C!>;-koPpP%Do=kxq3V zt+TKyA!8Dkr*UzDE8vXEnr~r_i8C{=d*A8!ukg;WDOtQxcgv>XYcMtaLv)ht$|<_< z<#NuMZ902{FO?R#SkhBS+WcM^uG3}r1^=J{T@q-Q!&fR z47v3WR}uJQ4w?7Uoiocfpx;+?hgwl89`&~*Oil$zNqA_7b$R=>7G21u>(}Juaf-e5`|m6Cp2g-bFmA_Ft=RI4t^nbXlR5s#?Iwy+Hg#gS z&#`Aj#G+B+Fo^-1xKtJ++a+cjjDz%?(HlLqO~Os08Ii-0jOd~WnfkjUL~X?I;xB$M zxCh<4g28)RI>E6wQ(;y*f;~4LOCeg>%v=2xo}~KW1UVL1X6F5L!59PtwR^1g{~lWR z!PD(ZvW5o-hZSGNtH>`p__)|pY7moSzxPKsPKVoFnVtbjCI#_us6ZVhQ*C5(vc1u~ zl~x;eSYBNx>gyH|n$zSjq^hs+Ne@j;0!t@d$(D~zUL=f9rPfLB?#2>aCubr91)Z8* z;o8{RHp>=V=lp)hg2`!S~PlDI^%I-~6%>E96+oVqs{-oXr@b+aOP54<>GokKp{ zrw1Ps;)Xt;0<0a!w2mSyMy-mNWNIGsomj*Xff{=7-Z+w@)ax-(#t=hqD|cAz=%x7d zbnq{D(UTBi@1<_xY$?%xZmM$^*N@0@^2!V5$ZN%w49VC+7fEZ|{gLZGXp!tvd)UMG%v()IsmwwWu4E%a$=$HW?;%DQ~e zGseyuwukMnrKBp38FWR3mqbb!6yR?B2Qlcqsp~MDk5vB#PJMC}o$C{GyobaH82RIFvKO zrzxgJsez6$11EVqHCgBr_-EH-Um-ipNaN?36HDdMLM!QwJow^<2NDwy_4kiTa5*cT z(QJ;LF}-Zfj@2UX@qP(e+DwX7SyxItZ8$22a|GH^szYyZ7n;!5)>(*}H4lbSk z*6d|;^mc|!re5J86rk4ObhE@%B;z1ncD6-;NG&jCITE%4XN0Z3{M62_-n7Ut6Po&~Syj%C_h+ZEnlS5JsDsJjinOc$`|x?fqIWKO)-AhMslQWc)_?xG2+uJZS5c?A$5~jUd0W#bW!Z zo~37vNNh3+^U=#tEms)r{WhoC$Y@)ao(ef6jt}j}_$E>?V7hlZ|8-uQBotSf9(+=B#L`7diTej#K~8jf~hvSPfLnt1KV#R;88p61nRz={+n8jtxW)qSVr0ip``Ypn({$g$dbU*^+JW04WP z{4JMk_R)PjR_UQ*8Vgq)lp&O}#V8xk=aiI*6Qt3q67Rkh1NC>ZH?`99qoi-=9$pD5 z+~6zq*i(P^M3vnf=N+(!lJ@9~b7j_DamhjnyGJ zdp{dj7fYsi2NF%E{ezy%Xy>1~l-Rm{rjFnDeJ&Wi0EZj1)In_XOyV1+d1okSf3fjJ5l}KxwcI)` zAadCkL#caXu6i-Wb7?($ZjlCo|m!KN_p`0XF8*)*RZqwO!ZINeFbuVN%rsKaR%S6ZDi+N8vy z?Zfl}{1xtJ74D@Zr$o=%XGJQ0k)4WosypYJLAHJa#&tILqaUx5P=tL*AgHZRRXcB3 zMx-jW211%FNNk!%kFUY%&usS?YN25aT5k>cMGN~u5qQnA4ZpMPZw$0h&f0qbpJS*f zh-MI%SPy0&31Qn=Ew~2-sJ0fYXc+W{{>ne AumAu6 literal 0 HcmV?d00001 diff --git a/src/pyqt/Makefile.am b/src/pyqt/Makefile.am new file mode 100644 index 000000000..0799353fa --- /dev/null +++ b/src/pyqt/Makefile.am @@ -0,0 +1,3 @@ +include $(top_srcdir)/adm/unix/make_begin.am + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/pyqt/gui/Appli.py b/src/pyqt/gui/Appli.py new file mode 100644 index 000000000..5d1e71bdd --- /dev/null +++ b/src/pyqt/gui/Appli.py @@ -0,0 +1,340 @@ +""" +""" +import sys,os +from qt import * +import Tree +import PanelManager +import Icons +import Items +import adapt +import Item +import pilot +import threading +import time + +class Browser(QVBox): + def __init__(self,parent,proc): + QVBox.__init__(self,parent) + self.hSplitter = QSplitter(self,"hSplitter") + self.objectBrowser=Tree.Tree(self.hSplitter,self.onSelect) + pp=adapt.adapt(proc,Item.Item) + self.proc=proc + self.pproc=pp + self.objectBrowser.additem(pp) + self.panelManager=PanelManager.PanelManager(self.hSplitter) + self.executor=None + self.resume=0 + self.thr=None + + def onSelect(self,item): + #item is instance of Item.Item + self.selected=item + self.panelManager.setview(item) + + def run(self): + if not self.executor: + self.executor = pilot.ExecutorSwig() + if self.thr and self.thr.isAlive(): + return + #step by step execution mode + self.executor.setExecMode(1) + #execute it in a thread + self.thr = threading.Thread(target=self.executor.RunW, args=(self.proc,0)) + #as a daemon (no need to join) + self.thr.setDaemon(1) + #start the thread + self.thr.start() + self.resume=1 + #wait pause + time.sleep(0.1) + self.executor.waitPause() + #switch to continue execution mode + self.executor.setExecMode(0) + #resume it + self.executor.resumeCurrentBreakPoint() + self.resume=0 + + def susp(self): + """Suspend or resume an executing schema""" + if not self.executor: + return + if not self.thr.isAlive(): + return + + if self.resume: + #continue execution mode + self.executor.setExecMode(0) + #if finished stop it + #resume it + self.executor.resumeCurrentBreakPoint() + self.resume=0 + else: + #step by step execution mode + self.executor.setExecMode(1) + #self.executor.waitPause() + self.resume=1 + + def step(self): + """Step on a paused schema""" + if not self.executor: + self.executor = pilot.ExecutorSwig() + if not self.thr or not self.thr.isAlive(): + #start in step by step mode + self.executor.setExecMode(1) + self.thr = threading.Thread(target=self.executor.RunW, args=(self.proc,0)) + self.thr.setDaemon(1) + self.thr.start() + self.resume=1 + return + + #step by step execution mode + self.resume=1 + self.executor.setExecMode(1) + #if finished stop it + #resume it + self.executor.resumeCurrentBreakPoint() + + def stop(self): + """Stop the schema""" + if not self.executor: + return + if not self.thr.isAlive(): + return + self.executor.setExecMode(1) + self.executor.waitPause() + self.executor.resumeCurrentBreakPoint() + #self.executor.stopExecution() + +class Appli(QMainWindow): + """ + Appli() + Cree la fenetre principale de l'interface utilisateur + """ + def __init__(self): + QMainWindow.__init__(self) + self.createWidgets() + self.initActions() + self.initMenus() + self.initToolbar() + self.initStatusbar() + self.initYACS() + + def createWidgets(self): + self.tabWidget = QTabWidget(self) + self.currentPanel=None + self.connect(self.tabWidget, SIGNAL('currentChanged(QWidget *)'),self.handlePanelChanged) + self.setCentralWidget(self.tabWidget) + self.resize(800,600) + + def handlePanelChanged(self,panel): + self.currentPanel=panel + + def initActions(self): + self.actions = [] + + self.newAct=QAction('New', QIconSet(Icons.get_image("new")), '&New', + QKeySequence("CTRL+N"),self) + self.newAct.setStatusTip('Open an empty editor window') + self.newAct.setWhatsThis( """New""" + """

An empty editor window will be created.

""") + self.newAct.connect(self.newAct,SIGNAL('activated()'), self.handleFile) + self.actions.append(self.newAct) + + self.prefAct=QAction('Preferences',QIconSet(Icons.get_image("configure.png")),'&Preferences...', + 0, self) + self.prefAct.setStatusTip('Set the prefered configuration') + self.prefAct.setWhatsThis("""Preferences""" + """

Set the configuration items of the application""" + """ with your prefered values.

""") + self.prefAct.connect(self.prefAct,SIGNAL('activated()'), self.handlePreferences) + self.actions.append(self.prefAct) + + self.runAct=QAction('Run',QIconSet(Icons.get_image("run.png")),'&Run',0,self) + self.runAct.connect(self.runAct,SIGNAL('activated()'), self.run) + self.runAct.setStatusTip('Run the selected schema') + self.actions.append(self.runAct) + + self.suspAct=QAction('Suspend/resume',QIconSet(Icons.get_image("suspend-resume.gif")),'&Suspend/resume',0,self) + self.suspAct.connect(self.suspAct,SIGNAL('activated()'), self.susp) + self.suspAct.setStatusTip('Suspend/resume the selected schema') + self.actions.append(self.suspAct) + + self.stepAct=QAction('Step',QIconSet(Icons.get_image("steps.png")),'&Step',0,self) + self.stepAct.connect(self.stepAct,SIGNAL('activated()'), self.step) + self.stepAct.setStatusTip('Step the selected schema') + self.actions.append(self.stepAct) + + self.stopAct=QAction('Stop',QIconSet(Icons.get_image("kill.png")),'&Stop',0,self) + self.stopAct.connect(self.stopAct,SIGNAL('activated()'), self.stop) + self.stopAct.setStatusTip('Stop the selected schema') + self.actions.append(self.stopAct) + + def initMenus(self): + menubar = self.menuBar() + + #menu file + self.fileMenu=QPopupMenu(self) + self.newAct.addTo(self.fileMenu) + self.fileMenu.insertItem("&Open", self.openFile) + self.fileMenu.insertItem("&Open Salome", self.openSalomeFile) + menubar.insertItem('&File',self.fileMenu) + + #menu settings + self.settingsMenu = QPopupMenu(self) + menubar.insertItem('&Settings', self.settingsMenu) + self.settingsMenu.insertTearOffHandle() + self.prefAct.addTo(self.settingsMenu) + + #menu Edit + self.editMenu = QPopupMenu(self) + self.editMenu.insertItem("&Add node", self.addNode) + menubar.insertItem('&Edit', self.editMenu) + + #menu Canvas + #sous menu layout + self.layoutMenu = QPopupMenu(self) + self.layoutMenu.insertItem("&Left Right", self.LR) + self.canvasMenu = QPopupMenu(self) + self.canvasMenu.insertItem("&Zoom in", self.zoomIn) + self.canvasMenu.insertItem("Zoom &out", self.zoomOut) + self.canvasMenu.insertItem("Layout", self.layoutMenu) + self.canvasMenu.insertItem("&Update", self.updateCanvas) + menubar.insertItem('&Canvas', self.canvasMenu) + + #menu window + self.windowMenu = QPopupMenu(self) + menubar.insertItem('&Window', self.windowMenu) + self.connect(self.windowMenu, SIGNAL('aboutToShow()'), self.handleWindowMenu) + + #menu help + self.help=QPopupMenu(self) + menubar.insertItem('&Help',self.help) + self.help.insertItem('&About',self.about,Qt.Key_F1) + self.help.insertItem('About &Qt',self.aboutQt) + + def initYACS(self): + import pilot + import loader + import salomeloader + self.runtime= pilot.getRuntime() + self.loader = loader.YACSLoader() + self.executor = pilot.ExecutorSwig() + self.salomeloader=salomeloader.SalomeLoader() + + def openSalomeFile(self): + fn = QFileDialog.getOpenFileName(QString.null,QString.null,self) + if fn.isEmpty(): + self.statusBar().message('Loading aborted',2000) + return + fileName = str(fn) + proc=self.salomeloader.load(fileName) + + panel=Browser(self.tabWidget,proc) + self.currentPanel=panel + self.tabWidget.addTab( panel,os.path.basename(fileName)) + self.tabWidget.showPage(panel) + + def openFile(self): + fn = QFileDialog.getOpenFileName(QString.null,QString.null,self) + if fn.isEmpty(): + self.statusBar().message('Loading aborted',2000) + return + fileName = str(fn) + proc=self.loader.load(fileName) + + panel=Browser(self.tabWidget,proc) + self.currentPanel=panel + self.tabWidget.addTab( panel,os.path.basename(fileName)) + self.tabWidget.showPage(panel) + + def LR(self): + if self.currentPanel.selected and isinstance(self.currentPanel.selected,Items.ItemComposedNode): + self.currentPanel.selected.layout("LR") + + def updateCanvas(self): + if self.currentPanel.selected:#item selected + if isinstance(self.currentPanel.selected,Items.ItemComposedNode): + #on peut updater + self.currentPanel.selected.editor.updateCanvas() + + def addNode(self): + if self.currentPanel.selected:#item selected + if isinstance(self.currentPanel.selected,Items.ItemComposedNode): + #on peut ajouter un noeud + self.currentPanel.selected.addNode() + + def zoomIn(self): + if self.currentPanel.selected:#item selected + if isinstance(self.currentPanel.selected,Items.ItemComposedNode): + #on peut zoomer + self.currentPanel.selected.editor.zoomIn() + + def zoomOut(self): + if self.currentPanel.selected:#item selected + if isinstance(self.currentPanel.selected,Items.ItemComposedNode): + #on peut dezoomer + self.currentPanel.selected.editor.zoomOut() + + def handleFile(self): + pass + + def handlePreferences(self): + pass + + def handleWindowMenu(self): + pass + + def about(self): + QMessageBox.about(self,'YACS browser GUI', 'YACS browser GUI') + + def aboutQt(self): + QMessageBox.aboutQt(self,'YACS browser GUI') + + def run(self): + if self.currentPanel: + self.currentPanel.run() + + def susp(self): + if self.currentPanel: + self.currentPanel.susp() + + def step(self): + if self.currentPanel: + self.currentPanel.step() + + def stop(self): + if self.currentPanel: + self.currentPanel.stop() + + def initToolbar(self): + tb = QToolBar(self) + self.newAct.addTo(tb) + self.runAct.addTo(tb) + self.suspAct.addTo(tb) + self.stepAct.addTo(tb) + self.stopAct.addTo(tb) + self.toolbars={} + self.toolbars['File']=tb + + def initStatusbar(self): + sb = self.statusBar() + self.SBfile=QLabel(sb) + sb.addWidget(self.SBfile) + QWhatsThis.add(self.SBfile, + """

Partie de la statusbar qui donne le nom""" + """du fichier courant.

""") + self.SBfile.setText("") + + +if __name__ == "__main__": + from Item import Item + app = QApplication(sys.argv) + t=Appli() + t.objectBrowser.additem(Item("item1")) + n=t.objectBrowser.additem(Item("item2")) + n.additem(Item("item3")) + app.setMainWidget(t) + t.show() + app.exec_loop() + + diff --git a/src/pyqt/gui/CItems.py b/src/pyqt/gui/CItems.py new file mode 100644 index 000000000..4e9f79be3 --- /dev/null +++ b/src/pyqt/gui/CItems.py @@ -0,0 +1,493 @@ + +import sys,traceback +from qt import * +from qtcanvas import * +import pilot +dispatcher=pilot.Dispatcher.getDispatcher() + +class PointItem(QCanvasEllipse): + def __init__(self,obj,x,y,canvas): + """Create a point contained in a composite line (obj)""" + QCanvasEllipse.__init__(self,6,6,canvas) + self.obj=obj + self.inline=None + self.outline=None + self.setPen(QPen(Qt.black)) + self.setBrush(QBrush(Qt.red)) + self.setX(x) + self.setY(y) + self.setVisible(True) + + def setInline(self,inline): + self.inline=inline + if inline.z() >= self.z(): + self.setZ(inline.z()+1) + def setOutline(self,outline): + self.outline=outline + if outline.z() >= self.z(): + self.setZ(outline.z()+1) + + def moveBy(self,dx,dy): + """Request the point move by x,y""" + self.myMove(dx,dy) + + def myMove(self,dx,dy): + """The real move""" + QCanvasEllipse.moveBy(self,dx,dy) + if self.outline: + self.outline.setFromPoint( int(self.x()), int(self.y()) ) + if self.inline: + self.inline.setToPoint( int(self.x()), int(self.y()) ) + + def getObj(self): + """The object which contains the point""" + return self.obj + + def handleDoubleClick(self,pos): + self.obj.deletePoint(self,pos) + #def __del__(self): + # print "PointItem.__del__" + def clear(self): + """To remove from canvas""" + self.setCanvas(None) + self.obj=None + self.inline=None + self.outline=None + +class LineItem(QCanvasLine): + """A line between 2 points""" + def __init__(self,obj,fromPoint, toPoint,canvas): + QCanvasLine.__init__(self,canvas) + self.obj=obj + self.fromPoint=fromPoint + self.toPoint=toPoint + self.setPen(QPen(Qt.black)) + self.setBrush(QBrush(Qt.red)) + self.setPoints(int(fromPoint.x()),int(fromPoint.y()), int(toPoint.x()), int(toPoint.y())) + self.setZ(min(fromPoint.z(),toPoint.z())-1) + self.setVisible(True) + + def setFromPoint(self,x,y): + self.setPoints(x,y,self.endPoint().x(),self.endPoint().y()) + def setToPoint(self,x,y): + self.setPoints(self.startPoint().x(), self.startPoint().y(),x,y) + def moveBy(self,dx,dy): + """Disable line move""" + pass + + def getObj(self): + """The object which contains the line""" + return self.obj + def handleDoubleClick(self,pos): + #split the line + self.obj.splitline(self,pos) + #def __del__(self): + # print "LineItem.__del__" + def clear(self): + """To remove from canvas""" + self.setCanvas(None) + self.fromPoint=None + self.toPoint=None + self.obj=None + +class LinkItem: + def __init__(self,fromPort, toPort,canvas): + self.fromPort=fromPort + self.toPort=toPort + self.canvas=canvas + fromPort.addOutLink(self) + toPort.addInLink(self) + self.lines=[] + self.points=[] + self.lines.append(LineItem(self,fromPort, toPort,canvas)) + + def deletePoint(self,point,pos): + """Delete intermediate point""" + if point not in self.points: + return + self.points.remove(point) + inline=point.inline + outline=point.outline + inline.toPoint=outline.toPoint + inline.setToPoint(outline.toPoint.x(),outline.toPoint.y()) + self.lines.remove(outline) + if inline.toPoint in self.points: + inline.toPoint.setInline(inline) + #remove from canvas + point.clear() + outline.clear() + + def splitline(self,line,pos): + """Split line at position pos""" + #The new point + point=PointItem(self,pos.x(),pos.y(),self.canvas) + self.points.append(point) + i=self.lines.index(line) + + newline=LineItem(self,point,line.toPoint,self.canvas) + if line.toPoint in self.points: + #line not connected to port : reconnect newline + line.toPoint.setInline(newline) + self.lines.insert(i+1,newline) + + line.setToPoint(pos.x(),pos.y()) + line.toPoint=point + point.setInline(line) + point.setOutline(newline) + + def setFromPoint(self,x,y): + first=self.lines[0] + first.setFromPoint(x,y) + + def setToPoint(self,x,y): + last=self.lines[-1] + last.setToPoint(x,y) + + def moveBy(self,dx,dy): + pass + + def popup(self,canvasView): + menu=QPopupMenu() + caption = QLabel( "Link Menu",menu ) + caption.setAlignment( Qt.AlignCenter ) + menu.insertItem( caption ) + menu.insertItem("Delete", self.delete) + return menu + + def delete(self): + print "delete link" + + def tooltip(self,view,pos): + r = QRect(pos.x(), pos.y(), pos.x()+10, pos.y()+10) + s = QString( "link: "+self.fromPort.port.getNode().getName() +":"+self.fromPort.port.getName()+"->"+self.toPort.port.getNode().getName()+":"+self.toPort.port.getName() ) + view.tip( r, s ) + #QToolTip(view).tip( r, s ) + +class ControlLinkItem(LinkItem): + def tooltip(self,view,pos): + r = QRect(pos.x(), pos.y(), pos.x()+10, pos.y()+10) + s = QString( "link: "+self.fromPort.port.getNode().getName()+"->"+self.toPort.port.getNode().getName()) + view.tip( r, s ) + #QToolTip(view).tip( r, s ) + +class ControlItem(QCanvasRectangle): + def __init__(self,node,port,canvas): + QCanvasRectangle.__init__(self,canvas) + self.setSize(6,6) + self.port=port + self.setPen(QPen(Qt.black)) + self.setBrush(QBrush(Qt.red)) + self.setZ(node.z()+1) + self.node=node + def moveBy(self,dx,dy): + self.node.moveBy(dx,dy) + def myMove(self,dx,dy): + QCanvasRectangle.moveBy(self,dx,dy) + def getObj(self): + return self + def popup(self,canvasView): + self.context=canvasView + menu=QPopupMenu() + caption = QLabel( "Port Menu",menu ) + caption.setAlignment( Qt.AlignCenter ) + menu.insertItem( caption ) + menu.insertItem("Connect", self.connect) + return menu + def connect(self): + print "connect",self.context + self.context.connecting(self) + def link(self,obj): + print "link:",obj + def tooltip(self,view,pos): + r = QRect(pos.x(), pos.y(), self.width(), self.height()) + s = QString( "gate:") + view.tip( r, s ) + #QToolTip(view).tip( r, s ) + +class InControlItem(ControlItem): + def __init__(self,node,port,canvas): + ControlItem.__init__(self,node,port,canvas) + self.__inList=[] + + def myMove(self,dx,dy): + ControlItem.myMove(self,dx,dy) + for link in self.__inList: + link.setToPoint( int(self.x()), int(self.y()) ) + + def link(self,obj): + print "link:",obj + if isinstance(obj,OutControlItem): + #Connection possible + l=LinkItem(obj,self,self.canvas()) + + def addInLink(self,link): + self.__inList.append(link) + + def tooltip(self,view,pos): + r = QRect(pos.x(), pos.y(), self.width(), self.height()) + s = QString( "ingate:") + view.tip( r, s ) + #QToolTip(view).tip( r, s ) + +class OutControlItem(ControlItem): + def __init__(self,node,port,canvas): + ControlItem.__init__(self,node,port,canvas) + self.__outList=[] + + def myMove(self,dx,dy): + ControlItem.myMove(self,dx,dy) + for link in self.__outList: + link.setFromPoint( int(self.x()), int(self.y()) ) + + def link(self,obj): + print "link:",obj + if isinstance(obj,InControlItem): + #Connection possible + l=LinkItem(self,obj,self.canvas()) + + def addOutLink(self,link): + self.__outList.append(link) + + def tooltip(self,view,pos): + r = QRect(pos.x(), pos.y(), self.width(), self.height()) + s = QString( "outgate:") + view.tip( r, s ) + #QToolTip(view).tip( r, s ) + +class PortItem(QCanvasEllipse): + def __init__(self,node,port,canvas): + QCanvasEllipse.__init__(self,6,6,canvas) + self.port=port + self.setPen(QPen(Qt.black)) + self.setBrush(QBrush(Qt.red)) + self.setZ(node.z()+1) + self.node=node + + def moveBy(self,dx,dy): + self.node.moveBy(dx,dy) + + def myMove(self,dx,dy): + QCanvasEllipse.moveBy(self,dx,dy) + + def getObj(self): + return self + + def popup(self,canvasView): + self.context=canvasView + menu=QPopupMenu() + caption = QLabel( "Port Menu",menu ) + caption.setAlignment( Qt.AlignCenter ) + menu.insertItem( caption ) + menu.insertItem("Connect", self.connect) + return menu + + def connect(self): + print "connect",self.context + self.context.connecting(self) + + def link(self,obj): + print "link:",obj + + def tooltip(self,view,pos): + r = QRect(pos.x(),pos.y(),self.width(), self.height()) + t=self.port.edGetType() + s = QString( "port: " + self.port.getName() + ":" + t.name()) + view.tip( r, s ) + #QToolTip(view).tip( r, s ) + +class InPortItem(PortItem): + def __init__(self,node,port,canvas): + PortItem.__init__(self,node,port,canvas) + self.__inList=[] + + def myMove(self,dx,dy): + PortItem.myMove(self,dx,dy) + for link in self.__inList: + link.setToPoint( int(self.x()), int(self.y()) ) + + def link(self,obj): + print "link:",obj + if isinstance(obj,OutPortItem): + #Connection possible + l=LinkItem(obj,self,self.canvas()) + + def addInLink(self,link): + self.__inList.append(link) + + + +class OutPortItem(PortItem): + def __init__(self,node,port,canvas): + PortItem.__init__(self,node,port,canvas) + self.__outList=[] + + def myMove(self,dx,dy): + PortItem.myMove(self,dx,dy) + for link in self.__outList: + link.setFromPoint( int(self.x()), int(self.y()) ) + + def link(self,obj): + print "link:",obj + if isinstance(obj,InPortItem): + #Connection possible + l=LinkItem(self,obj,self.canvas()) + + def addOutLink(self,link): + self.__outList.append(link) + +class InStreamItem(InPortItem): + def __init__(self,node,port,canvas): + InPortItem.__init__(self,node,port,canvas) + self.setBrush(QBrush(Qt.green)) + +class OutStreamItem(OutPortItem): + def __init__(self,node,port,canvas): + OutPortItem.__init__(self,node,port,canvas) + self.setBrush(QBrush(Qt.green)) + +class Cell(QCanvasRectangle,pilot.PyObserver): + colors={ + "pink":Qt.cyan, + "green":Qt.green, + "magenta":Qt.magenta, + "purple":Qt.darkMagenta, + "blue":Qt.blue, + "red":Qt.red, + "orange":Qt.yellow, + "grey":Qt.gray, + "white":Qt.white, + } + + def __init__(self,node,canvas): + QCanvasRectangle.__init__(self,canvas) + pilot.PyObserver.__init__(self) + self.setSize(50,50) + #node is an instance of YACS::ENGINE::Node + self.node=node + dispatcher.addObserver(self,node,"status") + self.label=QCanvasText(canvas) + self.label.setText(self.node.getName()) + self.label.setFont(QFont("Helvetica",8)) + rect=self.label.boundingRect() + self.label.setX(self.x()+self.width()/2-rect.width()/2) + self.label.setY(self.y()+self.height()/2-rect.height()/2) + self.label.setZ(self.z()+1) + color= self.colors.get(node.getColorState(node.getEffectiveState()),Qt.white) + self.setBrush(QBrush(color)) + + self.inports=[] + self.outports=[] + + liste= self.node.getSetOfInputPort() + dy=6 + y=0 + for inport in self.node.getSetOfInputPort(): + p=InPortItem(self,inport,canvas) + y=y+dy + p.myMove(0,y) + self.inports.append(p) + + for instream in self.node.getSetOfInputDataStreamPort(): + p=InStreamItem(self,instream,canvas) + y=y+dy + p.myMove(0,y) + self.inports.append(p) + + ymax=y + + liste= self.node.getSetOfOutputPort() + dy=6 + y=0 + for outport in self.node.getSetOfOutputPort(): + p=OutPortItem(self,outport,canvas) + y=y+dy + p.myMove(50,y) + self.outports.append(p) + + for outstream in self.node.getSetOfOutputDataStreamPort(): + p=OutStreamItem(self,outstream,canvas) + y=y+dy + p.myMove(50,y) + self.outports.append(p) + + ymax=max(y,ymax) + + #Control ports + y=ymax+dy + if y < 44:y=44 + p=InControlItem(self,self.node.getInGate(),canvas) + p.myMove(0,y) + self.inports.append(p) + self.ingate=p + p=OutControlItem(self,self.node.getOutGate(),canvas) + p.myMove(44,y) + self.outports.append(p) + self.outgate=p + y=y+dy + self.setSize(50,y) + + + events={ + "status":QEvent.User+1, + } + + def pynotify(self,object,event): + #print "pynotify",event,object + try: + evType=self.events[event] + ev=QCustomEvent(evType) + ev.setData(self) + ev.yacsEvent=event + QApplication.postEvent(self.canvas(), ev) + #request immediate processing (deadlock risk ???) + #QApplication.sendPostedEvents(self.canvas(), evType) + #print "pynotify end" + except: + #traceback.print_exc() + raise + + def customEvent(self,event): + if event.yacsEvent=="status": + object=self.node + state=object.getEffectiveState() + color=object.getColorState(state) + color= self.colors.get(color,Qt.white) + self.setBrush(QBrush(color)) + else: + print "Unknown custom event type:", event.type() + + def moveBy(self,dx,dy): + QCanvasRectangle.moveBy(self,dx,dy) + self.label.moveBy(dx,dy) + for p in self.inports: + p.myMove(dx,dy) + for p in self.outports: + p.myMove(dx,dy) + + def show(self): + QCanvasRectangle.show(self) + self.label.show() + for p in self.inports: + p.show() + for p in self.outports: + p.show() + + def getObj(self): + return self + + def popup(self,canvasView): + menu=QPopupMenu() + caption = QLabel( "Node Menu",menu ) + caption.setAlignment( Qt.AlignCenter ) + menu.insertItem( caption ) + menu.insertItem("Browse", self.browse) + return menu + + def tooltip(self,view,pos): + r = QRect(pos.x(), pos.y(), self.width(), self.height()) + s = QString( "node: " + self.node.getName()) + view.tip( r, s ) + #QToolTip(view).tip( r, s ) + + def browse(self): + print "browse" diff --git a/src/pyqt/gui/Editor.py b/src/pyqt/gui/Editor.py new file mode 100644 index 000000000..0d7116990 --- /dev/null +++ b/src/pyqt/gui/Editor.py @@ -0,0 +1,19 @@ + +from qt import QSizePolicy,QMultiLineEdit +try: + from qtext import QextScintilla,QextScintillaLexerPython + + class Editor(QextScintilla): + def __init__(self, parent=None, name=None, flags=0): + QextScintilla.__init__(self, parent, name, flags) + self.lexer=QextScintillaLexerPython(self) + self.setLexer(self.lexer) + self.lexer.setIndentationWarning(QextScintillaLexerPython.Inconsistent) + #self.lexer.setAutoIndentStyle(0) + self.lexer.setAutoIndentStyle(QextScintilla.AiMaintain) + self.setAutoIndent(1) + self.setBraceMatching(QextScintilla.SloppyBraceMatch) + self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)) +except: + Editor=QMultiLineEdit + diff --git a/src/pyqt/gui/GraphViewer.py b/src/pyqt/gui/GraphViewer.py new file mode 100644 index 000000000..4d78cc9ec --- /dev/null +++ b/src/pyqt/gui/GraphViewer.py @@ -0,0 +1,387 @@ + +import sys +from qt import * +from qtcanvas import * + +class DynamicTip( QToolTip ): + def __init__( self, parent ): + QToolTip.__init__( self, parent ) + + def maybeTip( self, pos ): + pos2=self.parentWidget().viewportToContents(pos) + point = self.parentWidget().inverseWorldMatrix().map(pos2) + ilist = self.parentWidget().canvas().collisions(point) #QCanvasItemList ilist + for each_item in ilist: + if hasattr(each_item,"tooltip"): + each_item.tooltip(self,pos) + return + elif hasattr(each_item,"getObj"): + each_item.getObj().tooltip(self,pos) + return + +class GraphViewer(QCanvasView): + def __init__(self,item,c,parent,name,f): + QCanvasView.__init__(self,c,parent,name,f) + self.item=item + self.__moving=0 + self.__connecting=0 + self.__moving_start= 0 + self.tooltip = DynamicTip( self ) + + def contentsMouseDoubleClickEvent(self,e): # QMouseEvent e + point = self.inverseWorldMatrix().map(e.pos()) + ilist = self.canvas().collisions(point) #QCanvasItemList ilist + for each_item in ilist: + if each_item.rtti()==984376: + if not each_item.hit(point): + continue + if e.button()== Qt.LeftButton: + if hasattr(each_item,"handleDoubleClick"): + each_item.handleDoubleClick(point) + self.canvas().update() + return + + + def contentsMousePressEvent(self,e): # QMouseEvent e + p=e.globalPos() + point = self.inverseWorldMatrix().map(e.pos()) + ilist = self.canvas().collisions(point) #QCanvasItemList ilist + for each_item in ilist: + if each_item.rtti()==984376: + if not each_item.hit(point): + continue + if e.button()== Qt.RightButton: + self.__moving=0 + self.__connecting=0 + if hasattr(each_item,"popup"): + menu=each_item.popup(self) + if menu: + menu.exec_loop( QCursor.pos() ) + self.canvas().update() + elif hasattr(each_item,"getObj"): + menu=each_item.getObj().popup(self) + if menu: + menu.exec_loop( QCursor.pos() ) + self.canvas().update() + elif e.button()== Qt.LeftButton: + if self.__connecting: + if hasattr(each_item,"getObj"): + #a connection is ending + self.__connecting.link(each_item.getObj()) + self.canvas().update() + self.__connecting=0 + else: + self.__moving=each_item + self.__moving_start=point + return + if e.button()== Qt.RightButton: + menu=self.popup() + if menu: + menu.exec_loop( QCursor.pos() ) + self.canvas().update() + self.__moving=0 + self.__connecting=0 + QCanvasView.contentsMousePressEvent(self,e) + + def popup(self): + menu=QPopupMenu() + caption = QLabel( "View Menu", self ) + caption.setAlignment( Qt.AlignCenter ) + menu.insertItem( caption ) + menu.insertItem("add Node", self.addNode) + return menu + + def layout(self,rankdir): + print rankdir + + def updateCanvas(self): + #Par defaut, Qt n'efface pas le background. Seul repaintContents + #semble le faire. Utile apres un popup ou un resize avec scrollbars + #Peut-on l'utiliser partout ? Pb de performance ? + self.repaintContents(True) + #self.canvas().update() + + def addNode(self): + self.item.addNode() + + def zoomIn(self): + m = self.worldMatrix() + m.scale( 2.0, 2.0 ) + self.setWorldMatrix( m ) + + def zoomOut(self): + m = self.worldMatrix() + m.scale( 0.5, 0.5 ) + self.setWorldMatrix( m ) + + def clear(self): + ilist = self.canvas().allItems() + for each_item in ilist: + if each_item: + each_item.setCanvas(None) + del each_item + self.canvas().update() + + def connecting(self,obj): + """Method called by an item to notify canvasView a connection has begun""" + print "connecting",obj + self.__connecting=obj + + def contentsMouseMoveEvent(self,e): + if self.__moving : + point = self.inverseWorldMatrix().map(e.pos()) + self.__moving.moveBy(point.x()-self.__moving_start.x(),point.y()-self.__moving_start.y()) + self.__moving_start = point + self.canvas().update() + else: + #self.tooltip.maybeTip(point) + QCanvasView.contentsMouseMoveEvent(self,e) + +class ImageItem(QCanvasRectangle): + def __init__(self,img,canvas): + QCanvasRectangle.__init__(self,canvas) + + self.imageRTTI=984376 + self.image=img + self.pixmap=QPixmap() + self.setSize(self.image.width(), self.image.height()) + self.pixmap.convertFromImage(self.image, Qt.OrderedAlphaDither); + + def rtti(self): + return self.imageRTTI + + def hit(self,p): + ix = p.x()-self.x() + iy = p.y()-self.y() + if not self.image.valid( ix , iy ): + return False + self.pixel = self.image.pixel( ix, iy ) + return (qAlpha( self.pixel ) != 0) + + def drawShape(self,p): + p.drawPixmap( self.x(), self.y(), self.pixmap ) + + +class NodeItem(QCanvasEllipse): + def __init__(self,canvas): + QCanvasEllipse.__init__(self,6,6,canvas) + self.__inList=[] + self.__outList=[] + self.setPen(QPen(Qt.black)) + self.setBrush(QBrush(Qt.red)) + self.setZ(128) + + def addInEdge(self,edge): + self.__inList.append(edge) + + def addOutEdge(self,edge): + self.__outList.append(edge) + + def moveBy(self,dx,dy): + QCanvasEllipse.moveBy(self,dx,dy) + for each_edge in self.__inList: + each_edge.setToPoint( int(self.x()), int(self.y()) ) + for each_edge in self.__outList: + each_edge.setFromPoint( int(self.x()), int(self.y()) ) + +class EdgeItem(QCanvasLine): + __c=0 + def __init__(self,fromNode, toNode,canvas): + QCanvasLine.__init__(self,canvas) + self.__c=self.__c+1 + self.setPen(QPen(Qt.black)) + self.setBrush(QBrush(Qt.red)) + fromNode.addOutEdge(self) + toNode.addInEdge(self) + self.setPoints(int(fromNode.x()),int(fromNode.y()), int(toNode.x()), int(toNode.y())) + self.setZ(127) + + def setFromPoint(self,x,y): + self.setPoints(x,y,self.endPoint().x(),self.endPoint().y()) + + def setToPoint(self,x,y): + self.setPoints(self.startPoint().x(), self.startPoint().y(),x,y) + + def count(self): + return self.__c + + def moveBy(self,dx,dy): + pass + +class LinkItem(QCanvasLine): + def __init__(self,fromPort, toPort,canvas): + QCanvasLine.__init__(self,canvas) + self.setPen(QPen(Qt.black)) + self.setBrush(QBrush(Qt.red)) + fromPort.addOutLink(self) + toPort.addInLink(self) + self.setPoints(int(fromPort.x()),int(fromPort.y()), int(toPort.x()), int(toPort.y())) + self.setZ(min(fromPort.z(),toPort.z())-1) + self.setVisible(True) + + def setFromPoint(self,x,y): + self.setPoints(x,y,self.endPoint().x(),self.endPoint().y()) + + def setToPoint(self,x,y): + self.setPoints(self.startPoint().x(), self.startPoint().y(),x,y) + + def moveBy(self,dx,dy): + pass + + def popup(self,canvasView): + menu=QPopupMenu() + caption = QLabel( "Node Menu",menu ) + caption.setAlignment( Qt.AlignCenter ) + menu.insertItem( caption ) + menu.insertItem("Delete", self.delete) + return menu + + def delete(self): + print "delete link" + + def tooltip(self,view,pos): + r = QRect(pos.x(), pos.y(), pos.x()+10, pos.y()+10) + s = QString( "link: %d,%d" % (r.center().x(), r.center().y()) ) + QToolTip(view).tip( r, s ) + +class PortItem(QCanvasEllipse): + def __init__(self,node,canvas): + QCanvasEllipse.__init__(self,6,6,canvas) + self.setPen(QPen(Qt.black)) + self.setBrush(QBrush(Qt.red)) + self.setZ(node.z()+1) + self.node=node + + def moveBy(self,dx,dy): + self.node.moveBy(dx,dy) + + def myMove(self,dx,dy): + QCanvasEllipse.moveBy(self,dx,dy) + + def getObj(self): + return self + + def popup(self,canvasView): + self.context=canvasView + menu=QPopupMenu() + caption = QLabel( "Port Menu",menu ) + caption.setAlignment( Qt.AlignCenter ) + menu.insertItem( caption ) + menu.insertItem("Connect", self.connect) + return menu + + def connect(self): + print "connect",self.context + self.context.connecting(self) + + def link(self,obj): + print "link:",obj + + def tooltip(self,view,pos): + r = QRect(self.x(), self.y(), self.width(), self.height()) + s = QString( "port: %d,%d" % (r.center().x(), r.center().y()) ) + QToolTip(view).tip( r, s ) + +class InPortItem(PortItem): + def __init__(self,node,canvas): + PortItem.__init__(self,node,canvas) + self.__inList=[] + + def myMove(self,dx,dy): + PortItem.myMove(self,dx,dy) + for link in self.__inList: + link.setToPoint( int(self.x()), int(self.y()) ) + + def link(self,obj): + print "link:",obj + if isinstance(obj,OutPortItem): + #Connection possible + l=LinkItem(obj,self,self.canvas()) + + def addInLink(self,link): + self.__inList.append(link) + +class OutPortItem(PortItem): + def __init__(self,node,canvas): + PortItem.__init__(self,node,canvas) + self.__outList=[] + + def myMove(self,dx,dy): + PortItem.myMove(self,dx,dy) + for link in self.__outList: + link.setFromPoint( int(self.x()), int(self.y()) ) + + def link(self,obj): + print "link:",obj + if isinstance(obj,InPortItem): + #Connection possible + l=LinkItem(self,obj,self.canvas()) + + def addOutLink(self,link): + self.__outList.append(link) + +class Cell(QCanvasRectangle): + def __init__(self,canvas): + QCanvasRectangle.__init__(self,canvas) + self.setSize(50,50) + + self.inports=[] + self.outports=[] + + p=InPortItem(self,canvas) + p.myMove(0,25) + self.inports.append(p) + p=OutPortItem(self,canvas) + p.myMove(50,25) + self.outports.append(p) + + def moveBy(self,dx,dy): + QCanvasRectangle.moveBy(self,dx,dy) + for p in self.inports: + p.myMove(dx,dy) + for p in self.outports: + p.myMove(dx,dy) + + def show(self): + QCanvasRectangle.show(self) + for p in self.inports: + p.show() + for p in self.outports: + p.show() + + def getObj(self): + return self + + def popup(self,canvasView): + menu=QPopupMenu() + caption = QLabel( "Node Menu",menu ) + caption.setAlignment( Qt.AlignCenter ) + menu.insertItem( caption ) + menu.insertItem("Browse", self.browse) + return menu + + def tooltip(self,view,pos): + r = QRect(self.x(), self.y(), self.width(), self.height()) + s = QString( "node: %d,%d" % (r.center().x(), r.center().y()) ) + QToolTip(view).tip( r, s ) + + def browse(self): + print "browse" + +if __name__=='__main__': + app=QApplication(sys.argv) + qvbox=QVBox() + QToolBar(qvbox,"toolbar") + canvas=QCanvas(800,600) + canvas.setAdvancePeriod(30) + m=GraphViewer(canvas,qvbox,"example",0) + for x,y in ((150,150),(150,250)): + c=Cell(canvas) + c.moveBy(x,y) + c.show() + + qApp.setMainWidget(qvbox) + qvbox.show() + app.exec_loop() + + diff --git a/src/pyqt/gui/Icons.py b/src/pyqt/gui/Icons.py new file mode 100644 index 000000000..4b69c9aa1 --- /dev/null +++ b/src/pyqt/gui/Icons.py @@ -0,0 +1,30 @@ +"""Ce module fournit des icones (QPixmap) pour afficher dans l'arbre + Ces icones sont obtenues a partir d'un nom et conservees dans un cache. + La source des icones est soit une string xpm soit un fichier gif ou autre +""" + +import os +from qt import QPixmap +from imagesxpm import dico_xpm + +dico_images={} + +def get_image(name): + if dico_images.has_key(name): + return dico_images[name] + else : + if dico_xpm.has_key(name): + image=QPixmap(dico_xpm[name]) + else: + fic_image = os.path.join(os.path.dirname(__file__),"icons",name) + if not os.path.isfile(fic_image): + file, ext = os.path.splitext(fic_image) + fic_image = file + '.gif' + image = QPixmap(fic_image) + dico_images[name]=image + return image + +def update_cache(): + global dico_images + dico_images={} + diff --git a/src/pyqt/gui/Item.py b/src/pyqt/gui/Item.py new file mode 100644 index 000000000..7ac53357e --- /dev/null +++ b/src/pyqt/gui/Item.py @@ -0,0 +1,31 @@ +import sys +from qt import * + +class Item: + def __init__(self,label): + self.label=label + + def isExpandable(self): + return False + + def getChildren(self): + return [] + + def getIconName(self): + return "python" + + def panel(self,parent): + """Retourne un widget pour browser/editer l'item""" + qvbox=QVBox(parent) + label=QLabel("Default Panel",qvbox) + label.setAlignment( Qt.AlignHCenter | Qt.AlignVCenter ) + return qvbox + + +if __name__ == "__main__": + app = QApplication(sys.argv) + t=Item("label").panel(None) + app.setMainWidget(t) + t.show() + app.exec_loop() + diff --git a/src/pyqt/gui/Items.py b/src/pyqt/gui/Items.py new file mode 100644 index 000000000..bad879226 --- /dev/null +++ b/src/pyqt/gui/Items.py @@ -0,0 +1,577 @@ +import sys +import pilot +import Item +import adapt +from qt import * +from qtcanvas import * +from GraphViewer import GraphViewer +import Editor +import CItems +import pygraphviz +import traceback + + +class DataLinkItem(Item.Item): + def __init__(self,pin,pout): + self.pin=pin + self.pout=pout + self.label= pout.getNode().getName()+":"+pout.getName()+"->"+pin.getNode().getName()+":"+pin.getName() + + def getIconName(self): + return "datalink.png" + +class StreamLinkItem(Item.Item): + def __init__(self,pin,pout): + self.pin=pin + self.pout=pout + self.label= pout.getNode().getName()+":"+pout.getName()+"->"+pin.getNode().getName()+":"+pin.getName() + + def getIconName(self): + return "streamlink.png" + +class ControlLinkItem(Item.Item): + def __init__(self,nodeup,nodedown): + self.nodedown=nodedown + self.nodeup=nodeup + self.label= nodeup.getName()+"->"+nodedown.getName() + + def getIconName(self): + return "controllink.png" + +class ControlLinksItem(Item.Item): + """Item pour les liens controle d'un noeud compose""" + def __init__(self,item): + self.item=item + self.label="Control Links" + def getIconName(self): + return "folder" + def isExpandable(self): + return True + def getChildren(self): + sublist=[] + for n in self.item.node.edGetDirectDescendants(): + for p in n.getOutNodes(): + sublist.append(ControlLinkItem(n,p)) + return sublist + +class DataLinksItem(Item.Item): + """Item pour les liens data d'un noeud compose""" + def __init__(self,item): + self.item=item + self.label="Data Links" + + def getIconName(self): + return "folder" + + def isExpandable(self): + return True + + def getChildren(self): + sublist=[] + for pout,pin in self.item.node.getSetOfInternalLinks(): + if pout.getNode().getFather() != self.item.node and pin.getNode().getFather() != self.item.node: + continue + if isinstance(pin,pilot_InputDataStreamPort): + sublist.append(StreamLinkItem(pin,pout)) + else: + sublist.append(DataLinkItem(pin,pout)) + #for pout,pin in self.item.node.getSetOfLinksLeavingCurrentScope(): + # sublist.append(DataLinkItem(pin,pout)) + #for pin,pout in self.item.node.getSetOfLinksComingInCurrentScope(): + # sublist.append(DataLinkItem(pin,pout)) + return sublist + +class MyCanvas(QCanvas): + def customEvent(self,event): + object=event.data() + object.customEvent(event) + self.update() + +class ItemComposedNode(Item.Item): + """Item pour les noeuds composes""" + n=0 + def __init__(self,node): + #node is an instance of YACS::ENGINE::ComposedNode + self.node=node + self.label=node.getName() + + def isExpandable(self): + return True + + def getChildren(self): + #liste des noeuds fils + liste=self.node.edGetDirectDescendants() + #On les adapte en item avant de les retourner + sublist=[] + for n in liste: + try: + sublist.append(adapt.adapt(n,Item.Item)) + except: + print n + #traceback.print_exc() + raise + sublist.append(DataLinksItem(self)) + sublist.append(ControlLinksItem(self)) + return sublist + + def getIconName(self): + return "green-los" + + def panel(self,parent): + """Retourne un tab widget pour browser/editer la proc""" + tabWidget = QTabWidget( parent ) + for name,method in self.panels: + tabWidget.addTab( method(self,tabWidget), name ) + return tabWidget + + def addNode(self): + r=pilot.getRuntime() + ItemComposedNode.n=ItemComposedNode.n+1 + n1=r.createScriptNode("","unknown_%d" % ItemComposedNode.n) + node=CItems.Cell(n1,self.canvas) + node.show() + self.citems[n1.ptr()]=node + self.canvas.update() + + def panel1(self,parent): + qvbox=QVBox(parent) + #Canvas size : 10000x10000 + self.canvas=MyCanvas(10000,10000) + self.editor=GraphViewer(self,self.canvas,qvbox,"example",0) + + #permet de retrouver un item node dans le canvas a partir + #d'un proxy swig quelconque (astuce) + #Pour retrouver un item node faire : citems[node.ptr()] + citems={} + self.citems=citems + #permet de retrouver un item port dans le canvas a partir + #d'un proxy swig quelconque (astuce) + #Pour retrouver un item port faire : pitems[port.ptr()] + pitems={} + #self.pitems=pitems + + y=0 + lnode=self.node.edGetDirectDescendants() + for n in lnode: + c=CItems.Cell(n,self.canvas) + citems[n.ptr()]=c + c.show() + + for k,n in citems.items(): + for p in n.inports: + pitems[p.port.ptr()]=p + for p in n.outports: + pitems[p.port.ptr()]=p + + for pout,pin in self.node.getSetOfInternalLinks(): + if pout.getNode().getFather() != self.node and pin.getNode().getFather() != self.node: + continue + po=pitems.get(pout.ptr()) + pi=pitems.get(pin.ptr()) + if pi and po: + CItems.LinkItem(po,pi,self.canvas) + + for n in lnode: + itemup=citems[n.ptr()] + for ndown in n.getOutNodes(): + itemdown=citems[ndown.ptr()] + CItems.ControlLinkItem(itemup.outgate,itemdown.ingate,self.canvas) + + self.layout("LR") + + return qvbox + + panels=[("Panel1",panel1)] + + def layout(self,rankdir): + """Compute graph layout with graphviz package""" + G=pygraphviz.AGraph(strict=False,directed=True) + G.graph_attr["rankdir"]=rankdir + for k,n in self.citems.items(): + #k est l'adresse du node (YACS) + #n est l'item dans le canvas + G.add_node(k) + + for pout,pin in self.node.getSetOfInternalLinks(): + if pout.getNode().ptr() not in self.citems : + continue + if pin.getNode().ptr() not in self.citems: + continue + G.add_edge(pout.getNode().ptr(),pin.getNode().ptr()) + + for k,n in self.citems.items(): + for ndown in n.node.getOutNodes(): + G.add_edge(n.node.ptr(),ndown.ptr()) + + #By default graphviz uses 96.0 pixel per inch (dpi=96.0) + for n in G.nodes(): + item=self.citems[int(n)] + h=item.height()/96. #height in inch + w=item.width()/96. #width in inch + n.attr['height']=str(h) + n.attr['width']=str(w) + n.attr['fixedsize']="true" + n.attr['shape']="box" + #n.attr['label']=item.node.getName() + + G.layout(prog='dot') # use dot + #G.write("layout.dot") + #G.draw("layout.png") + + #from pygraphviz import graphviz as gv + #bbox= gv.agget(G.handle,"bb")#bounding box to resize + #x1,y1,x2,y2=eval(bbox) + #self.canvas.resize(w,h) + + for n in G: + pos=n.attr['pos'] #position is given in points (72 points par inch, so 1 point = 96./72=1.34) + x,y=eval(pos) + x=96./72*x+10 + y=96./72*y+10 + item=self.citems[int(n)] + # x0=item.x()+item.width()/2. + # y0=item.y()+item.height()/2. + x0=item.x() + y0=item.y() + x=x-x0 + y=y-y0 + item.moveBy(x,y) + + self.canvas.update() + +class ItemProc(ItemComposedNode): + """Item pour la procedure""" + +class ItemPort(Item.Item): + """Item pour les ports """ + panels=[] + def __init__(self,port): + self.port=port + self.label=port.getName() + + def getIconName(self): + return "port.png" + + def panel(self,parent): + """Retourne un tab widget pour browser/editer l'item""" + tabWidget = QTabWidget( parent ) + for name,method in self.panels: + tabWidget.addTab( method(self,tabWidget), name ) + return tabWidget + +class ItemInPort(ItemPort): + def getIconName(self): + return "inport.png" + + def panel1(self,parent): + qvbox=QVBox(parent) + qvbox.layout().setAlignment(Qt.AlignTop|Qt.AlignLeft) + qvbox.setSpacing( 5 ) + row0=QHBox(qvbox) + label=QLabel("Name: ",row0) + lined0 = QLineEdit(self.port.getName(),row0) + label=QLabel("Type: ",row0) + QLineEdit(self.port.edGetType().name(),row0) + + label=QLabel("Value: ",qvbox) + #self.value=QLabel("Empty",qvbox) + self.value=QTextEdit(qvbox) + self.value.setText("Empty") + if not self.port.isEmpty(): + self.value.setText(self.port.dump()) + + row3=QHBox(qvbox) + but2=QPushButton( "Refresh", row3 ) + qvbox.connect( but2, SIGNAL("clicked()"), self.handleRefresh ) + + return qvbox + + def handleRefresh(self): + if not self.port.isEmpty(): + self.value.setText(self.port.dump()) + + panels=[("Panel1",panel1)] + +class ItemOutPort(ItemPort): + def getIconName(self): + return "outport.png" + + def panel1(self,parent): + qvbox=QVBox(parent) + qvbox.layout().setAlignment(Qt.AlignTop|Qt.AlignLeft) + qvbox.setSpacing( 5 ) + + row0=QHBox(qvbox) + QLabel("Name: ",row0) + QLineEdit(self.port.getName(),row0) + QLabel("Type: ",row0) + QLineEdit(self.port.edGetType().name(),row0) + + QLabel("Value: ",qvbox) + self.value=QTextEdit(qvbox) + self.value.setText("Empty") + try: + self.value.setText(self.port.dump()) + except: + traceback.print_exc() + + row3=QHBox(qvbox) + but2=QPushButton( "Refresh", row3 ) + qvbox.connect( but2, SIGNAL("clicked()"), self.handleRefresh ) + + return qvbox + + def handleRefresh(self): + try: + self.value.setText(self.port.dump()) + except: + traceback.print_exc() + + panels=[("Panel1",panel1)] + + +class ItemInStream(ItemPort): + def getIconName(self): + return "instream.png" +class ItemOutStream(ItemPort): + def getIconName(self): + return "outstream.png" + +class ItemNode(Item.Item): + """Item pour les noeuds elementaires + Il n a pas de fils + """ + #attr donnant la liste des panels du noeud (nom,method) + panels=[] + def __init__(self,node): + self.node=node + self.label=node.getName() + + def isExpandable(self): + return True + + def getChildren(self): + sublist=[] + for n in self.node.getSetOfInputPort(): + sublist.append(adapt.adapt(n,Item.Item)) + for n in self.node.getSetOfOutputPort(): + sublist.append(adapt.adapt(n,Item.Item)) + for n in self.node.getSetOfInputDataStreamPort(): + sublist.append(adapt.adapt(n,Item.Item)) + for n in self.node.getSetOfOutputDataStreamPort(): + sublist.append(adapt.adapt(n,Item.Item)) + return sublist + + def panel(self,parent): + """Retourne un tab widget pour browser/editer l'item""" + tabWidget = QTabWidget( parent ) + for name,method in self.panels: + tabWidget.addTab( method(self,tabWidget), name ) + return tabWidget + +class ItemScriptNode(ItemNode): + + def panel1(self,parent): + qvbox=QVBox(parent) + qvbox.setSpacing( 5 ) + + row0=QHBox(qvbox) + label=QLabel("Name: ",row0) + lined0 = QLineEdit(self.node.getName(),row0) + + label=QLabel("Script: ",qvbox) + mle=Editor.Editor(qvbox,"multiLineEdit" ) + mle.setText(self.node.getScript()) + + row2=QHBox(qvbox) + but1=QPushButton( "Save", row2 ) + but2=QPushButton( "Cancel", row2 ) + qvbox.connect( but1, SIGNAL("clicked()"), self.handleSave ) + qvbox.connect( but2, SIGNAL("clicked()"), self.handleCancel ) + + return qvbox + + panels=[("Panel1",panel1)] + + def getIconName(self): + return "green-ball" + + def handleSave(self): + self.node.setScript(str(self.mle.text())) + def handleCancel(self): + self.lined0.setText(self.node.getName()) + self.mle.setText(self.node.getScript()) + +class ItemFuncNode(ItemNode): + def panel1(self,parent): + """Retourne un widget pour browser/editer l'item""" + qvbox=QVBox(parent) + qvbox.setSpacing( 5 ) + + row0=QHBox(qvbox) + label=QLabel("Name: ",row0) + self.lined0 = QLineEdit(self.node.getName(),row0) + + row1=QHBox(qvbox) + label=QLabel("Fname: ",row1) + self.lined1 = QLineEdit(self.node.getFname(),row1) + + label=QLabel("Function: ",qvbox) + self.mle=Editor.Editor(qvbox,"multiLineEdit" ) + self.mle.setText(self.node.getScript()) + + row2=QHBox(qvbox) + but1=QPushButton( "Save", row2 ) + but2=QPushButton( "Cancel", row2 ) + qvbox.connect( but1, SIGNAL("clicked()"), self.handleSave ) + qvbox.connect( but2, SIGNAL("clicked()"), self.handleCancel ) + + return qvbox + + panels=[("Panel1",panel1)] + + def getIconName(self): + return "green-ball" + def FuncChanged(self, newText ): + self.myFunc=str(newText) + + def handleSave(self): + self.node.setFname(str(self.lined1.text())) + self.node.setScript(str(self.mle.text())) + def handleCancel(self): + self.lined0.setText(self.node.getName()) + self.lined1.setText(self.node.getFname()) + self.mle.setText(self.node.getScript()) + +class ItemService(ItemNode): + def panel1(self,parent): + """Retourne un widget pour browser/editer l'item""" + self.myName=self.node.getName() + + qvbox=QVBox(parent) + qvbox.layout().setAlignment(Qt.AlignTop|Qt.AlignLeft) + qvbox.setSpacing( 5 ) + + row0=QHBox(qvbox) + label=QLabel("Name: ",row0) + self.lined0 = QLineEdit(self.node.getName(),row0) + qvbox.connect( self.lined0, SIGNAL("textChanged(const QString &)"), self.NameChanged ) + qvbox.connect( self.lined0, SIGNAL("returnPressed()"), self.NameReturn ) + QToolTip.add( self.lined0, "Node name" ) + + row1=QHBox(qvbox) + label1=QLabel("Ref: ",row1) + self.lined1 = QLineEdit(row1) + if self.node.getComponent(): + self.lined1.setText(self.node.getComponent().getName()) + else: + self.lined1.setText("NO_COMPONENT_NAME") + + row2=QHBox(qvbox) + label2=QLabel("Method: ",row2) + self.lined2 = QLineEdit(row2) + self.lined2.setText(self.node.getMethod()) + + row3=QHBox(qvbox) + but1=QPushButton( "Save", row3 ) + but2=QPushButton( "Cancel", row3 ) + qvbox.connect( but1, SIGNAL("clicked()"), self.handleSave ) + qvbox.connect( but2, SIGNAL("clicked()"), self.handleCancel ) + + return qvbox + + panels=[("Panel1",panel1)] + + def NameChanged(self, newText ): + self.myName=str(newText) + + def NameReturn(self): + pass + + def getIconName(self): + return "green-square" + + def handleSave(self): + self.node.setRef(str(self.lined1.text())) + self.node.setMethod(str(self.lined2.text())) + def handleCancel(self): + self.lined0.setText(self.node.getName()) + self.lined1.setText(self.node.getComponent().getName()) + self.lined2.setText(self.node.getMethod()) + +def adapt_Proc_to_Item(obj, protocol, alternate): + return ItemProc(obj) + +def adapt_Node_to_Item(obj, protocol, alternate): + return ItemNode(obj) + +def adapt_ComposedNode_to_Item(obj, protocol, alternate): + return ItemComposedNode(obj) + +def adapt_InlineFuncNode_to_Item(obj, protocol, alternate): + return ItemFuncNode(obj) + +def adapt_InlineScriptNode_to_Item(obj, protocol, alternate): + return ItemScriptNode(obj) + +def adapt_ServiceNode_to_Item(obj, protocol, alternate): + return ItemService(obj) + +def adapt_Port_to_Item(obj, protocol, alternate): + return ItemPort(obj) + +def adapt_InPort_to_Item(obj, protocol, alternate): + return ItemInPort(obj) + +def adapt_OutPort_to_Item(obj, protocol, alternate): + return ItemOutPort(obj) + +def adapt_InStream_to_Item(obj, protocol, alternate): + return ItemInStream(obj) + +def adapt_OutStream_to_Item(obj, protocol, alternate): + return ItemOutStream(obj) + +if hasattr(pilot,"ProcPtr"): + adapt.registerAdapterFactory(pilot.ProcPtr, Item.Item, adapt_Proc_to_Item) + adapt.registerAdapterFactory(pilot.BlocPtr, Item.Item, adapt_ComposedNode_to_Item) + adapt.registerAdapterFactory(pilot.ForLoopPtr, Item.Item, adapt_ComposedNode_to_Item) + adapt.registerAdapterFactory(pilot.WhileLoopPtr, Item.Item, adapt_ComposedNode_to_Item) + adapt.registerAdapterFactory(pilot.ForEachLoopPtr, Item.Item, adapt_ComposedNode_to_Item) + adapt.registerAdapterFactory(pilot.SwitchPtr, Item.Item, adapt_ComposedNode_to_Item) + adapt.registerAdapterFactory(pilot.ComposedNodePtr, Item.Item, adapt_ComposedNode_to_Item) + + adapt.registerAdapterFactory(pilot.ServiceNodePtr, Item.Item, adapt_ServiceNode_to_Item) + #adapt.registerAdapterFactory(pilot.ServiceNodeNodePtr, Item.Item, adapt_Node_to_Item) + adapt.registerAdapterFactory(pilot.InlineNodePtr, Item.Item, adapt_InlineScriptNode_to_Item) + adapt.registerAdapterFactory(pilot.InlineFuncNodePtr, Item.Item, adapt_InlineFuncNode_to_Item) + adapt.registerAdapterFactory(pilot.NodePtr, Item.Item, adapt_Node_to_Item) + + adapt.registerAdapterFactory(pilot.OutputPortPtr, Item.Item, adapt_OutPort_to_Item) + adapt.registerAdapterFactory(pilot.InputPortPtr, Item.Item, adapt_InPort_to_Item) + adapt.registerAdapterFactory(pilot.OutputDataStreamPortPtr, Item.Item, adapt_OutStream_to_Item) + adapt.registerAdapterFactory(pilot.InputDataStreamPortPtr, Item.Item, adapt_InStream_to_Item) + + pilot_InputDataStreamPort=pilot.InputDataStreamPortPtr + +else: + adapt.registerAdapterFactory(pilot.Proc, Item.Item, adapt_Proc_to_Item) + adapt.registerAdapterFactory(pilot.Bloc, Item.Item, adapt_ComposedNode_to_Item) + adapt.registerAdapterFactory(pilot.ForLoop, Item.Item, adapt_ComposedNode_to_Item) + adapt.registerAdapterFactory(pilot.WhileLoop, Item.Item, adapt_ComposedNode_to_Item) + adapt.registerAdapterFactory(pilot.ForEachLoop, Item.Item, adapt_ComposedNode_to_Item) + adapt.registerAdapterFactory(pilot.Switch, Item.Item, adapt_ComposedNode_to_Item) + adapt.registerAdapterFactory(pilot.ComposedNode, Item.Item, adapt_ComposedNode_to_Item) + + adapt.registerAdapterFactory(pilot.ServiceNode, Item.Item, adapt_ServiceNode_to_Item) + #adapt.registerAdapterFactory(pilot.ServiceNodeNode, Item.Item, adapt_Node_to_Item) + adapt.registerAdapterFactory(pilot.InlineNode, Item.Item, adapt_InlineScriptNode_to_Item) + adapt.registerAdapterFactory(pilot.InlineFuncNode, Item.Item, adapt_InlineFuncNode_to_Item) + adapt.registerAdapterFactory(pilot.Node, Item.Item, adapt_Node_to_Item) + + adapt.registerAdapterFactory(pilot.OutputPort, Item.Item, adapt_OutPort_to_Item) + adapt.registerAdapterFactory(pilot.InputPort, Item.Item, adapt_InPort_to_Item) + adapt.registerAdapterFactory(pilot.OutputDataStreamPort, Item.Item, adapt_OutStream_to_Item) + adapt.registerAdapterFactory(pilot.InputDataStreamPort, Item.Item, adapt_InStream_to_Item) + + pilot_InputDataStreamPort=pilot.InputDataStreamPort diff --git a/src/pyqt/gui/PanelManager.py b/src/pyqt/gui/PanelManager.py new file mode 100644 index 000000000..17f87f508 --- /dev/null +++ b/src/pyqt/gui/PanelManager.py @@ -0,0 +1,15 @@ + +from qt import * + +class PanelManager(QWidgetStack): + def __init__(self,parent): + QWidgetStack.__init__(self,parent) + self.panels={} + + def setview(self,item): + if not self.panels.has_key(item): + panel=item.panel(self) + self.panels[item]=panel + idd=self.addWidget(panel) + self.raiseWidget(panel) + self.raiseWidget(self.panels[item]) diff --git a/src/pyqt/gui/Tree.py b/src/pyqt/gui/Tree.py new file mode 100644 index 000000000..cbd1bf20e --- /dev/null +++ b/src/pyqt/gui/Tree.py @@ -0,0 +1,83 @@ +# -*- coding: iso-8859-15 -*- +"""Ce module permet de créer des vues sous forme d'arbre + Ces vues sont construites à partir des informations + fournies par un modèle +""" + +import sys +from qt import * +import Icons + +class Tree(QListView): + """Tree(parent=None) + Classe pour faire une vue d'un arbre + """ + def __init__(self,parent=None,onSelect=None): + QListView.__init__(self,parent) + self.setCaption("Tree") + self.setRootIsDecorated(1) + self.setSorting(-1) + self.addColumn("Name") + self.children=[] + self.last=None + self.onSelect=onSelect + self.connect(self,SIGNAL('selectionChanged(QListViewItem *)'), + self.handleSelected) + + def handleSelected(self,node): + if self.onSelect:self.onSelect(node.item) + + def additem(self,item): + node=Node(self,item.label,item,self.last) + self.last=node + self.children.append(node) + return node + + +class Node(QListViewItem): + """Node(parent,text,item,after) + Classe pour faire une vue d'un noeud d'un arbre + """ + def __init__(self,parent,text,item,after=None): + if after is None: + QListViewItem.__init__(self,parent,text) + else: + QListViewItem.__init__(self,parent,after,text) + self.item=item + self.setPixmap(0,Icons.get_image(item.getIconName())) + self.setExpandable(self.item.isExpandable()) + self.children = [] + + def additem(self,item): + if self.children: + node=Node(self,item.label,item,self.children[-1]) + else: + node=Node(self,item.label,item) + self.children.append(node) + return node + + def setOpen(self,o): + if o: + #open + for child in self.item.getChildren(): + self.additem(child) + else: + #close + for node in self.children: + self.takeItem(node) + del node + self.children=[] + QListViewItem.setOpen(self,o) + + +if __name__ == "__main__": + from Item import Item + app = QApplication(sys.argv) + t=Tree() + t.additem(Item("item1")) + #n=t.additem(Item("item2")) + #n.additem(Item("item3")) + app.setMainWidget(t) + t.show() + app.exec_loop() + diff --git a/src/pyqt/gui/__init__.py b/src/pyqt/gui/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/pyqt/gui/adapt.py b/src/pyqt/gui/adapt.py new file mode 100644 index 000000000..b5d50941f --- /dev/null +++ b/src/pyqt/gui/adapt.py @@ -0,0 +1,59 @@ +class AdaptationError(TypeError): + pass +class LiskovViolation(AdaptationError): + pass + +_adapter_factory_registry = {} + +def registerAdapterFactory(objtype, protocol, factory): + _adapter_factory_registry[objtype, protocol] = factory + +def unregisterAdapterFactory(objtype, protocol): + del _adapter_factory_registry[objtype, protocol] + +def _adapt_by_registry(obj, protocol, alternate): + factory = _adapter_factory_registry.get((type(obj), protocol)) + if factory is None: + adapter = alternate + else: + adapter = factory(obj, protocol, alternate) + if adapter is AdaptationError: + raise AdaptationError + else: + return adapter + + +def adapt(obj, protocol, alternate=AdaptationError): + + t = type(obj) + + # (a) first check to see if object has the exact protocol + if t is protocol: + return obj + + try: + # (b) next check if t.__conform__ exists & likes protocol + conform = getattr(t, '__conform__', None) + if conform is not None: + result = conform(obj, protocol) + if result is not None: + return result + + # (c) then check if protocol.__adapt__ exists & likes obj + adapt = getattr(type(protocol), '__adapt__', None) + if adapt is not None: + result = adapt(protocol, obj) + if result is not None: + return result + except LiskovViolation: + pass + else: + # (d) check if object is instance of protocol + try: + if isinstance(obj, protocol): + return obj + except: + pass + + # (e) last chance: try the registry + return _adapt_by_registry(obj, protocol, alternate) diff --git a/src/pyqt/gui/icons/components.png b/src/pyqt/gui/icons/components.png new file mode 100644 index 0000000000000000000000000000000000000000..6433f3900bcfbbfad603785301d957cc2a77945d GIT binary patch literal 1334 zcmZ`&%WcIl408`X^;Wb%N9ZxWya9Ue5&_;&0ld=7N-0TwtcRpQVmPuSQk4AjdwXqq zZdkwZed7DT_tL(w;=%d*n|)?zZS0Q+-VN)(hQC``VdO8506W@)QA}JUnhQOKl!zqn{a`Y-)MDEjWbZlk48{!K-f{){1iXDqT z1NDa;#fQ1U4w%+!{fVzL2`07D4$h%8@Wp>wLl3qf7%EH>Saqsa5=dGDCx62?G00r6 zkiAtrdbWG;37qpIL2f?i0F#f?;JEN9@@AdmcQRe7Bo8d)DAqAUJT2!MC3n$Y0 z?~$|4^bp{*3j<*$dE!gh(q|sT!=_y8qW;JHt9hw&=`+->_^iuVnEw5a`F|SeJf<8f z8=H821TqWex0}v(G5vblji^`EEmA7+IX_Fc+?K_2O~5%tq)B^-B_HC$>O(4!D+;AR oRU{Z1v;QI%uoo;0*_pe9aO3=e0#*!?ZMdHI^l=BA%AdsBA499QUER)n@O=*=hV@)~wOhY1pfgweRhx1m0 R>k^<*44$rjF6*2UngHFzAgTZW literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/datalink.png b/src/pyqt/gui/icons/datalink.png new file mode 100644 index 0000000000000000000000000000000000000000..be94e57d0b863507d8dd4961397ec18bb0d31301 GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3HGlXG}j1q?|on978O6lM^IZnYkn;-uPeG z@t8^CmE=RA8Ey}a1y)zN@o*kudlYiM>3CU(n-GKI;SIZc8j@DEN}5TZ>^d80aDag! Y<*5+QvfCy7K;sxZUHx3vIVCg!03nYjN&o-= literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/edit.png b/src/pyqt/gui/icons/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..2fdb70233b8f2c7b1915ebde713f0368ec71bb2a GIT binary patch literal 629 zcmV-*0*d{KP)1Q#xfd>Q}%0rE*iK~#90rIo#o(?A$SkHcmc;f+`+v5)|X5;~M79c`-Z(x=Wl zP|;9QrSKCVlqaB~CP@4>Xd8lDfCRQe5J(w&?D;4XCmF}i58P&a<(V_r*S5xCL%m*4 z=JPp9DFBpGF&jB1tbh2sUIA%B;md#sjG@H$sPN!U6UgG;cgTX+m;45{zU71WK zvP)4ENe~3mYPDoM9*gh$0!WcnD<=yfGWB^D7R(~E^- z3P}~R^ilwqcI-HgHD0Tqff(vHZep~;y?q}s8I5}n0l0YZXp6D;m(G(E6G^54$nr`K zNxYaT%LR+xjb4mmvZY^l3~Y65forw3HA`TY$ literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/folder.gif b/src/pyqt/gui/icons/folder.gif new file mode 100644 index 0000000000000000000000000000000000000000..effe8dc8a00681b3f1c1f5bdd7808a924e3b9b15 GIT binary patch literal 120 zcmZ?wbhEHb2o4-Lp!k!8k%57oK?lSK zsdZqstq4D}EI?FXl_(>3(z3teliOz1cfwq&OIy`)(JLT literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/green-los.gif b/src/pyqt/gui/icons/green-los.gif new file mode 100755 index 0000000000000000000000000000000000000000..0c9dbd020c77449eb2288a05326135e159cbf00f GIT binary patch literal 143 zcmZ?wbhEHb6lM@)_{abT{~6YSf#N@11qILCg8ZVA)D(rZqWoM1cTYEk%-qEER4awV z;u77;)SR6Ba^0N#V!iatGzP_=EQ|~c%nUjpV?YKnFzL^!Z#d1iFshpIlZe9mScgpKP1+Q!=h33+i=9&NF=MiIIum%8yEh~}$ literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/import.gif b/src/pyqt/gui/icons/import.gif new file mode 100644 index 0000000000000000000000000000000000000000..badc18ba7aa0985c963f95758a8edebfb10be668 GIT binary patch literal 270 zcmZ?wbhEHb6k!ly_{_rq0+a4|?D*f!z_5scVJ8E_1qO!a3=IDn820Vk*LUSV5C9oq zbs$3VCkrD30}q4ZKUD<<&)kCiqLS1Ug|wplT!n}LUxm!v#Pn1vh0=nQ#FA9Kih^7Q z9gr@NWz8T4DORy0O*rYfdapur_d(0HiG{)qbLIz%NM|m3a4YF}=Mrth@O#r&vC6V1 zd}u9l^6^-#$Wvx>&B>8frCq1hL4d)=b5hSVYo_+&vBjLcZy9bpeOR*b>9T|Gts>8! Rc>lAOtGuB$S6Gn28USmXV^shE literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/inport.png b/src/pyqt/gui/icons/inport.png new file mode 100644 index 0000000000000000000000000000000000000000..a1927d279b55b933af53677061eeb62414f599ec GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3HGlXG}j1q+C5+978O6lM^IZmoT{*ef@hp zjm@&{@9`uNWy`jOQY~o;nr(^Z948&bcz8t^N)CV6Ic0$>vsl^<-X#iVf^3VV&ACo6 ZG3;H<$G30tI!~a144$rjF6*2UngH$mBqIO- literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/instream.png b/src/pyqt/gui/icons/instream.png new file mode 100644 index 0000000000000000000000000000000000000000..cf2e41e7167b35190df4910392860e17ee3c3e1c GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3HGlXG}j1qmfQGkiGg)@6IPhiloY!$N|^5jjmtClWND92Dbb*{71U+qb`Y-d!Em i{C$}V;@4#SVR(^ODZwXFYY-1Kn8DN4&t;ucLK6UpY%Oa5 literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/kill.png b/src/pyqt/gui/icons/kill.png new file mode 100644 index 0000000000000000000000000000000000000000..51ecc2793f0a23c76b71211ded9ec729b4d4c8fd GIT binary patch literal 889 zcmV-<1BU#GP)+Uu`oH#*sWCZW#bpYZxK}rdL3?){h!JgRX{lUF_Kk>VvMdo5H z^vv*1u3yV&*IMyn5k5l*idMKTaYzs1-fwS26oLyI5uydK1;c$ zhmNiaZg~TRQiVcS7X#ztbnV(j_wH>}mzEgtV}|9xR8Q zC(i(|^^;-T&JwokV!K85oFB`|HhPu98&x`8K~LjZQ}ZkU%=6|(1s81#yek*;yKNtR zitV~ozdDId5&(W1K8{`J1R=8161;4P;{>@BkV;7$C(K_P%OCFe`18!cb(#9|LsGwv zaGHjyb;L?3j8f<{K}ksxN6cRR_63KjufIU25>aqS>rY<-URL7QkV+xLIx0<2smvo? z(Y|w+0D%fZEN>ZXn)k$l=dBDE1LCMbyy%lWtG`gwsc(jJr*|%Y2ceG%LyS`G!9oZ; z&qFsFU|EP_XWspln#!ktGjZ%t?s(wtkHk(0T4S_sQwn34zkQo0PiCO!(!!cLDfm`xfM1|1c*tezDvHUOgvfsK1Z>f#kr!gE(b_WjRoA&{2f( z0-|UE{fCEst%#gmWG+?II!a7#Dm881+5t2}{e2A9Q{GBbHoo1L)o@vjndvNTt(lX$ zEwmLlhY$F1wo$8x-xx3kqqFoUH(VP){G)q$?d^ZKrWV<96D8 zXXp36<6*nW%5G>{f0r3}XFfddGk;Rtn?j+G0Eh@8f-&ZSjv~U+($bzYZ$4{|9U4c` zHd9kmJj@uq!KpK!vxQF1Y{SMF0463Ty58)09=Tku>)MYOzTuTUSDBq2Lru=W;>k|< zLC0Fl&tDaoogQQ8)pucW4nmin_6r^c{p{!q%uWtB(eraqbwQ*vvFCX^LhWmD9P`ts zN0@mr$I$r9HmU>^o$yXQws&l;<@*z_F+D!qL`$cUO&6sEjl%ca;N4bXt>t3j4TcY9 zw$ZA$g}P<%s$CM_4{e+~%UC{7W+)G()3CXUQVNa2^946hd{A_D-*J*8G|rvH$>mVa zB-P~wGF1Ewomv9qy=Nr;e|zt>GNZKz0;yOAuDkqHu8VDw@@b;=__dtyX&n z2zFIPT))l8^^1@nhrlCri){K892v$BD|mslqc?y*?gKaf0oFE}X_bR6m+^y5Dq)Df zDQG>wd`U>B)3i|FMn@If9UDv}BuT_*a0$lpgry?hYKaxEjMkbJ8DP0s;k`rCe7Sgm z77En6zQ-a02#Cf+5oxuKu2d+muCn5lDTabu);Nyh89wp->T(8_Aj$>Nrf8bW)-`6f9#?UZ^ufJX4e9^@j z$TEL?hUL;tjEU*%bx_t2g&W+8dP%F!hu;B@Jo7Y&5Z(C)-w#+gd6>(-;k!#!o_}tH zC$jr_EPH?f)q}NnF(%^bZ|nDV+6CUKLN}`bm_PLie_p%B(BpOb`}-Ju>PhxFeW+BO zBATc*2sS1=m}dRvU;K@bvO;2GFfoaZNvw1v hPPLsU{QueV{spsR6H!O|y@~(;002ovPDHLkV1mk%voHVv literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/openfolder.gif b/src/pyqt/gui/icons/openfolder.gif new file mode 100644 index 0000000000000000000000000000000000000000..24aea1bebe8413427326f964ae8b6f9a29641029 GIT binary patch literal 125 zcmZ?wbhEHb6ky7fiA{5+57r9a@@xaKl9H#tW>S8=RaE bzBro0!*Kd>PT20+wB2&-H*#hPF<1it%q=nK literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/outport.png b/src/pyqt/gui/icons/outport.png new file mode 100644 index 0000000000000000000000000000000000000000..552ec98a7dd5d2dfb2afb1400d24c926619a1f3c GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3HGlXG}j1q+C5+978O6lM^IZmoT}R{HwPq zQjz>7-yNtT$r0R>B`}lC=#fbW4|8P47Loa-1*bbqdo-p8+MY>h$lBOxAh7+8#sWqL ZhCnu6LDql`pMVB3c)I$ztaD0e0syw@BfbCt literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/outstream.png b/src/pyqt/gui/icons/outstream.png new file mode 100644 index 0000000000000000000000000000000000000000..f74cbf02e648b473c3b4814c73886035538f6062 GIT binary patch literal 131 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3HGlXG}j1q`W*`978O6lM^IZmoT}R{HwPq zQjz@j|9^c;WKU0ziZn-XPm;h+Hls&I9Wu<39a}`U=W@6U=1K(WEv}kzkl|{QaGrwP e&Oird28M}`#RYeMzo!W_mBG{1&t;ucLK6Vx`6opH literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/port.png b/src/pyqt/gui/icons/port.png new file mode 100644 index 0000000000000000000000000000000000000000..b71b1cc20b754ef107527e241a66ffbab097ec4f GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJB2O2`kcif|(=7Q8DDbfO9ywfL zWzQ|j>(2B|i92)ok`H{#1r=K?gdd1*-g7r%*7FA}ZU?!QBpRoF=xm8iP_I!)6u!`6 zF4XVI&``&!vw6J=r(l>*=Wnqc+&kto#vMK#@6^k(NBoV4%A+3!%gdoE?w?yY*XMamxaAW~()k6;QGVVf3ZPpQcy+38CrH3{Qk zoaxN-vWJ+OcH(Y#5qvHK|CitMf1CdUU;7AQ8zF4-#i736F~#EMso~pq*Ek7JMLa$}POH_T(b)M|f)>8t;^3f3 zKA)#ntMKyW+7Z-s>l6xWsZ53jrMAEC5{41RXe`Snj$`6DMr+Vop|xgsc$hE@Sz20V zb@eG)%b|Y+_m{*NND_%L1}POFH@MUObOdhQq^%&CMdWZvC2q+x@_Pg_JQ$DGG%bJbwIyVzG#2o#E=$@5yGf z#Bm5%IplY1BB@I((}Bdlpj1;;nAaqNZEDBWHP2)F0;K|LMcrchIBe@ z&Ye4p5H>e&{)pCc=qTd1Z_6|q4IIZIpUy{Fg7-dG2KQ=nb2l+s9lDyqr z7!DY|eAoo!aTa()7Bet#3xP1>rMq>1fP(BLp1!W^ml-8^jLg@h%=!%!%Jy_|45^6g zo#@GTK!Jyu{Yv}q=Pw(N=yqQ@$9i<*VulZn(XS$|-V|VR(BI2E(Q@%DmJ+AQ8!jDR zn3(BhnVn;>O~mYkd4T8QCtIpR+OOR-aws<7n;FD%!g`O<${imk%&eSz`t97W^Aqa7 a$lvM6Q4+HLn0Xm!ErX}4pUXO@geCy1h*Kv3 literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/streamlink.png b/src/pyqt/gui/icons/streamlink.png new file mode 100644 index 0000000000000000000000000000000000000000..9ccd8add8d222b332e9325f629706578e3195a88 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3HGlXG}j1q`W;{978O6lM^IZnYkn;-uPeG z@t8^CRpP9F|Nr+-NKSE?csNVI>}$^pAs2~`U|Vjv+maFidz}OXjCfX`=FnUgH6wBJ g#5Ff$Sebbk`b6b;`oE;@2O7)Z>FVdQ&MBb@0H~-bxc~qF literal 0 HcmV?d00001 diff --git a/src/pyqt/gui/icons/suspend-resume.gif b/src/pyqt/gui/icons/suspend-resume.gif new file mode 100644 index 0000000000000000000000000000000000000000..b0ffb7e0cc026c1e0c383a17044f5aabcf4b5d91 GIT binary patch literal 214 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIWsLS&DhwO0R|NR`GsU;7Aqtcl_&tI%shpX zj8uh!(xjZsWQCOc+{Da0Jq7R7GN6P8 zTBKlTX=%!!_>+Z^fq{`h2V@1vb_QloiCuU88JzN5z4yk{OJ&c!6gd(UCY?Un$r?Nn?=Lqvv3P#w6Kw&mW_iT|AE}uhs$W)G1T8 + + + + + ? + ? + aNewDataFlow_1 + 9 + 300 + 0 + 0 + ? + + aNewDataFlow_1 + + + + + + 31/3/2006 - 10:33:22 + 31/3/2006 - 10:34:14 + 3.0 + ? + ? + ? + 0 + 0 + + + + + COMPONENT_A + COMPONENT_A + S1 + 0 + ? + + S1 + + + + + + 31/3/2006 - 10:33:25 + 31/3/2006 - 10:33:25 + 3.0 + ? + localhost/FactoryServer + S1 from COMPONENT_A + 32 + 131 + + + COMPONENT_B + COMPONENT_B + S2 + 0 + ? + + S2 + + + + + + 0 + S2_data_uses_port + 0 + 0 + + + + 31/3/2006 - 10:33:28 + 31/3/2006 - 10:33:28 + 3.0 + ? + localhost/FactoryServer + S2 from COMPONENT_B + 333 + 64 + + + COMPONENT_C + COMPONENT_C + S3 + 0 + ? + + S3 + + + + + + 0 + S3_data_provides_port + 0 + 0 + 0 + 0 + + + + 31/3/2006 - 10:33:33 + 31/3/2006 - 10:33:33 + 3.0 + ? + localhost/FactoryServer + S3 from COMPONENT_C + 334 + 250 + + + + + S1 + Gate + S2 + Gate + + + + S1 + Gate + S3 + Gate + + + + S2 + S2_data_uses_port + S3 + S3_data_provides_port + + + 320 + 325 + + + 320 + 214 + + + 580 + 214 + + + 580 + 139 + + + + + + + + diff --git a/src/pyqt/salomefiles/GraphLoop1.xml b/src/pyqt/salomefiles/GraphLoop1.xml new file mode 100644 index 000000000..f5ad503de --- /dev/null +++ b/src/pyqt/salomefiles/GraphLoop1.xml @@ -0,0 +1,307 @@ + + + + + +? + ? + GraphLoop1 + 1 + ? + +GraphLoop_2 + + +long + Init__Index + +long + Init__Min + +long + Init__Max + +long + Init__Incr + + +long + EndInit__Index + +long + EndInit__Min + +long + EndInit__Max + +long + EndInit__Incr + + + 24/3/2003 - 14:44:35 + 6/6/2005 - 15:13:52 + 1.04 + ? + ? + ? + 0 + 0 + + +? + ? + Init + 4 + EndInit + +Init + + +long + Index + +long + Min + +long + Max + +long + Incr + + +long + Index + +long + Min + +long + Max + +long + Incr + + + +Init + + + + + + + +More + + + + + + + + + +Next + + + + 6/6/2005 - 15:13:52 + 6/6/2005 - 15:13:52 + 1.04 + ? + ? + Compute Node + 17 + 257 + +? + ? + EndInit + 5 + Init + +EndInit + + +long + Index + +long + Min + +long + Max + +long + Incr + + +long + Index + +long + Min + +long + Max + +long + Incr + + + +? + + 6/6/2005 - 15:13:52 + 6/6/2005 - 15:13:52 + 1.04 + ? + ? + Compute Node + 555 + 255 + +? + ? + NodeIndex + 3 + ? + +NodeIndex + + +long + Index + + +long + Index + + + +? + + 6/6/2005 - 15:13:52 + 6/6/2005 - 15:13:52 + 2.0 + ? + ? + Compute Node + 281 + 215 + +? + ? + NodeIncr + 3 + ? + +NodeIncr + + +long + Incr + + +long + Incr + + + +? + + 6/6/2005 - 15:13:52 + 6/6/2005 - 15:13:52 + 2.0 + ? + ? + Compute Node + 278 + 372 + + +Init + DoLoop + EndInit + DoLoop + + +Init + Index + NodeIndex + Index + + +Init + Min + EndInit + Min + + +Init + Max + EndInit + Max + + +Init + Incr + NodeIncr + Incr + + +EndInit + DoLoop + Init + DoLoop + + +NodeIndex + Index + EndInit + Index + + +NodeIncr + Incr + EndInit + Incr + + + +GraphLoop1 + Init__Index + Init + Index + +3 + 0 + + +GraphLoop1 + Init__Min + Init + Min + +3 + 5 + + +GraphLoop1 + Init__Max + Init + Max + +3 + 10 + + +GraphLoop1 + Init__Incr + Init + Incr + +3 + 1 + diff --git a/src/pyqt/salomefiles/calc.xml b/src/pyqt/salomefiles/calc.xml new file mode 100644 index 000000000..7937dc42c --- /dev/null +++ b/src/pyqt/salomefiles/calc.xml @@ -0,0 +1,301 @@ + + + + + + ? + ? + aNewDataFlow_1 + 9 + 300 + 0 + 0 + ? + + aNewDataFlow_1 + + + double + RunMC__sigma_s_milieu_1 + + + double + RunMC__sigma_t_milieu_1 + + + double + RunMC__sigma_s_milieu_2 + + + double + RunMC__sigma_t_milieu_2 + + + double + RunMC__theta + + + long + RunMC__nbphot + + + string + RunMC__working_directory + + + string + RunMC__infilename + + + double + RunMC__epsilon + + + double + RunDIF__sigma_s_milieu_1 + + + double + RunDIF__sigma_t_milieu_1 + + + double + RunDIF__sigma_s_milieu_2 + + + double + RunDIF__sigma_t_milieu_2 + + + string + RunDIF__working_directory + + + string + RunDIF__infilename + + + + + string + RunMC__outfilename + + + double + RunMC__ecart_type + + + string + RunDIF__outfilename + + + long + RunDIF__iterations + + + + + + 13/3/2006 - 16:47:39 + 13/3/2006 - 16:50:14 + 3.0 + ? + ? + ? + 0 + 0 + + + + + MC2DCPL + MC2DCPL + RunMC + 0 + ? + + RunMC + + + double + sigma_s_milieu_1 + + + double + sigma_t_milieu_1 + + + double + sigma_s_milieu_2 + + + double + sigma_t_milieu_2 + + + double + theta + + + long + nbphot + + + string + working_directory + + + string + infilename + + + double + epsilon + + + + + string + outfilename + + + double + ecart_type + + + + + + 3 + FDIFMC + 1 + 1 + 2 + 0 + + + 3 + FMCDIF + 1 + 0 + + + + 13/3/2006 - 16:47:56 + 13/3/2006 - 16:47:56 + 3.0 + ? + localhost/FactoryServer + RunMC from MC2DCPL + 221 + 136 + + + DIF2DCPL + DIF2DCPL + RunDIF + 0 + ? + + RunDIF + + + double + sigma_s_milieu_1 + + + double + sigma_t_milieu_1 + + + double + sigma_s_milieu_2 + + + double + sigma_t_milieu_2 + + + string + working_directory + + + string + infilename + + + + + string + outfilename + + + long + iterations + + + + + + 3 + FMCDIF + 1 + 1 + 2 + 0 + + + 3 + FDIFMC + 1 + 0 + + + + 13/3/2006 - 16:48:4 + 13/3/2006 - 16:48:4 + 3.0 + ? + localhost/FactoryServer + RunDIF from DIF2DCPL + 590 + 196 + + + + + RunMC + FMCDIF + RunDIF + FMCDIF + + + + RunDIF + FDIFMC + RunMC + FDIFMC + + + 142 + 390 + + + 142 + 499 + + + 818 + 504 + + + 815 + 389 + + + + + + + + diff --git a/src/pyqt/salomefiles/my2loopsf.xml b/src/pyqt/salomefiles/my2loopsf.xml new file mode 100644 index 000000000..64bbfbe9e --- /dev/null +++ b/src/pyqt/salomefiles/my2loopsf.xml @@ -0,0 +1,936 @@ + + + + + + ? + ? + aNewDataFlow_1 + 1 + ? + + aNewDataFlow_1 + + + double + Add__y + + + double + Add_1__y + + + double + Add_2__y + + + double + Add_3__y + + + double + Add_5__x + + + double + Add_5__y + + + double + Add_6__y + + + double + Add_7__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_2__FuncValue + + + double + Add_3__FuncValue + + + double + Add_4__FuncValue + + + double + Add_5__FuncValue + + + double + Add_6__FuncValue + + + double + Add_7__FuncValue + + + double + Add_7__z + + + double + f_2__a + + + + + + 10/3/2006 - 19:8:42 + 18/3/2006 - 13:43:15 + 3.0 + ? + ? + ? + 0 + 0 + + + + + SuperVisionTest + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 12:53:43 + 18/3/2006 - 12:53:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 996 + 195 + + + SuperVisionTest + AddComponent + Add_1 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 12:53:43 + 18/3/2006 - 12:53:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 960 + 383 + + + ? + ? + Loop + 4 + EndLoop + + Loop + + + double + x + + + + + double + x + + + + + + + ? + + + + ? + + + + ? + + + + 18/3/2006 - 12:56:11 + 18/3/2006 - 12:56:11 + 3.0 + ? + ? + Compute Node + 226 + 162 + + + ? + ? + EndLoop + 5 + Loop + + EndLoop + + + double + x + + + + + double + x + + + + + + + EndLoop + + + + 18/3/2006 - 12:56:11 + 18/3/2006 - 12:56:11 + 3.0 + ? + ? + Compute Node + 799 + 176 + + + SuperVisionTest + AddComponent + Add_2 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 12:59:16 + 18/3/2006 - 12:59:16 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 418 + 12 + + + SuperVisionTest + AddComponent + Add_3 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 13:0:47 + 18/3/2006 - 13:0:47 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 45 + 42 + + + SuperVisionTest + AddComponent + Add_4 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 13:8:54 + 18/3/2006 - 13:8:54 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 603 + 115 + + + ? + ? + Loop_1 + 4 + EndLoop_1 + + Loop_1 + + + double + x + + + + + double + x + + + + + + + ? + + + + ? + + + + ? + + + + 18/3/2006 - 13:16:39 + 18/3/2006 - 13:16:39 + 3.0 + ? + ? + Compute Node + 147 + 330 + + + ? + ? + EndLoop_1 + 5 + Loop_1 + + EndLoop_1 + + + double + x + + + + + double + x + + + + + + + EndLoop + + + + 18/3/2006 - 13:16:39 + 18/3/2006 - 13:16:39 + 3.0 + ? + ? + Compute Node + 683 + 586 + + + SuperVisionTest + AddComponent + Add_5 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 13:18:57 + 18/3/2006 - 13:18:57 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 18 + 501 + + + SuperVisionTest + AddComponent + Add_6 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 13:19:23 + 18/3/2006 - 13:19:23 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 1084 + 555 + + + SuperVisionTest + AddComponent + Add_7 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 13:33:40 + 18/3/2006 - 13:33:40 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 464 + 262 + + + ? + ? + f + 3 + ? + + f + + + double + a + + + + + double + a + + + + + + + f + + + + + 18/3/2006 - 13:41:45 + 18/3/2006 - 13:41:45 + 3.0 + ? + ? + Compute Node + 201 + 644 + + + ? + ? + f_1 + 3 + ? + + f_1 + + + double + a + + + + + double + a + + + + + + + f_1 + + + + + 18/3/2006 - 13:42:35 + 18/3/2006 - 13:42:35 + 3.0 + ? + ? + Compute Node + 408 + 671 + + + ? + ? + f_2 + 3 + ? + + f_2 + + + double + a + + + + + double + a + + + + + + + f_2 + + + + + 18/3/2006 - 13:42:42 + 18/3/2006 - 13:42:42 + 3.0 + ? + ? + Compute Node + 619 + 685 + + + + + Add + z + Add_1 + x + + + + Add_1 + z + EndLoop_1 + x + + + + Loop + DoLoop + EndLoop + DoLoop + + + + Loop + x + Add_2 + x + + + + Loop + x + Add_4 + y + + + + Loop + x + Add_7 + x + + + + EndLoop + DoLoop + Loop + DoLoop + + + + EndLoop + x + Add + x + + + + Add_2 + z + Add_4 + x + + + + Add_3 + z + Loop + x + + + + Add_4 + z + EndLoop + x + + + + Loop_1 + DoLoop + EndLoop_1 + DoLoop + + + + Loop_1 + x + Add_3 + x + + + + EndLoop_1 + DoLoop + Loop_1 + DoLoop + + + + EndLoop_1 + x + Add_6 + x + + + + Add_5 + z + Loop_1 + x + + + + Add_6 + z + f + a + + + + Add_7 + Gate + EndLoop + Gate + + + + f + a + f_1 + a + + + + f_1 + a + f_2 + a + + + + + + aNewDataFlow_1 + Add__y + Add + y + + 7 + 3 + + + + + aNewDataFlow_1 + Add_1__y + Add_1 + y + + 7 + 3 + + + + + aNewDataFlow_1 + Add_2__y + Add_2 + y + + 7 + 1 + + + + + aNewDataFlow_1 + Add_3__y + Add_3 + y + + 7 + 10 + + + + + aNewDataFlow_1 + Add_5__x + Add_5 + x + + 7 + 1 + + + + + aNewDataFlow_1 + Add_5__y + Add_5 + y + + 7 + 2 + + + + + aNewDataFlow_1 + Add_6__y + Add_6 + y + + 7 + 6 + + + + + aNewDataFlow_1 + Add_7__y + Add_7 + y + + 7 + 3 + + + + + + + diff --git a/src/pyqt/salomefiles/myloop.xml b/src/pyqt/salomefiles/myloop.xml new file mode 100644 index 000000000..b3cdcdea9 --- /dev/null +++ b/src/pyqt/salomefiles/myloop.xml @@ -0,0 +1,345 @@ + + + + + + ? + ? + GraphLoop1 + 1 + ? + + GraphLoop1 + + + long + Init__Index + + + long + Init__Min + + + long + Init__Max + + + long + Init__Incr + + + + + long + EndInit__Index + + + long + EndInit__Min + + + long + EndInit__Max + + + long + EndInit__Incr + + + + + + 24/3/2003 - 14:44:35 + 22/2/2007 - 19:25:43 + 1.04 + ? + ? + ? + 0 + 0 + + + + + ? + ? + Init + 4 + EndInit + + Init + + + long + Index + + + long + Min + + + long + Max + + + long + Incr + + + + + long + Index + + + long + Min + + + long + Max + + + long + Incr + + + + + + + Init + + + + + + + + + More + + + + + + + + + + + Next + + + + + + 22/2/2007 - 16:4:22 + 22/2/2007 - 16:4:22 + 1.04 + ? + ? + Compute Node + 17 + 257 + + + ? + ? + EndInit + 5 + Init + + EndInit + + + long + Index + + + long + Min + + + long + Max + + + long + Incr + + + + + long + Index + + + long + Min + + + long + Max + + + long + Incr + + + + + + + ? + + + + 22/2/2007 - 16:4:22 + 22/2/2007 - 16:4:22 + 1.04 + ? + ? + Compute Node + 555 + 255 + + + ? + ? + f + 3 + ? + + f + + + long + f + + + + + long + f + + + + + + + f + + + + + 22/2/2007 - 19:24:3 + 22/2/2007 - 19:24:3 + 3.0 + ? + ? + Compute Node + 273 + 272 + + + + + Init + DoLoop + EndInit + DoLoop + + + + Init + Index + f + f + + + + Init + Min + EndInit + Min + + + + Init + Max + EndInit + Max + + + + Init + Incr + EndInit + Incr + + + + EndInit + DoLoop + Init + DoLoop + + + + f + f + EndInit + Index + + + + + + GraphLoop1 + Init__Index + Init + Index + + 3 + 0 + + + + + GraphLoop1 + Init__Min + Init + Min + + 3 + 5 + + + + + GraphLoop1 + Init__Max + Init + Max + + 3 + 10 + + + + + GraphLoop1 + Init__Incr + Init + Incr + + 3 + 1 + + + + + + + diff --git a/src/pyqt/salomefiles/mymacro.xml b/src/pyqt/salomefiles/mymacro.xml new file mode 100644 index 000000000..612ee6ac5 --- /dev/null +++ b/src/pyqt/salomefiles/mymacro.xml @@ -0,0 +1,92 @@ + + + + + + ? + ? + GraphAdd_1 + 1 + ? + + GraphAdd_1 + + + double + Add__x + + + double + Add__y + + + + + double + Add__FuncValue + + + double + Add__z + + + + + + 28/9/2005 - 16:2:26 + 29/3/2006 - 19:54:5 + 2.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 29/3/2006 - 19:54:5 + 29/3/2006 - 19:54:5 + 2.0 + ? + localhost/FactoryServer + Add from AddComponent + 55 + 61 + + + + + + + diff --git a/src/pyqt/salomefiles/mymacro2.xml b/src/pyqt/salomefiles/mymacro2.xml new file mode 100644 index 000000000..836f7aeeb --- /dev/null +++ b/src/pyqt/salomefiles/mymacro2.xml @@ -0,0 +1,151 @@ + + + + + + ? + ? + GraphAdd_1 + 1 + ? + + GraphAdd_1 + + + double + Add__x + + + double + Add__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_1__z + + + + + + 28/9/2005 - 16:2:26 + 29/3/2006 - 20:1:9 + 2.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 29/3/2006 - 19:59:47 + 29/3/2006 - 19:59:47 + 2.0 + ? + localhost/FactoryServer + Add from AddComponent + 233 + 71 + + + AddComponent + AddComponent + Add_1 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 29/3/2006 - 20:0:24 + 29/3/2006 - 20:0:24 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 523 + 72 + + + + + Add + z + Add_1 + x + + + + Add + z + Add_1 + y + + + + + + + diff --git a/src/pyqt/salomefiles/myproc.xml b/src/pyqt/salomefiles/myproc.xml new file mode 100644 index 000000000..bf326bccc --- /dev/null +++ b/src/pyqt/salomefiles/myproc.xml @@ -0,0 +1,482 @@ + + + + + + ? + ? + aNewDataFlow_1 + 1 + ? + + aNewDataFlow_1 + + + double + Add__y + + + double + Add_1__y + + + double + Add_2__y + + + double + Add_3__x + + + double + Add_3__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_1__z + + + double + Add_2__FuncValue + + + double + Add_3__FuncValue + + + double + Add_4__FuncValue + + + + + + 10/3/2006 - 19:8:42 + 18/3/2006 - 13:10:38 + 3.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 12:53:43 + 18/3/2006 - 12:53:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 996 + 195 + + + AddComponent + AddComponent + Add_1 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 12:53:43 + 18/3/2006 - 12:53:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 1149 + 387 + + + ? + ? + Loop + 4 + EndLoop + + Loop + + + double + x + + + + + double + x + + + + + + + ? + + + + ? + + + + ? + + + + 18/3/2006 - 12:56:11 + 18/3/2006 - 12:56:11 + 3.0 + ? + ? + Compute Node + 226 + 162 + + + ? + ? + EndLoop + 5 + Loop + + EndLoop + + + double + x + + + + + double + x + + + + + + + EndLoop + + + + 18/3/2006 - 12:56:11 + 18/3/2006 - 12:56:11 + 3.0 + ? + ? + Compute Node + 799 + 176 + + + AddComponent + AddComponent + Add_2 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 12:59:16 + 18/3/2006 - 12:59:16 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 418 + 12 + + + AddComponent + AddComponent + Add_3 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 13:0:47 + 18/3/2006 - 13:0:47 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 20 + 100 + + + AddComponent + AddComponent + Add_4 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 13:8:54 + 18/3/2006 - 13:8:54 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 603 + 115 + + + + + Add + z + Add_1 + x + + + + Loop + DoLoop + EndLoop + DoLoop + + + + Loop + x + Add_2 + x + + + + Loop + x + Add_4 + y + + + + EndLoop + DoLoop + Loop + DoLoop + + + + EndLoop + x + Add + x + + + + Add_2 + z + Add_4 + x + + + + Add_3 + z + Loop + x + + + + Add_4 + z + EndLoop + x + + + + + + aNewDataFlow_1 + Add__y + Add + y + + 7 + 3 + + + + + aNewDataFlow_1 + Add_1__y + Add_1 + y + + 7 + 3 + + + + + aNewDataFlow_1 + Add_2__y + Add_2 + y + + 7 + 1 + + + + + aNewDataFlow_1 + Add_3__x + Add_3 + x + + 7 + 3 + + + + + aNewDataFlow_1 + Add_3__y + Add_3 + y + + 7 + 10 + + + + + + + diff --git a/src/pyqt/salomefiles/onenode.xml b/src/pyqt/salomefiles/onenode.xml new file mode 100644 index 000000000..d68ebdd26 --- /dev/null +++ b/src/pyqt/salomefiles/onenode.xml @@ -0,0 +1,126 @@ + + + + + + ? + ? + aNewDataFlow_1 + 1 + ? + + aNewDataFlow_1 + + + double + MakeBoxDXDYDZ__theDX + + + double + MakeBoxDXDYDZ__theDY + + + double + MakeBoxDXDYDZ__theDZ + + + + + GEOM_Object + MakeBoxDXDYDZ__return + + + + + + 10/3/2006 - 19:8:42 + 10/3/2006 - 19:9:40 + 3.0 + ? + ? + ? + 0 + 0 + + + + + GEOM_Superv + GEOM_Superv + MakeBoxDXDYDZ + 0 + ? + + MakeBoxDXDYDZ + + + double + theDX + + + double + theDY + + + double + theDZ + + + + + GEOM_Object + return + + + + + + 10/3/2006 - 19:9:40 + 10/3/2006 - 19:9:40 + 3.0 + ? + localhost/FactoryServer + MakeBoxDXDYDZ from GEOM_Superv + 111 + 28 + + + + + + aNewDataFlow_1 + MakeBoxDXDYDZ__theDX + MakeBoxDXDYDZ + theDX + + 7 + 1 + + + + + aNewDataFlow_1 + MakeBoxDXDYDZ__theDY + MakeBoxDXDYDZ + theDY + + 7 + 1 + + + + + aNewDataFlow_1 + MakeBoxDXDYDZ__theDZ + MakeBoxDXDYDZ + theDZ + + 7 + 1 + + + + + + + diff --git a/src/pyqt/salomefiles/procmacro.xml b/src/pyqt/salomefiles/procmacro.xml new file mode 100644 index 000000000..93983e7cc --- /dev/null +++ b/src/pyqt/salomefiles/procmacro.xml @@ -0,0 +1,408 @@ + + + + + + ? + ? + aNewDataFlow + 1 + ? + + aNewDataFlow + + + double + Macro_GraphAdd_1__Add__y + + + double + Add__x + + + double + Add__y + + + double + Add_8__y + + + + + double + Macro_GraphAdd_1__Add__FuncValue + + + double + Macro_GraphAdd_1__Add_1__FuncValue + + + double + Add__FuncValue + + + double + Add_8__FuncValue + + + double + Add_8__z + + + + + + 2/4/2006 - 17:13:47 + 2/4/2006 - 22:0:48 + 3.0 + ? + ? + ? + 0 + 0 + + + + + ? + ? + Macro_GraphAdd_1 + 10 + GraphAdd_1 + + GraphAdd_1 + + + double + Add__x + + + double + Add__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_1__z + + + + + + + ? + + + + 2/4/2006 - 21:59:30 + 2/4/2006 - 21:59:30 + 3.0 + ? + ? + Macro Node + 361 + 81 + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 2/4/2006 - 22:0:1 + 2/4/2006 - 22:0:1 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 76 + 87 + + + AddComponent + AddComponent + Add_8 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 2/4/2006 - 22:0:36 + 2/4/2006 - 22:0:36 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 606 + 81 + + + + + Macro_GraphAdd_1 + Add_1__z + Add_8 + x + + + + Add + z + Macro_GraphAdd_1 + Add__x + + + + + + aNewDataFlow + Macro_GraphAdd_1__Add__y + Macro_GraphAdd_1 + Add__y + + 7 + 5 + + + + + aNewDataFlow + Add__x + Add + x + + 7 + 3 + + + + + aNewDataFlow + Add__y + Add + y + + 7 + 7 + + + + + aNewDataFlow + Add_8__y + Add_8 + y + + 7 + 7 + + + + + + + + + ? + ? + GraphAdd_1 + 1 + ? + + GraphAdd_1 + + + double + Add__x + + + double + Add__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_1__z + + + + + + 28/9/2005 - 16:2:26 + 2/4/2006 - 21:59:30 + 2.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 2/4/2006 - 21:59:30 + 2/4/2006 - 21:59:30 + 2.0 + ? + localhost/FactoryServer + Add from AddComponent + 233 + 71 + + + AddComponent + AddComponent + Add_1 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 2/4/2006 - 21:59:30 + 2/4/2006 - 21:59:30 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 523 + 72 + + + + + Add + z + Add_1 + x + + + + Add + z + Add_1 + y + + + + + + + diff --git a/src/pyqt/salomefiles/procmacro2.xml b/src/pyqt/salomefiles/procmacro2.xml new file mode 100644 index 000000000..c74d604a0 --- /dev/null +++ b/src/pyqt/salomefiles/procmacro2.xml @@ -0,0 +1,626 @@ + + + + + + ? + ? + aNewDataFlow + 1 + ? + + aNewDataFlow + + + double + Macro_GraphAdd_1__Add__y + + + double + Add__x + + + double + Add__y + + + double + Macro_GraphAdd_1_1__Add__y + + + + + double + Macro_GraphAdd_1__Add__FuncValue + + + double + Macro_GraphAdd_1__Add_1__FuncValue + + + double + Add__FuncValue + + + double + Add_8__FuncValue + + + double + Add_8__z + + + double + Macro_GraphAdd_1_1__Add__FuncValue + + + double + Macro_GraphAdd_1_1__Add_1__FuncValue + + + + + + 2/4/2006 - 17:13:47 + 2/4/2006 - 22:17:21 + 3.0 + ? + ? + ? + 0 + 0 + + + + + ? + ? + Macro_GraphAdd_1 + 10 + GraphAdd_1 + + GraphAdd_1 + + + double + Add__x + + + double + Add__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_1__z + + + + + + + ? + + + + 2/4/2006 - 21:59:30 + 2/4/2006 - 21:59:30 + 3.0 + ? + ? + Macro Node + 361 + 81 + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 2/4/2006 - 22:0:1 + 2/4/2006 - 22:0:1 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 76 + 87 + + + AddComponent + AddComponent + Add_8 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 2/4/2006 - 22:0:36 + 2/4/2006 - 22:0:36 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 637 + 61 + + + ? + ? + Macro_GraphAdd_1_1 + 10 + GraphAdd_1_1 + + GraphAdd_1_1 + + + double + Add__x + + + double + Add__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_1__z + + + + + + + ? + + + + 2/4/2006 - 22:16:53 + 2/4/2006 - 22:16:53 + 3.0 + ? + ? + ? + 0 + 0 + + + + + Macro_GraphAdd_1 + Add_1__z + Add_8 + x + + + + Add + z + Macro_GraphAdd_1 + Add__x + + + + Add + z + Macro_GraphAdd_1_1 + Add__x + + + + Macro_GraphAdd_1_1 + Add_1__z + Add_8 + y + + + + + + aNewDataFlow + Macro_GraphAdd_1__Add__y + Macro_GraphAdd_1 + Add__y + + 7 + 5 + + + + + aNewDataFlow + Add__x + Add + x + + 7 + 3 + + + + + aNewDataFlow + Add__y + Add + y + + 7 + 7 + + + + + aNewDataFlow + Macro_GraphAdd_1_1__Add__y + Macro_GraphAdd_1_1 + Add__y + + 7 + 9 + + + + + + + + + ? + ? + GraphAdd_1 + 1 + ? + + GraphAdd_1 + + + double + Add__x + + + double + Add__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_1__z + + + + + + 28/9/2005 - 16:2:26 + 2/4/2006 - 21:59:30 + 2.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 2/4/2006 - 21:59:30 + 2/4/2006 - 21:59:30 + 2.0 + ? + localhost/FactoryServer + Add from AddComponent + 233 + 71 + + + AddComponent + AddComponent + Add_1 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 2/4/2006 - 21:59:30 + 2/4/2006 - 21:59:30 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 523 + 72 + + + + + Add + z + Add_1 + x + + + + Add + z + Add_1 + y + + + + + + + + + ? + ? + GraphAdd_1_1 + 1 + ? + + GraphAdd_1_1 + + + double + Add__x + + + double + Add__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_1__z + + + + + + 28/9/2005 - 16:2:26 + 2/4/2006 - 22:16:53 + 2.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 2/4/2006 - 22:16:53 + 2/4/2006 - 22:16:53 + 2.0 + ? + localhost/FactoryServer + Add from AddComponent + 233 + 71 + + + AddComponent + AddComponent + Add_1 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 2/4/2006 - 22:16:53 + 2/4/2006 - 22:16:53 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 523 + 72 + + + + + Add + z + Add_1 + x + + + + Add + z + Add_1 + y + + + + + + + diff --git a/src/pyqt/salomefiles/procmacro3.xml b/src/pyqt/salomefiles/procmacro3.xml new file mode 100644 index 000000000..70048b411 --- /dev/null +++ b/src/pyqt/salomefiles/procmacro3.xml @@ -0,0 +1,817 @@ + + + + + + ? + ? + aNewDataFlow_1_1 + 1 + ? + + aNewDataFlow_1_1 + + + double + Macro_GraphAdd_1__Add__y + + + double + Macro_GraphAdd_1__Add_1__x + + + double + Macro_GraphAdd_1__Macro_GraphAdd_1_2__Add__y + + + double + Add__x + + + double + Add__y + + + double + Macro_GraphAdd_1_1__Add__y + + + + + double + Macro_GraphAdd_1__Add__FuncValue + + + double + Macro_GraphAdd_1__Add_1__FuncValue + + + double + Macro_GraphAdd_1__Macro_GraphAdd_1_2__Add__FuncValue + + + double + Add__FuncValue + + + double + Add_8__FuncValue + + + double + Add_8__z + + + double + Macro_GraphAdd_1_1__Add__FuncValue + + + double + Macro_GraphAdd_1_1__Add_1__FuncValue + + + + + + 2/4/2006 - 17:13:47 + 3/4/2006 - 9:6:34 + 3.0 + ? + ? + ? + 0 + 0 + + + + + ? + ? + Macro_GraphAdd_1 + 10 + GraphAdd_1_1 + + GraphAdd_1 + + + double + Add__x + + + double + Add__y + + + double + Add_1__x + + + double + Macro_GraphAdd_1_2__Add__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_1__z + + + double + Macro_GraphAdd_1_2__Add__FuncValue + + + + + + + ? + + + + 3/4/2006 - 9:6:34 + 3/4/2006 - 9:6:34 + 3.0 + ? + ? + Macro Node + 337 + 39 + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 3/4/2006 - 9:6:34 + 3/4/2006 - 9:6:34 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 76 + 87 + + + AddComponent + AddComponent + Add_8 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 3/4/2006 - 9:6:34 + 3/4/2006 - 9:6:34 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 637 + 61 + + + ? + ? + Macro_GraphAdd_1_1 + 10 + GraphAdd_1_1_1 + + GraphAdd_1_1 + + + double + Add__x + + + double + Add__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_1__z + + + + + + + ? + + + + 3/4/2006 - 9:6:34 + 3/4/2006 - 9:6:34 + 3.0 + ? + ? + Macro Node + 364 + 326 + + + + + Macro_GraphAdd_1 + Add_1__z + Add_8 + x + + + + Add + z + Macro_GraphAdd_1 + Add__x + + + + Add + z + Macro_GraphAdd_1_1 + Add__x + + + + Macro_GraphAdd_1_1 + Add_1__z + Add_8 + y + + + + + + aNewDataFlow_1_1 + Macro_GraphAdd_1__Add__y + Macro_GraphAdd_1 + Add__y + + 7 + 5 + + + + + aNewDataFlow_1_1 + Macro_GraphAdd_1__Add_1__x + Macro_GraphAdd_1 + Add_1__x + + 7 + 6 + + + + + aNewDataFlow_1_1 + Macro_GraphAdd_1__Macro_GraphAdd_1_2__Add__y + Macro_GraphAdd_1 + Macro_GraphAdd_1_2__Add__y + + 7 + 7 + + + + + aNewDataFlow_1_1 + Add__x + Add + x + + 7 + 3 + + + + + aNewDataFlow_1_1 + Add__y + Add + y + + 7 + 7 + + + + + aNewDataFlow_1_1 + Macro_GraphAdd_1_1__Add__y + Macro_GraphAdd_1_1 + Add__y + + 7 + 9 + + + + + + + + + ? + ? + GraphAdd_1_1 + 1 + ? + + GraphAdd_1_1 + + + double + Add__x + + + double + Add__y + + + double + Add_1__x + + + double + Macro_GraphAdd_1_2__Add__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_1__z + + + double + Macro_GraphAdd_1_2__Add__FuncValue + + + + + + 28/9/2005 - 16:2:26 + 3/4/2006 - 9:6:34 + 2.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 3/4/2006 - 9:6:34 + 3/4/2006 - 9:6:34 + 2.0 + ? + localhost/FactoryServer + Add from AddComponent + 87 + 43 + + + AddComponent + AddComponent + Add_1 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 3/4/2006 - 9:6:34 + 3/4/2006 - 9:6:34 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 523 + 72 + + + ? + ? + Macro_GraphAdd_1_2 + 10 + GraphAdd_1_2_1 + + GraphAdd_1_2 + + + double + Add__x + + + double + Add__y + + + + + double + Add__FuncValue + + + double + Add__z + + + + + + + ? + + + + 3/4/2006 - 9:6:34 + 3/4/2006 - 9:6:34 + 3.0 + ? + ? + Macro Node + 329 + 241 + + + + + Add + z + Macro_GraphAdd_1_2 + Add__x + + + + Macro_GraphAdd_1_2 + Add__z + Add_1 + y + + + + + + + + + ? + ? + GraphAdd_1_2_1 + 1 + ? + + GraphAdd_1_2_1 + + + double + Add__x + + + double + Add__y + + + + + double + Add__FuncValue + + + double + Add__z + + + + + + 28/9/2005 - 16:2:26 + 3/4/2006 - 9:6:34 + 2.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 3/4/2006 - 9:6:34 + 3/4/2006 - 9:6:34 + 2.0 + ? + localhost/FactoryServer + Add from AddComponent + 55 + 61 + + + + + + + + + ? + ? + GraphAdd_1_1_1 + 1 + ? + + GraphAdd_1_1_1 + + + double + Add__x + + + double + Add__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_1__z + + + + + + 28/9/2005 - 16:2:26 + 3/4/2006 - 9:6:34 + 2.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 3/4/2006 - 9:6:34 + 3/4/2006 - 9:6:34 + 2.0 + ? + localhost/FactoryServer + Add from AddComponent + 233 + 71 + + + AddComponent + AddComponent + Add_1 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 3/4/2006 - 9:6:34 + 3/4/2006 - 9:6:34 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 523 + 72 + + + + + Add + z + Add_1 + x + + + + Add + z + Add_1 + y + + + + + + + diff --git a/src/pyqt/salomefiles/simple2loops.xml b/src/pyqt/salomefiles/simple2loops.xml new file mode 100644 index 000000000..d5b9e7fd9 --- /dev/null +++ b/src/pyqt/salomefiles/simple2loops.xml @@ -0,0 +1,674 @@ + + + + + + ? + ? + aNewDataFlow_1_1 + 1 + ? + + aNewDataFlow_1_1 + + + double + Add__y + + + double + Add_1__y + + + double + Add_2__y + + + double + Add_3__y + + + double + Add_5__x + + + double + Add_5__y + + + double + Add_6__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_2__FuncValue + + + double + Add_3__FuncValue + + + double + Add_5__FuncValue + + + double + Add_6__FuncValue + + + double + Add_6__z + + + + + + 10/3/2006 - 19:8:42 + 23/3/2006 - 13:54:33 + 3.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 23/3/2006 - 13:54:3 + 23/3/2006 - 13:54:3 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 996 + 195 + + + AddComponent + AddComponent + Add_1 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 23/3/2006 - 13:54:3 + 23/3/2006 - 13:54:3 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 960 + 383 + + + ? + ? + Loop + 4 + EndLoop + + Loop + + + double + x + + + + + double + x + + + + + + + Init + + + + + More + + + + + + Next + + + + + 23/3/2006 - 13:54:3 + 23/3/2006 - 13:54:3 + 3.0 + ? + ? + Compute Node + 226 + 162 + + + ? + ? + EndLoop + 5 + Loop + + EndLoop + + + double + x + + + + + double + x + + + + + + + EndLoop + + + + 23/3/2006 - 13:54:3 + 23/3/2006 - 13:54:3 + 3.0 + ? + ? + Compute Node + 799 + 176 + + + AddComponent + AddComponent + Add_2 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 23/3/2006 - 13:54:3 + 23/3/2006 - 13:54:3 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 530 + 141 + + + AddComponent + AddComponent + Add_3 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 23/3/2006 - 13:54:3 + 23/3/2006 - 13:54:3 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 45 + 42 + + + ? + ? + Loop_1 + 4 + EndLoop_1 + + Loop_1 + + + double + x + + + + + double + x + + + + + + + Init + + + + + More + + + + + + Next + + + + + 23/3/2006 - 13:54:3 + 23/3/2006 - 13:54:3 + 3.0 + ? + ? + Compute Node + 147 + 330 + + + ? + ? + EndLoop_1 + 5 + Loop_1 + + EndLoop_1 + + + double + x + + + + + double + x + + + + + + + EndLoop + + + + 23/3/2006 - 13:54:3 + 23/3/2006 - 13:54:3 + 3.0 + ? + ? + Compute Node + 683 + 586 + + + AddComponent + AddComponent + Add_5 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 23/3/2006 - 13:54:3 + 23/3/2006 - 13:54:3 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 18 + 501 + + + AddComponent + AddComponent + Add_6 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 23/3/2006 - 13:54:3 + 23/3/2006 - 13:54:3 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 1084 + 555 + + + + + Add + z + Add_1 + x + + + + Add_1 + z + EndLoop_1 + x + + + + Loop + DoLoop + EndLoop + DoLoop + + + + Loop + x + Add_2 + x + + + + EndLoop + DoLoop + Loop + DoLoop + + + + EndLoop + x + Add + x + + + + Add_2 + z + EndLoop + x + + + + Add_3 + z + Loop + x + + + + Loop_1 + DoLoop + EndLoop_1 + DoLoop + + + + Loop_1 + x + Add_3 + x + + + + EndLoop_1 + DoLoop + Loop_1 + DoLoop + + + + EndLoop_1 + x + Add_6 + x + + + + Add_5 + z + Loop_1 + x + + + + + + aNewDataFlow_1_1 + Add__y + Add + y + + 7 + 3 + + + + + aNewDataFlow_1_1 + Add_1__y + Add_1 + y + + 7 + 3 + + + + + aNewDataFlow_1_1 + Add_2__y + Add_2 + y + + 7 + 1 + + + + + aNewDataFlow_1_1 + Add_3__y + Add_3 + y + + 7 + 10 + + + + + aNewDataFlow_1_1 + Add_5__x + Add_5 + x + + 7 + 1 + + + + + aNewDataFlow_1_1 + Add_5__y + Add_5 + y + + 7 + 2 + + + + + aNewDataFlow_1_1 + Add_6__y + Add_6 + y + + 7 + 6 + + + + + + + diff --git a/src/pyqt/salomefiles/threecompo.xml b/src/pyqt/salomefiles/threecompo.xml new file mode 100644 index 000000000..8b393840f --- /dev/null +++ b/src/pyqt/salomefiles/threecompo.xml @@ -0,0 +1,224 @@ + + + + + + ? + ? + aNewDataFlow + 1 + ? + + aNewDataFlow + + + double + Add__x + + + double + Add__y + + + + + double + Add_2__FuncValue + + + double + Add_2__z + + + + + + 22/2/2007 - 15:21:25 + 22/2/2007 - 15:23:16 + 3.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 22/2/2007 - 15:22:0 + 22/2/2007 - 15:22:0 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 62 + 173 + + + AddComponent + AddComponent + Add_1 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 22/2/2007 - 15:22:7 + 22/2/2007 - 15:22:7 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 427 + 177 + + + AddComponent + AddComponent + Add_2 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 22/2/2007 - 15:22:10 + 22/2/2007 - 15:22:10 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 741 + 175 + + + + + Add + FuncValue + Add_1 + x + + + + Add + z + Add_1 + y + + + + Add_1 + FuncValue + Add_2 + x + + + + Add_1 + z + Add_2 + y + + + + + + aNewDataFlow + Add__x + Add + x + + 7 + 3 + + + + + aNewDataFlow + Add__y + Add + y + + 7 + 4 + + + + + + + diff --git a/src/pyqt/salomefiles/threef.xml b/src/pyqt/salomefiles/threef.xml new file mode 100644 index 000000000..c952e54f1 --- /dev/null +++ b/src/pyqt/salomefiles/threef.xml @@ -0,0 +1,185 @@ + + + + + + ? + ? + aNewDataFlow_1 + 1 + ? + + aNewDataFlow_1 + + + double + f__a + + + + + double + f_2__a + + + + + + 10/3/2006 - 19:8:42 + 18/3/2006 - 13:51:19 + 3.0 + ? + ? + ? + 0 + 0 + + + + + ? + ? + f + 3 + ? + + f + + + double + a + + + + + double + a + + + + + + + f + + + + + 18/3/2006 - 13:47:40 + 18/3/2006 - 13:47:40 + 3.0 + ? + ? + Compute Node + 58 + 76 + + + ? + ? + f_1 + 3 + ? + + f_1 + + + double + a + + + + + double + a + + + + + + + f_1 + + + + + 18/3/2006 - 13:47:40 + 18/3/2006 - 13:47:40 + 3.0 + ? + ? + Compute Node + 343 + 74 + + + ? + ? + f_2 + 3 + ? + + f_2 + + + double + a + + + + + double + a + + + + + + + f_2 + + + + + 18/3/2006 - 13:47:40 + 18/3/2006 - 13:47:40 + 3.0 + ? + ? + Compute Node + 677 + 74 + + + + + f + a + f_1 + a + + + + f_1 + a + f_2 + a + + + + + + aNewDataFlow_1 + f__a + f + a + + 7 + 1 + + + + + + + diff --git a/src/pyqt/salomefiles/threenodes.xml b/src/pyqt/salomefiles/threenodes.xml new file mode 100644 index 000000000..44d36f545 --- /dev/null +++ b/src/pyqt/salomefiles/threenodes.xml @@ -0,0 +1,243 @@ + + + + + + ? + ? + aNewDataFlow_1 + 1 + ? + + aNewDataFlow_1 + + + double + MakeBoxDXDYDZ__theDX + + + double + MakeBoxDXDYDZ__theDY + + + double + MakeBoxDXDYDZ__theDZ + + + string + CreateHypothesis__anHyp + + + long + CreateHypothesis__studyId + + + + + boolean + AddHypothesis__res + + + + + + 10/3/2006 - 19:8:42 + 10/3/2006 - 19:16:0 + 3.0 + ? + ? + ? + 0 + 0 + + + + + GEOM_Superv + GEOM_Superv + MakeBoxDXDYDZ + 0 + ? + + MakeBoxDXDYDZ + + + double + theDX + + + double + theDY + + + double + theDZ + + + + + GEOM_Object + return + + + + + + 10/3/2006 - 19:9:40 + 10/3/2006 - 19:9:40 + 3.0 + ? + localhost/FactoryServer + MakeBoxDXDYDZ from GEOM_Superv + 79 + 31 + + + SMESH + SMESH + CreateHypothesis + 0 + ? + + CreateHypothesis + + + string + anHyp + + + long + studyId + + + + + SMESH_Hypothesis + aHyp + + + + + + 10/3/2006 - 19:14:2 + 10/3/2006 - 19:14:2 + 3.0 + ? + localhost/FactoryServer + CreateHypothesis from SMESH + 26 + 201 + + + SMESH + SMESH_Mesh + AddHypothesis + 0 + ? + + AddHypothesis + + + GEOM_Shape + aSubShape + + + SMESH_Hypothesis + aHyp + + + + + boolean + res + + + + + + 10/3/2006 - 19:15:5 + 10/3/2006 - 19:15:5 + 3.0 + ? + localhost/FactoryServer + AddHypothesis from SMESH + 384 + 131 + + + + + MakeBoxDXDYDZ + return + AddHypothesis + aSubShape + + + + CreateHypothesis + aHyp + AddHypothesis + aHyp + + + + + + aNewDataFlow_1 + MakeBoxDXDYDZ__theDX + MakeBoxDXDYDZ + theDX + + 7 + 1 + + + + + aNewDataFlow_1 + MakeBoxDXDYDZ__theDY + MakeBoxDXDYDZ + theDY + + 7 + 1 + + + + + aNewDataFlow_1 + MakeBoxDXDYDZ__theDZ + MakeBoxDXDYDZ + theDZ + + 7 + 1 + + + + + aNewDataFlow_1 + CreateHypothesis__anHyp + CreateHypothesis + anHyp + + 18 + + + + + + aNewDataFlow_1 + CreateHypothesis__studyId + CreateHypothesis + studyId + + 3 + 1 + + + + + + + diff --git a/src/pyqt/salomefiles/twoconnectednodes.xml b/src/pyqt/salomefiles/twoconnectednodes.xml new file mode 100644 index 000000000..41fae77a7 --- /dev/null +++ b/src/pyqt/salomefiles/twoconnectednodes.xml @@ -0,0 +1,155 @@ + + + + + + ? + ? + aNewDataFlow_1 + 1 + ? + + aNewDataFlow_1 + + + string + CreateHypothesis__anHyp + + + long + CreateHypothesis__studyId + + + GEOM_Shape + AddHypothesis__aSubShape + + + + + boolean + AddHypothesis__res + + + + + + 10/3/2006 - 19:8:42 + 10/3/2006 - 19:16:19 + 3.0 + ? + ? + ? + 0 + 0 + + + + + SMESH + SMESH + CreateHypothesis + 0 + ? + + CreateHypothesis + + + string + anHyp + + + long + studyId + + + + + SMESH_Hypothesis + aHyp + + + + + + 10/3/2006 - 19:14:2 + 10/3/2006 - 19:14:2 + 3.0 + ? + localhost/FactoryServer + CreateHypothesis from SMESH + 26 + 201 + + + SMESH + SMESH_Mesh + AddHypothesis + 0 + ? + + AddHypothesis + + + GEOM_Shape + aSubShape + + + SMESH_Hypothesis + aHyp + + + + + boolean + res + + + + + + 10/3/2006 - 19:15:5 + 10/3/2006 - 19:15:5 + 3.0 + ? + localhost/FactoryServer + AddHypothesis from SMESH + 384 + 131 + + + + + CreateHypothesis + aHyp + AddHypothesis + aHyp + + + + + + aNewDataFlow_1 + CreateHypothesis__anHyp + CreateHypothesis + anHyp + + 18 + + + + + + aNewDataFlow_1 + CreateHypothesis__studyId + CreateHypothesis + studyId + + 3 + 1 + + + + + + + diff --git a/src/pyqt/salomefiles/twoloops.xml b/src/pyqt/salomefiles/twoloops.xml new file mode 100644 index 000000000..1e5bc48bc --- /dev/null +++ b/src/pyqt/salomefiles/twoloops.xml @@ -0,0 +1,732 @@ + + + + + + ? + ? + aNewDataFlow_1_1 + 1 + ? + + aNewDataFlow_1_1 + + + double + Add__y + + + double + Add_1__y + + + double + Add_2__y + + + double + Add_3__y + + + double + Add_5__x + + + double + Add_5__y + + + double + Add_6__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_2__FuncValue + + + double + Add_3__FuncValue + + + double + Add_4__FuncValue + + + double + Add_5__FuncValue + + + double + Add_6__FuncValue + + + double + Add_6__z + + + + + + 10/3/2006 - 19:8:42 + 19/3/2006 - 18:27:43 + 3.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 19/3/2006 - 18:27:43 + 19/3/2006 - 18:27:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 996 + 195 + + + AddComponent + AddComponent + Add_1 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 19/3/2006 - 18:27:43 + 19/3/2006 - 18:27:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 960 + 383 + + + ? + ? + Loop + 4 + EndLoop + + Loop + + + double + x + + + + + double + x + + + + + + + Init + + + + + More + + + + + + Next + + + + + 19/3/2006 - 18:27:43 + 19/3/2006 - 18:27:43 + 3.0 + ? + ? + Compute Node + 226 + 162 + + + ? + ? + EndLoop + 5 + Loop + + EndLoop + + + double + x + + + + + double + x + + + + + + + EndLoop + + + + 19/3/2006 - 18:27:43 + 19/3/2006 - 18:27:43 + 3.0 + ? + ? + Compute Node + 799 + 176 + + + AddComponent + AddComponent + Add_2 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 19/3/2006 - 18:27:43 + 19/3/2006 - 18:27:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 418 + 12 + + + AddComponent + AddComponent + Add_3 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 19/3/2006 - 18:27:43 + 19/3/2006 - 18:27:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 45 + 42 + + + AddComponent + AddComponent + Add_4 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 19/3/2006 - 18:27:43 + 19/3/2006 - 18:27:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 603 + 115 + + + ? + ? + Loop_1 + 4 + EndLoop_1 + + Loop_1 + + + double + x + + + + + double + x + + + + + + + Init + + + + + More + + + + + + Next + + + + + 19/3/2006 - 18:27:43 + 19/3/2006 - 18:27:43 + 3.0 + ? + ? + Compute Node + 147 + 330 + + + ? + ? + EndLoop_1 + 5 + Loop_1 + + EndLoop_1 + + + double + x + + + + + double + x + + + + + + + EndLoop + + + + 19/3/2006 - 18:27:43 + 19/3/2006 - 18:27:43 + 3.0 + ? + ? + Compute Node + 683 + 586 + + + AddComponent + AddComponent + Add_5 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 19/3/2006 - 18:27:43 + 19/3/2006 - 18:27:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 18 + 501 + + + AddComponent + AddComponent + Add_6 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 19/3/2006 - 18:27:43 + 19/3/2006 - 18:27:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 1084 + 555 + + + + + Add + z + Add_1 + x + + + + Add_1 + z + EndLoop_1 + x + + + + Loop + DoLoop + EndLoop + DoLoop + + + + Loop + x + Add_2 + x + + + + Loop + x + Add_4 + y + + + + EndLoop + DoLoop + Loop + DoLoop + + + + EndLoop + x + Add + x + + + + Add_2 + z + Add_4 + x + + + + Add_3 + z + Loop + x + + + + Add_4 + z + EndLoop + x + + + + Loop_1 + DoLoop + EndLoop_1 + DoLoop + + + + Loop_1 + x + Add_3 + x + + + + EndLoop_1 + DoLoop + Loop_1 + DoLoop + + + + EndLoop_1 + x + Add_6 + x + + + + Add_5 + z + Loop_1 + x + + + + + + aNewDataFlow_1_1 + Add__y + Add + y + + 7 + 3 + + + + + aNewDataFlow_1_1 + Add_1__y + Add_1 + y + + 7 + 3 + + + + + aNewDataFlow_1_1 + Add_2__y + Add_2 + y + + 7 + 1 + + + + + aNewDataFlow_1_1 + Add_3__y + Add_3 + y + + 7 + 10 + + + + + aNewDataFlow_1_1 + Add_5__x + Add_5 + x + + 7 + 1 + + + + + aNewDataFlow_1_1 + Add_5__y + Add_5 + y + + 7 + 2 + + + + + aNewDataFlow_1_1 + Add_6__y + Add_6 + y + + 7 + 6 + + + + + + + diff --git a/src/pyqt/salomefiles/twoloopsandf.xml b/src/pyqt/salomefiles/twoloopsandf.xml new file mode 100644 index 000000000..7ff6c310f --- /dev/null +++ b/src/pyqt/salomefiles/twoloopsandf.xml @@ -0,0 +1,936 @@ + + + + + + ? + ? + aNewDataFlow_1 + 1 + ? + + aNewDataFlow_1 + + + double + Add__y + + + double + Add_1__y + + + double + Add_2__y + + + double + Add_3__y + + + double + Add_5__x + + + double + Add_5__y + + + double + Add_6__y + + + double + Add_7__y + + + + + double + Add__FuncValue + + + double + Add_1__FuncValue + + + double + Add_2__FuncValue + + + double + Add_3__FuncValue + + + double + Add_4__FuncValue + + + double + Add_5__FuncValue + + + double + Add_6__FuncValue + + + double + Add_7__FuncValue + + + double + Add_7__z + + + double + f_2__a + + + + + + 10/3/2006 - 19:8:42 + 18/3/2006 - 13:43:15 + 3.0 + ? + ? + ? + 0 + 0 + + + + + AddComponent + AddComponent + Add + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 12:53:43 + 18/3/2006 - 12:53:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 996 + 195 + + + AddComponent + AddComponent + Add_1 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 12:53:43 + 18/3/2006 - 12:53:43 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 960 + 383 + + + ? + ? + Loop + 4 + EndLoop + + Loop + + + double + x + + + + + double + x + + + + + + + ? + + + + ? + + + + ? + + + + 18/3/2006 - 12:56:11 + 18/3/2006 - 12:56:11 + 3.0 + ? + ? + Compute Node + 226 + 162 + + + ? + ? + EndLoop + 5 + Loop + + EndLoop + + + double + x + + + + + double + x + + + + + + + EndLoop + + + + 18/3/2006 - 12:56:11 + 18/3/2006 - 12:56:11 + 3.0 + ? + ? + Compute Node + 799 + 176 + + + AddComponent + AddComponent + Add_2 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 12:59:16 + 18/3/2006 - 12:59:16 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 418 + 12 + + + AddComponent + AddComponent + Add_3 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 13:0:47 + 18/3/2006 - 13:0:47 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 45 + 42 + + + AddComponent + AddComponent + Add_4 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 13:8:54 + 18/3/2006 - 13:8:54 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 603 + 115 + + + ? + ? + Loop_1 + 4 + EndLoop_1 + + Loop_1 + + + double + x + + + + + double + x + + + + + + + ? + + + + ? + + + + ? + + + + 18/3/2006 - 13:16:39 + 18/3/2006 - 13:16:39 + 3.0 + ? + ? + Compute Node + 147 + 330 + + + ? + ? + EndLoop_1 + 5 + Loop_1 + + EndLoop_1 + + + double + x + + + + + double + x + + + + + + + EndLoop + + + + 18/3/2006 - 13:16:39 + 18/3/2006 - 13:16:39 + 3.0 + ? + ? + Compute Node + 683 + 586 + + + AddComponent + AddComponent + Add_5 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 13:18:57 + 18/3/2006 - 13:18:57 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 18 + 501 + + + AddComponent + AddComponent + Add_6 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 13:19:23 + 18/3/2006 - 13:19:23 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 1084 + 555 + + + AddComponent + AddComponent + Add_7 + 0 + ? + + Add + + + double + x + + + double + y + + + + + double + FuncValue + + + double + z + + + + + + 18/3/2006 - 13:33:40 + 18/3/2006 - 13:33:40 + 3.0 + ? + localhost/FactoryServer + Add from AddComponent + 464 + 262 + + + ? + ? + f + 3 + ? + + f + + + double + a + + + + + double + a + + + + + + + f + + + + + 18/3/2006 - 13:41:45 + 18/3/2006 - 13:41:45 + 3.0 + ? + ? + Compute Node + 201 + 644 + + + ? + ? + f_1 + 3 + ? + + f_1 + + + double + a + + + + + double + a + + + + + + + f_1 + + + + + 18/3/2006 - 13:42:35 + 18/3/2006 - 13:42:35 + 3.0 + ? + ? + Compute Node + 408 + 671 + + + ? + ? + f_2 + 3 + ? + + f_2 + + + double + a + + + + + double + a + + + + + + + f_2 + + + + + 18/3/2006 - 13:42:42 + 18/3/2006 - 13:42:42 + 3.0 + ? + ? + Compute Node + 619 + 685 + + + + + Add + z + Add_1 + x + + + + Add_1 + z + EndLoop_1 + x + + + + Loop + DoLoop + EndLoop + DoLoop + + + + Loop + x + Add_2 + x + + + + Loop + x + Add_4 + y + + + + Loop + x + Add_7 + x + + + + EndLoop + DoLoop + Loop + DoLoop + + + + EndLoop + x + Add + x + + + + Add_2 + z + Add_4 + x + + + + Add_3 + z + Loop + x + + + + Add_4 + z + EndLoop + x + + + + Loop_1 + DoLoop + EndLoop_1 + DoLoop + + + + Loop_1 + x + Add_3 + x + + + + EndLoop_1 + DoLoop + Loop_1 + DoLoop + + + + EndLoop_1 + x + Add_6 + x + + + + Add_5 + z + Loop_1 + x + + + + Add_6 + z + f + a + + + + Add_7 + Gate + EndLoop + Gate + + + + f + a + f_1 + a + + + + f_1 + a + f_2 + a + + + + + + aNewDataFlow_1 + Add__y + Add + y + + 7 + 3 + + + + + aNewDataFlow_1 + Add_1__y + Add_1 + y + + 7 + 3 + + + + + aNewDataFlow_1 + Add_2__y + Add_2 + y + + 7 + 1 + + + + + aNewDataFlow_1 + Add_3__y + Add_3 + y + + 7 + 10 + + + + + aNewDataFlow_1 + Add_5__x + Add_5 + x + + 7 + 1 + + + + + aNewDataFlow_1 + Add_5__y + Add_5 + y + + 7 + 2 + + + + + aNewDataFlow_1 + Add_6__y + Add_6 + y + + 7 + 6 + + + + + aNewDataFlow_1 + Add_7__y + Add_7 + y + + 7 + 3 + + + + + + + diff --git a/src/pyqt/salomefiles/twonodes.xml b/src/pyqt/salomefiles/twonodes.xml new file mode 100644 index 000000000..ecb853efe --- /dev/null +++ b/src/pyqt/salomefiles/twonodes.xml @@ -0,0 +1,196 @@ + + + + + + ? + ? + aNewDataFlow_1 + 1 + ? + + aNewDataFlow_1 + + + double + MakeBoxDXDYDZ__theDX + + + double + MakeBoxDXDYDZ__theDY + + + double + MakeBoxDXDYDZ__theDZ + + + string + CreateHypothesis__anHyp + + + long + CreateHypothesis__studyId + + + + + GEOM_Object + MakeBoxDXDYDZ__return + + + SMESH_Hypothesis + CreateHypothesis__aHyp + + + + + + 10/3/2006 - 19:8:42 + 10/3/2006 - 19:14:2 + 3.0 + ? + ? + ? + 0 + 0 + + + + + GEOM_Superv + GEOM_Superv + MakeBoxDXDYDZ + 0 + ? + + MakeBoxDXDYDZ + + + double + theDX + + + double + theDY + + + double + theDZ + + + + + GEOM_Object + return + + + + + + 10/3/2006 - 19:9:40 + 10/3/2006 - 19:9:40 + 3.0 + ? + localhost/FactoryServer + MakeBoxDXDYDZ from GEOM_Superv + 111 + 28 + + + SMESH + SMESH + CreateHypothesis + 0 + ? + + CreateHypothesis + + + string + anHyp + + + long + studyId + + + + + SMESH_Hypothesis + aHyp + + + + + + 10/3/2006 - 19:14:2 + 10/3/2006 - 19:14:2 + 3.0 + ? + localhost/FactoryServer + CreateHypothesis from SMESH + 391 + 108 + + + + + + aNewDataFlow_1 + MakeBoxDXDYDZ__theDX + MakeBoxDXDYDZ + theDX + + 7 + 1 + + + + + aNewDataFlow_1 + MakeBoxDXDYDZ__theDY + MakeBoxDXDYDZ + theDY + + 7 + 1 + + + + + aNewDataFlow_1 + MakeBoxDXDYDZ__theDZ + MakeBoxDXDYDZ + theDZ + + 7 + 1 + + + + + aNewDataFlow_1 + CreateHypothesis__anHyp + CreateHypothesis + anHyp + + 18 + + + + + + aNewDataFlow_1 + CreateHypothesis__studyId + CreateHypothesis + studyId + + 3 + 1 + + + + + + + diff --git a/src/pyqt/yacsedit.py b/src/pyqt/yacsedit.py new file mode 100644 index 000000000..cd86bfebf --- /dev/null +++ b/src/pyqt/yacsedit.py @@ -0,0 +1,21 @@ +# -*- coding: iso-8859-1 -*- +import glob +import SALOMERuntime +import pilot +import salomeloader +from gui import Item +from gui import Items +from gui import adapt +from qt import * +from gui.Appli import Appli + +SALOMERuntime.RuntimeSALOME_setRuntime() + +loader=salomeloader.SalomeLoader() + +app = QApplication(sys.argv) +t=Appli() +app.setMainWidget(t) +t.show() +app.exec_loop() + diff --git a/src/pyqt/yacsfiles/forloop3.xml b/src/pyqt/yacsfiles/forloop3.xml new file mode 100644 index 000000000..5360520d0 --- /dev/null +++ b/src/pyqt/yacsfiles/forloop3.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print a + return p1 + + + + + + + + nnstep + b1 nsteps + + + b1.node2 p1 + 23 + + + diff --git a/src/pyqt/yacsfiles/while1.xml b/src/pyqt/yacsfiles/while1.xml new file mode 100644 index 000000000..bfb900560 --- /dev/null +++ b/src/pyqt/yacsfiles/while1.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print "p1:",p1 + + return p1,condition + + + + + + node2condition + b1 condition + node2p1 + node2 p1 + + + + ncondition + b1 condition + + + b1.node2 p1 + 23 + + + diff --git a/src/runtime/CORBACORBAConv.cxx b/src/runtime/CORBACORBAConv.cxx index c8440ef3c..be26cb671 100644 --- a/src/runtime/CORBACORBAConv.cxx +++ b/src/runtime/CORBACORBAConv.cxx @@ -1,29 +1,31 @@ - -#include "CORBACORBAConv.hxx" #include "TypeConversions.hxx" +#include "CORBACORBAConv.hxx" +#include "CORBAPorts.hxx" using namespace YACS::ENGINE; using namespace std; CorbaCorba::CorbaCorba(InputCorbaPort* p) - : ProxyPort(p), Port(p->getNode()) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) { } -//!Convertit un Any convertible en CORBA::Any +//!Convert a CORBA::Any to a CORBA::Any /*! - * \param data : CORBA::Any object + * transition method from const void* to CORBA::Any* + * \param data : const void * data */ - void CorbaCorba::put(const void *data) throw(ConversionException) { put((CORBA::Any *)data); } +//!Convert a CORBA::Any to a CORBA::Any +/*! + * \param data : CORBA::Any object + */ void CorbaCorba::put(CORBA::Any *data) throw(ConversionException) { - //conversion du Any data en any attendu (de type type()) - - CORBA::Any *a = convertCorbaCorba(type(),data); + CORBA::Any *a = convertCorbaCorba(edGetType(),data); _port->put(a); } diff --git a/src/runtime/CORBACORBAConv.hxx b/src/runtime/CORBACORBAConv.hxx index f9b47bd16..37c8a1a7c 100644 --- a/src/runtime/CORBACORBAConv.hxx +++ b/src/runtime/CORBACORBAConv.hxx @@ -1,15 +1,20 @@ #ifndef __CORBACORBACONV_HXX__ #define __CORBACORBACONV_HXX__ -#include "RuntimeSALOME.hxx" +#include +#include "InputPort.hxx" +#include "ConversionException.hxx" namespace YACS { namespace ENGINE { - - // Ports adaptateurs Corba->Corba pour les différents types - + class InputCorbaPort; +/*! \brief Class for conversion from CORBA Output port to CORBA Input port + * + * \ingroup Ports + * + */ class CorbaCorba : public ProxyPort { public: diff --git a/src/runtime/CORBAComponent.cxx b/src/runtime/CORBAComponent.cxx new file mode 100644 index 000000000..3084ee7ec --- /dev/null +++ b/src/runtime/CORBAComponent.cxx @@ -0,0 +1,170 @@ +//To trace CORBA ref count, uncomment the following line +//#define REFCNT +#ifdef REFCNT +#define private public +#include +#endif + +#include "RuntimeSALOME.hxx" +#include "CORBAComponent.hxx" +#include "CORBANode.hxx" + +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +const char CORBAComponent::KIND[]="CORBA"; + +//! CORBAComponent constructor +CORBAComponent::CORBAComponent(const std::string& name): ComponentInstance(name) +{ + _objComponent=CORBA::Object::_nil(); +} + +//! CORBAComponent copy constructor +CORBAComponent::CORBAComponent(const CORBAComponent& other):ComponentInstance(other) +{ + _objComponent=CORBA::Object::_nil(); +} + +CORBAComponent::~CORBAComponent() +{ +#ifdef REFCNT + DEBTRACE( "+++++++++++++++++" << getName() << " +++++++++++++++++" ); + if(_objComponent != CORBA::Object::_nil()) + { + std::cerr << "CORBAComponent::destructor:refcount: " <<_objComponent->_PR_getobj()->pd_refCount << std::endl; + } +#endif +} + +std::string CORBAComponent::getKind() const +{ + return KIND; +} + +//! Unload the component +void CORBAComponent::unload() +{ + //Not implemented + std::cerr << "CORBAComponent::unload : not implemented " << std::endl; +} + +CORBA::Object_ptr CORBAComponent::getCompoPtr() +{ +#ifdef REFCNT + std::cerr << "CORBAComponent::getCompoPtr:refCount: " <<_objComponent->_PR_getobj()->pd_refCount << std::endl; +#endif + return CORBA::Object::_duplicate(_objComponent); +} + +//! Is the component instance already loaded ? +bool CORBAComponent::isLoaded() +{ + if(CORBA::is_nil(_objComponent)) + return false; + else + return true; +} + +//! Load the component +void CORBAComponent::load() +{ + DEBTRACE( "CORBAComponent::load" ); + CORBA::ORB_ptr orb; + try + { + DEBTRACE( "+++++++++++++++++" << getName() << " +++++++++++++++++" ); + orb = getSALOMERuntime()->getOrb(); + _objComponent= orb->string_to_object(getName().c_str()); +#ifdef REFCNT + std::cerr << "CORBAComponent::load:refCount: " <<_objComponent->_PR_getobj()->pd_refCount << std::endl; +#endif + } + catch(CORBA::COMM_FAILURE& ex) + { + cerr << "Caught system exception COMM_FAILURE -- unable to contact the " + << "object." << endl; + throw Exception("Execution problem"); + } + catch(CORBA::SystemException& ex) + { + cerr << "Caught a CORBA::SystemException." ; + CORBA::Any tmp; + tmp <<= ex; + CORBA::TypeCode_var tc = tmp.type(); + const char *p = tc->name(); + if ( *p != '\0' ) + cerr <id(); + cerr << endl; + throw Exception("Execution problem"); + } + catch(CORBA::Exception& ex) + { + cerr << "Caught CORBA::Exception. " ; + CORBA::Any tmp; + tmp <<= ex; + CORBA::TypeCode_var tc = tmp.type(); + const char *p = tc->name(); + if ( *p != '\0' ) + cerr <id(); + cerr << endl; + throw Exception("Execution problem"); + } + catch(omniORB::fatalException& fe) + { + cerr << "Caught omniORB::fatalException:" << endl; + cerr << " file: " << fe.file() << endl; + cerr << " line: " << fe.line() << endl; + cerr << " mesg: " << fe.errmsg() << endl; + throw Exception("Execution problem"); + } + catch(...) + { + cerr << "Caught unknown exception." << endl; + throw Exception("Execution problem"); + } + if( CORBA::is_nil(_objComponent) ) + { + cerr << "Can't get reference to object (or it was nil)." << endl; + throw Exception("Execution problem"); + } + //TODO: if IOR is valid but the component does not exist, it works (bad) +} + +//! Create a ServiceNode with this component instance and no input or output port +/*! + * \param name : node name + * \return a new CORBANode node + */ +ServiceNode* CORBAComponent::createNode(const std::string& name) +{ + CORBANode* node= new CORBANode(name); + node->setComponent(this); + return node; +} + +//! Clone the component instance +ComponentInstance* CORBAComponent::clone() const +{ + //no real need to clone a CORBA Component : there is no component instance loading + incrRef(); + return (ComponentInstance*)this; + //return new CORBAComponent(*this); +} + +std::string CORBAComponent::getFileRepr() const +{ + ostringstream stream; + stream << "" << getName() << ""; + return stream.str(); +} diff --git a/src/runtime/CORBAComponent.hxx b/src/runtime/CORBAComponent.hxx new file mode 100644 index 000000000..f04863516 --- /dev/null +++ b/src/runtime/CORBAComponent.hxx @@ -0,0 +1,40 @@ +#ifndef _CORBACOMPONENT_HXX_ +#define _CORBACOMPONENT_HXX_ + +#include "ComponentInstance.hxx" +#include + +namespace YACS +{ + namespace ENGINE + { + class ServiceNode; + +/*! \brief Class for CORBA component instance + * + * \ingroup Nodes + * + */ + class CORBAComponent : public ComponentInstance + { + public: + CORBAComponent(const std::string& name); + CORBAComponent(const CORBAComponent& other); + virtual ~CORBAComponent(); + virtual void load(); + virtual void unload(); + virtual bool isLoaded(); + virtual ServiceNode* createNode(const std::string& name); + virtual ComponentInstance* clone() const; + virtual std::string getFileRepr() const; + virtual CORBA::Object_ptr getCompoPtr(); + public: + static const char KIND[]; + virtual std::string getKind() const; + protected: + CORBA::Object_var _objComponent; + }; + } +} + +#endif diff --git a/src/runtime/CORBACppConv.cxx b/src/runtime/CORBACppConv.cxx new file mode 100644 index 000000000..442241840 --- /dev/null +++ b/src/runtime/CORBACppConv.cxx @@ -0,0 +1,59 @@ + +#include "TypeConversions.hxx" +#include "CORBACppConv.hxx" + +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; + +namespace YACS +{ + namespace ENGINE + { + Any * convertCorbaCpp(const TypeCode *t, CORBA::Any *A) + { + return convertCorbaNeutral(t, A); + } + + CorbaCpp::CorbaCpp(InputPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) + { + } + + //!Convert a CORBA::Any that is convertible to a YACS::ENGINE::Any * and send it to proxy port + /*! + * \param data : CORBA::Any object as a void * pointer + */ + + void CorbaCpp::put(const void *data) throw(ConversionException) + { + put((CORBA::Any *)data); + } + + //!Convert a CORBA::Any that is convertible to a YACS::ENGINE::Any * and send it to proxy port + /*! + * \param data : CORBA::Any object + */ + void CorbaCpp::put(CORBA::Any *data) throw(ConversionException) + { + DEBTRACE("CorbaCpp::put"); + YACS::ENGINE::Any *ob; + ob= convertCorbaCpp(edGetType(),data); + DEBTRACE("refcnt: " << ob->getRefCnt()); + DEBTRACE(_port->getName()); + _port->put(ob); + // ob has been created in convertCorbaNeutral. _port has normally called incrRef + ob->decrRef(); + DEBTRACE("after put refcnt: " << ob->getRefCnt()) + } + + int isAdaptableCppCorba(const TypeCode *t1,const TypeCode *t2) + { + return isAdaptableNeutralCorba(t1, t2); + } + } +} + diff --git a/src/runtime/CORBACppConv.hxx b/src/runtime/CORBACppConv.hxx new file mode 100644 index 000000000..bf3fff463 --- /dev/null +++ b/src/runtime/CORBACppConv.hxx @@ -0,0 +1,25 @@ +#ifndef __CORBACPPCONV_HXX__ +#define __CORBACPPCONV_HXX__ + +#include + +#include "InputPort.hxx" +#include "ConversionException.hxx" + +namespace YACS +{ + namespace ENGINE + { + // Adaptator Ports Corba->C++ + + class CorbaCpp : public ProxyPort + { + public: + CorbaCpp(InputPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(CORBA::Any *data) throw(ConversionException); + }; + int isAdaptableCppCorba(const TypeCode *t1,const TypeCode *t2); + } +} +#endif diff --git a/src/runtime/CORBANeutralConv.cxx b/src/runtime/CORBANeutralConv.cxx new file mode 100644 index 000000000..cb18ad681 --- /dev/null +++ b/src/runtime/CORBANeutralConv.cxx @@ -0,0 +1,43 @@ + +#include "TypeConversions.hxx" +#include "CORBANeutralConv.hxx" + +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +CorbaNeutral::CorbaNeutral(InputPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{ +} + +//!Convert a CORBA::Any that is convertible to a YACS::ENGINE::Any * and send it to proxy port +/*! + * \param data : CORBA::Any object as a void * pointer + */ + +void CorbaNeutral::put(const void *data) throw(ConversionException) +{ + put((CORBA::Any *)data); +} + +//!Convert a CORBA::Any that is convertible to a YACS::ENGINE::Any * and send it to proxy port +/*! + * \param data : CORBA::Any object + */ +void CorbaNeutral::put(CORBA::Any *data) throw(ConversionException) +{ + DEBTRACE( "CorbaNeutral::put" ) + YACS::ENGINE::Any *ob; + ob=convertCorbaNeutral(edGetType(),data); + DEBTRACE("before put refcnt: " << ob->getRefCnt()) + DEBTRACE( _port->getName() ) + _port->put(ob); + // ob has been created in convertCorbaNeutral. _port has normally called incRef + ob->decrRef(); + DEBTRACE("after put refcnt: " << ob->getRefCnt()) +} diff --git a/src/runtime/CORBANeutralConv.hxx b/src/runtime/CORBANeutralConv.hxx new file mode 100644 index 000000000..46a95f20c --- /dev/null +++ b/src/runtime/CORBANeutralConv.hxx @@ -0,0 +1,24 @@ +#ifndef __CORBANEUTRALCONV_HXX__ +#define __CORBANEUTRALCONV_HXX__ + +#include + +#include "InputPort.hxx" +#include "ConversionException.hxx" + +namespace YACS +{ + namespace ENGINE + { + // Adaptator Ports Corba->Neutral for several types + + class CorbaNeutral : public ProxyPort + { + public: + CorbaNeutral(InputPort* 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 index 49469e470..2014c46c5 100644 --- a/src/runtime/CORBANode.cxx +++ b/src/runtime/CORBANode.cxx @@ -1,158 +1,486 @@ -#include "CORBANode.hxx" +//#define REFCNT +#ifdef REFCNT +#define private public +#define protected public +#include +#include +#endif + #include "RuntimeSALOME.hxx" +#include "CORBANode.hxx" +#include "CORBAComponent.hxx" +#include "SalomeComponent.hxx" +#include "CORBAPorts.hxx" +#include "OutputDataStreamPort.hxx" +#include "CalStreamPort.hxx" +#include "InPort.hxx" + +#ifdef SALOME_KERNEL +#include "SALOME_NamingService.hxx" +#include "SALOME_LifeCycleCORBA.hxx" +#endif #include #include +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" using namespace YACS::ENGINE; using namespace std; -CORBANode::CORBANode(const std::string& name): ElementaryNode(name) +const char CORBANode::IMPL_NAME[]="CORBA"; +const char CORBANode::KIND[]="CORBA"; + +std::string CORBANode::getKind() const { - _implementation = "CORBA"; - cerr << "CORBANode::CORBANode " << name << endl; + return KIND; } -void CORBANode::set_ref(const string& ref) +//! CORBANode constructor +CORBANode::CORBANode(const std::string& name): ServiceNode(name) { - _ref = ref; + _implementation=IMPL_NAME; } -void CORBANode::set_method(const string& method) +CORBANode::CORBANode(const CORBANode& other,ComposedNode *father):ServiceNode(other,father) { - _method = method; + _implementation=IMPL_NAME; } +//! Execute the service on the component associated to the node 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 ; - } + DEBTRACE( "+++++++++++++ CorbaNode::execute: " << getName() << " +++++++++++++++" ); { - //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()); + //DII request building : + // a service gets all its in parameters first + // then all its out parameters + // no inout parameters + // the return value (if any) is the first out parameter + // not yet user exception (only CORBA exception) + + CORBA::Object_var objComponent=((CORBAComponent*)_component)->getCompoPtr(); + CORBA::Request_var req = objComponent->_request(_method.c_str()); CORBA::NVList_ptr arguments = req->arguments() ; - cerr << "+++++++++++++++++CorbaNode::inputs+++++++++++++++++" << endl; + DEBTRACE( "+++++++++++++++++CorbaNode::inputs+++++++++++++++++" ) int in_param=0; - //les parametres in - set::iterator iter2; + //in parameters + list::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; + InputCorbaPort *p=(InputCorbaPort *)*iter2; + DEBTRACE( "port name: " << p->getName() ) + DEBTRACE( "port kind: " << p->edGetType()->kind() ) + CORBA::Any* ob=p->getAny(); +#ifdef _DEVDEBUG_ + CORBA::TypeCode_var typcod= ob->type(); + switch(p->edGetType()->kind()) + { + case Double: + CORBA::Double d; + *ob >>= d; + DEBTRACE( d ) + break; + case Int: + CORBA::Long l; + *ob >>= l; + DEBTRACE( l ) + break; + case String: + const char *s; + *ob >>= s; + DEBTRACE( s ) + break; + case Bool: + CORBA::Boolean b; + if(*ob >>= CORBA::Any::to_boolean(b)) + DEBTRACE( b ) + else + DEBTRACE( "not a boolean" ) + break; + case Objref: + DEBTRACE( typcod->id() ) + break; + default: + break; + } +#endif + //add_value makes a copy of any (*ob). This copy will be deleted with the request + 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; + //output parameters + DEBTRACE( "+++++++++++++++++CorbaNode::outputs+++++++++++++++++" ) + list::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 ); + OutputCorbaPort *p=(OutputCorbaPort *)*iter; + DEBTRACE( "port name: " << p->getName() ) + DEBTRACE( "port kind: " << p->edGetType()->kind() ) + CORBA::Any* ob=p->getAnyOut(); +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count); +#endif + //add_value makes a copy of any. Copy will be deleted with request + arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_OUT ); +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count); +#endif } - //valeur de retour + //return value req->set_return_type(CORBA::_tc_void); - //autres exceptions + //user exceptions //req->exceptions()->add(eo::_tc_SALOME_Exception); - cerr << "+++++++++++++++++CorbaNode::calculation+++++++++++++++++" << _method << endl; + DEBTRACE( "+++++++++++++++++CorbaNode::calculation+++++++++++++++++" << _method ) 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 ; + DEBTRACE( "An exception was thrown!" ) + DEBTRACE( "The raised exception is of Type:" << exc->_name() ) + throw Exception("Execution problem"); } - cerr << "++++++++++++CorbaNode::outputs++++++++++++" << endl; + DEBTRACE( "++++++++++++CorbaNode::outputs++++++++++++" ) 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; + OutputCorbaPort *p=(OutputCorbaPort *)*iter; + DEBTRACE( "port name: " << p->getName() ) + DEBTRACE( "port kind: " << p->edGetType()->kind() ) + DEBTRACE( "port number: " << out_param ) + CORBA::Any *ob=arguments->item(out_param)->value(); +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count); +#endif +#ifdef _DEVDEBUG_ + CORBA::TypeCode_var tc=ob->type(); + switch(p->edGetType()->kind()) + { + case Double: + CORBA::Double d; + *ob >>= d; + DEBTRACE( d ) + break; + case Int: + CORBA::Long l; + *ob >>= l; + DEBTRACE( l ) + break; + case String: + const char *s; + *ob >>= s; + DEBTRACE( s ) + break; + case Objref: + DEBTRACE( tc->id() ) + break; + default: + break; + } +#endif + //OutputPort must copy the input Any(ob). + //This Any will be deleted with the request. + //Copy is made by the method put. + p->put(ob); + out_param=out_param+1; +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count); +#endif } + DEBTRACE( "++++++++++++++++++++++++++++++++++++++++++" ) + } + //Request has been deleted (_var ) + //All anys given to the request are deleted : don't forget to copy them + //if you want to keep them +#ifdef REFCNT + list::const_iterator iter; + for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++) + { + OutputCorbaPort *p=(OutputCorbaPort *)*iter; + CORBA::Any *ob=p->getAny(); + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)ob->pd_tc.in())->pd_ref_count); + } +#endif + DEBTRACE( "+++++++++++++++++ End CorbaNode::execute: " << getName() << " +++++++++++++++++" ) +} + +//! Clone the node : must also clone the component instance ? +Node *CORBANode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new CORBANode(*this,father); +} + +//! Create a CORBANode with the same component object and no input or output port +/*! + * \param name : node name + * \return a new CORBANode node + */ +ServiceNode* CORBANode::createNode(const std::string& name) +{ + + CORBANode* node= new CORBANode(name); + node->setComponent(_component); + return node; +} + +// SalomeNode Class + +const char SalomeNode::KIND[]="Salome"; + +std::string SalomeNode::getKind() const +{ + return KIND; +} + +//! SalomeNode constructor +SalomeNode::SalomeNode(const std::string& name):ServiceNode(name) +{ + _implementation=CORBANode::IMPL_NAME; +} + +SalomeNode::SalomeNode(const SalomeNode& other,ComposedNode *father):ServiceNode(other,father) +{ + _implementation=CORBANode::IMPL_NAME; +} + +SalomeNode::~SalomeNode() +{ +} + +#ifdef DSC_PORTS +//! Init the datastream ports of the component associated to the node +void SalomeNode::initService() +{ + DEBTRACE( "SalomeNode::initService: "<getCompoPtr(); + Engines::Superv_Component_var compo=Engines::Superv_Component::_narrow(objComponent); + if( CORBA::is_nil(compo) ) + { + throw Exception("Can't get reference to DSC object (or it was nil)."); + } + compo->init_service(_method.c_str()); +} + +//! Connect the datastream ports of the component associated to the node +void SalomeNode::connectService() +{ + DEBTRACE( "SalomeNode::connectService: "<getCompoPtr(); + SALOME_NamingService NS(getSALOMERuntime()->getOrb()) ; + SALOME_LifeCycleCORBA LCC(&NS) ; + CORBA::Object_var obj = NS.Resolve("/ConnectionManager"); + Engines::ConnectionManager_var manager=Engines::ConnectionManager::_narrow(obj); + Engines::Superv_Component_var me=Engines::Superv_Component::_narrow(objComponent); + std::list::iterator iter; + Engines::ConnectionManager::connectionId id; + for(iter = _setOfOutputDataStreamPort.begin(); iter != _setOfOutputDataStreamPort.end(); iter++) + { + OutputDataStreamPort *port=(OutputDataStreamPort *)*iter; + std::set ports=port->edSetInPort(); + std::set::iterator iterout; + for(iterout=ports.begin();iterout != ports.end(); iterout++) + { + //It's only possible to connect 2 SalomeNode : try to get a SalomeNode + SalomeNode* snode= dynamic_cast((*iterout)->getNode()); + if(snode == 0) //don't connect, it's not a SalomeNode + throw Exception("Can't connect : not a SalomeNode"); + + CORBA::Object_var comp=((SalomeComponent*)snode->getComponent())->getCompoPtr(); + Engines::Superv_Component_var other=Engines::Superv_Component::_narrow(comp); + id=manager->connect(me,port->getName().c_str(),other,(*iterout)->getName().c_str()); + ids.push_back(id); + } + } - cerr << "++++++++++++++++++++++++++++++++++++++++++" << endl; + //Init component port properties + for(iter = _setOfOutputDataStreamPort.begin(); iter != _setOfOutputDataStreamPort.end(); iter++) + { + (*iter)->initPortProperties(); + } + std::list::iterator iterin; + for(iterin = _setOfInputDataStreamPort.begin(); iterin != _setOfInputDataStreamPort.end(); iterin++) + { + (*iterin)->initPortProperties(); + } +} + +//! Disconnect the datastream ports of the component associated to the node +void SalomeNode::disconnectService() +{ + DEBTRACE( "SalomeNode::disconnectService: "<getOrb()) ; + SALOME_LifeCycleCORBA LCC(&NS) ; + CORBA::Object_var obj = NS.Resolve("/ConnectionManager"); + Engines::ConnectionManager_var manager=Engines::ConnectionManager::_narrow(obj); + std::list::iterator iter; + for(iter = ids.begin(); iter != ids.end(); iter++) + { + manager->disconnect(*iter,Engines::DSC::RemovingConnection); + } + ids.clear(); +} +#endif + +//! Execute the service on the component associated to the node +void SalomeNode::execute() +{ + DEBTRACE( "+++++++++++++++++ SalomeNode::execute: " << getName() << " +++++++++++++++++" ) + { + CORBA::Object_var objComponent=((SalomeComponent*)_component)->getCompoPtr(); + //DII request building : + // a service gets all its in parameters first + // then all its out parameters + // no inout parameters + // the return value (if any) is the first out parameter + // not yet user exception (only CORBA exception) + // + CORBA::Request_var req = objComponent->_request(_method.c_str()); + CORBA::NVList_ptr arguments = req->arguments() ; + + DEBTRACE( "+++++++++++++++++SalomeNode::inputs+++++++++++++++++" ) + int in_param=0; + //in parameters + list::iterator iter2; + for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++) + { + InputCorbaPort *p=(InputCorbaPort *)*iter2; + DEBTRACE( "port name: " << p->getName() ) + DEBTRACE( "port kind: " << p->edGetType()->kind() ) + CORBA::Any* ob=p->getAny(); +#ifdef _DEVDEBUG_ + CORBA::TypeCode_var tc; + switch(p->edGetType()->kind()) + { + case Double: + CORBA::Double d; + *ob >>= d; + DEBTRACE( d ) + break; + case Int: + CORBA::Long l; + *ob >>= l; + DEBTRACE( l ) + break; + case String: + const char *s; + *ob >>= s; + DEBTRACE( s ) + break; + case Objref: + DEBTRACE( tc->id() ) + break; + default: + break; + } +#endif + //add_value makes a copy of any. Copy will be deleted with request + arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_IN ) ; + in_param=in_param+1; + } + + //out parameters + DEBTRACE( "+++++++++++++++++SalomeNode::outputs+++++++++++++++++" ) + list::iterator iter; + for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++) + { + OutputCorbaPort *p=(OutputCorbaPort *)*iter; + DEBTRACE( "port name: " << p->getName() ) + DEBTRACE( "port kind: " << p->edGetType()->kind() ) + CORBA::Any* ob=p->getAnyOut(); + //add_value makes a copy of any. Copy will be deleted with request + arguments->add_value( p->getName().c_str() , *ob , CORBA::ARG_OUT ); + } + + //return value + //if return type is set to void (not mandatory, it's set by default) + //the return value will not be marshalled as a return value but + //as the first out argument (don't forget to add it as the first output argument) + req->set_return_type(CORBA::_tc_void); + //user exceptions + //req->exceptions()->add(eo::_tc_SALOME_Exception); + + DEBTRACE( "+++++++++++++++++SalomeNode::calculation+++++++++++++++++" << _method ) + req->invoke(); + CORBA::Exception *exc =req->env()->exception(); + if( exc ) + { + DEBTRACE( "An exception was thrown!" ) + DEBTRACE( "The raised exception is of Type:" << exc->_name() ) + throw Exception("Execution problem"); + } + + DEBTRACE( "++++++++++++SalomeNode::outputs++++++++++++" ) + int out_param=in_param; + for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++) + { + OutputCorbaPort *p=(OutputCorbaPort *)*iter; + DEBTRACE( "port name: " << p->getName() ) + DEBTRACE( "port kind: " << p->edGetType()->kind() ) + DEBTRACE( "port number: " << out_param ) + CORBA::Any *ob=arguments->item(out_param)->value(); +#ifdef _DEVDEBUG_ + switch(p->edGetType()->kind()) + { + case Double: + CORBA::Double d; + *ob >>= d; + DEBTRACE( d ) + break; + case Int: + CORBA::Long l; + *ob >>= l; + DEBTRACE( l ) + break; + case String: + const char *s; + *ob >>= s; + DEBTRACE( s ) + break; + default: + break; + } +#endif + //OutputPort must copy the input Any(ob). + //This Any will be deleted with the request. + //Copy is made by the method put. + p->put(ob); + out_param=out_param+1; + } } - //La requete n'existe plus ici (_var oblige) - //Tous les any passés a la requete sont détruits : il faut les copier + //Request has been deleted (_var ) + //All anys given to the request are deleted : don't forget to copy them + //if you want to keep them + DEBTRACE( "+++++++++++++++++ End SalomeNode::execute: " << getName() << " +++++++++++++++++" ) +} + +Node *SalomeNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new SalomeNode(*this,father); +} + +//! Create a SalomeNode with the same component object and no input or output port +/*! + * \param name : node name + * \return a new SalomeNode node + */ +ServiceNode* SalomeNode::createNode(const std::string& name) +{ + SalomeNode* node=new SalomeNode(name); + node->setComponent(_component); + return node; } diff --git a/src/runtime/CORBANode.hxx b/src/runtime/CORBANode.hxx index 9d9253064..b7bd66202 100644 --- a/src/runtime/CORBANode.hxx +++ b/src/runtime/CORBANode.hxx @@ -1,26 +1,65 @@ - #ifndef _CORBANODE_HXX_ #define _CORBANODE_HXX_ -#include "ElementaryNode.hxx" +#include "ServiceNode.hxx" +#include "yacsconfig.h" +#ifdef DSC_PORTS +#include "DSC_Engines.hh" +#endif +#include +#include namespace YACS { namespace ENGINE { - - class CORBANode: public ENGINE::ElementaryNode +/*! \brief Class for CORBA Service Node + * + * \ingroup Nodes + * + * \see InputCorbaPort + * \see OutputCorbaPort + */ + class CORBANode : public ServiceNode { + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; public: + CORBANode(const CORBANode& other,ComposedNode *father); 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; + virtual ServiceNode* createNode(const std::string& name); + virtual std::string getKind() const; + static const char KIND[]; + public: + static const char IMPL_NAME[]; + }; +/*! \brief Class for Salome component Service Node + * + * \ingroup Nodes + * + * \see InputCorbaPort + * \see OutputCorbaPort + */ + class SalomeNode : public ServiceNode + { protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + public: + SalomeNode(const SalomeNode& other,ComposedNode *father); + SalomeNode(const std::string& name); + virtual ~SalomeNode(); + virtual void execute(); + virtual ServiceNode* createNode(const std::string& name); + virtual std::string getKind() const; + static const char KIND[]; +#ifdef DSC_PORTS + virtual void initService(); + virtual void connectService(); + virtual void disconnectService(); + std::list ids; +#endif }; } } diff --git a/src/runtime/CORBAPorts.cxx b/src/runtime/CORBAPorts.cxx index 1610e536d..e4ad8ae76 100644 --- a/src/runtime/CORBAPorts.cxx +++ b/src/runtime/CORBAPorts.cxx @@ -1,79 +1,190 @@ -#include "CORBAPorts.hxx" +//#define REFCNT +#ifdef REFCNT +#define private public +#define protected public +#include +#include +#endif + #include "RuntimeSALOME.hxx" #include "TypeConversions.hxx" +#include "CORBAPorts.hxx" +#include "ServiceNode.hxx" +#include "ComponentInstance.hxx" #include #include +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" using namespace YACS::ENGINE; using namespace std; -InputCorbaPort::InputCorbaPort(const string& name, - Node *node, - TypeCode * type) - : InputPort(name, node, type), Port(node) +InputCorbaPort::InputCorbaPort(const std::string& name, + Node *node, + TypeCode * type) + : InputPort(name, node, type), DataPort(name, node, type), Port(node), _initData(0) { - _impl="CORBA"; _orb = getSALOMERuntime()->getOrb(); } +InputCorbaPort::InputCorbaPort(const InputCorbaPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder), + _initData(0) +{ + _orb = getSALOMERuntime()->getOrb(); + if(other._initData) + { + _initData=new CORBA::Any; + *_initData=*(other._initData); + } + _data=other._data; +} + +InputCorbaPort::~InputCorbaPort() +{ + delete _initData; +} + +bool InputCorbaPort::edIsManuallyInitialized() const +{ + return _initData!=0; +} + +void InputCorbaPort::edRemoveManInit() +{ + delete _initData; + _initData=0; + InputPort::edRemoveManInit(); +} + void InputCorbaPort::put(const void *data) throw (ConversionException) { put((CORBA::Any *)data); - _empty = false; } -void InputCorbaPort::put(CORBA::Any *data) throw (ConversionException) +void display(CORBA::Any* data) { - cerr << "InputCorbaPort::put" << endl; - // cerr << "addr data: " << data << endl; - // cerr << "addr data.value(): " << data->value() << endl; - switch(type()->kind()) + CORBA::TypeCode_var tc=data->type(); + switch(tc->kind()) { - case Double: + case CORBA::tk_double: CORBA::Double d; *data >>= d; - cerr << "Double: " << d << endl; + DEBTRACE( "Double: " << d ); break; - case Int: + case CORBA::tk_long: CORBA::Long l; *data >>= l; - cerr << "Int: " << l << endl; - break; - case Sequence: + DEBTRACE( "Int: " << l ); 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 +} + +void InputCorbaPort::put(CORBA::Any *data) throw (ConversionException) +{ +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count); +#endif +#ifdef _DEVDEBUG_ + display(data); +#endif + // make a copy of the any (protect against deletion of any source) _data=*data; - // cerr << "addr _data: " << &_data << endl; - // cerr << "addr _data.value(): " << _data.value() << endl; +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count); +#endif +} + +InputPort *InputCorbaPort::clone(Node *newHelder) const +{ + return new InputCorbaPort(*this,newHelder); +} + +void *InputCorbaPort::get() const throw(Exception) +{ + return (void *)&_data; +} + +bool InputCorbaPort::isEmpty() +{ + CORBA::TypeCode_var tc=_data.type(); + return tc->equivalent(CORBA::_tc_null); } 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 a pointer to internal any return &_data; } +//! Save the current data value for further reinitialization of the port +/*! + * + */ +void InputCorbaPort::exSaveInit() +{ + if(_initData) + delete _initData; + _initData=new CORBA::Any; + *_initData=_data; +} + +//! Restore the saved data value to current data value +/*! + * If no data has been saved (_initData == 0) don't restore + */ +void InputCorbaPort::exRestoreInit() +{ + if(!_initData)return; + put(_initData); +} + +std::string InputCorbaPort::dump() +{ + CORBA::TypeCode_var tc=_data.type(); + if (tc->equivalent(CORBA::_tc_null)) + return "nil"; + if (edGetType()->kind() != YACS::ENGINE::Objref) + return convertCorbaXml(edGetType(), &_data); + if (! _stringRef.empty()) + return _stringRef; + else + return convertCorbaXml(edGetType(), &_data); +// { +// stringstream msg; +// msg << "Cannot retreive init string reference string for port " << _name +// << " on node " << _node->getName(); +// throw Exception(msg.str()); +// } +} -OutputCorbaPort::OutputCorbaPort(const string& name, - Node *node, - TypeCode * type) - : OutputPort(name, node, type), Port(node) +OutputCorbaPort::OutputCorbaPort(const std::string& name, + Node *node, + TypeCode * type) + : OutputPort(name, node, type), DataPort(name, node, type), Port(node) { - _impl="CORBA"; _orb = getSALOMERuntime()->getOrb(); } +OutputCorbaPort::OutputCorbaPort(const OutputCorbaPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder) +{ + _orb = getSALOMERuntime()->getOrb(); +} + +OutputCorbaPort::~OutputCorbaPort() +{ + DEBTRACE(getName()); +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count); + DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); +#endif +} + void OutputCorbaPort::put(const void *data) throw (ConversionException) { put((CORBA::Any *)data); @@ -81,34 +192,41 @@ void OutputCorbaPort::put(const void *data) throw (ConversionException) 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) +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count); +#endif +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count); +#endif _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); - } +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count); +#endif + OutputPort::put(data); +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count); +#endif +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)_data.pd_tc.in())->pd_ref_count); +#endif +} + +OutputPort *OutputCorbaPort::clone(Node *newHelder) const +{ + return new OutputCorbaPort(*this,newHelder); } 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 a pointer to the internal any return &_data; } CORBA::Any * OutputCorbaPort::getAnyOut() { CORBA::Any* a=&_data; - DynType kind=type()->kind(); + DynType kind=edGetType()->kind(); if(kind == Int) { @@ -124,19 +242,32 @@ CORBA::Any * OutputCorbaPort::getAnyOut() } else if(kind == Objref) { - a->replace(CORBA::_tc_Object, (void*) 0); + //a->replace(CORBA::_tc_Object, (void*) 0); + CORBA::TypeCode_var t; + t = getCorbaTC(edGetType()); + a->replace(t, (void*) 0); } else if(kind == Sequence) { CORBA::TypeCode_var t; - t = getCorbaTC(type()); + t = getCorbaTC(edGetType()); + a->replace(t, (void*) 0); + } + else if(kind == Struct) + { + CORBA::TypeCode_var t; + t = getCorbaTC(edGetType()); +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)t.in())->pd_ref_count); +#endif a->replace(t, (void*) 0); - } +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)t.in())->pd_ref_count); +#endif + } else if(kind == Bool) { - stringstream msg; - msg << "Cannot set Any Out for Bool" << __FILE__ << ":" << __LINE__; - throw Exception(msg.str()); + a->replace(CORBA::_tc_boolean, (void*) 0); } else if(kind == None) { @@ -148,15 +279,27 @@ CORBA::Any * OutputCorbaPort::getAnyOut() { stringstream msg; msg << "Cannot set Any Out for unknown type" << __FILE__ - << ":" << __LINE__; + << ":" << __LINE__; throw Exception(msg.str()); } - // on retourne un pointeur sur le any interne reinitialisé - // cerr << "getAnyOut::_data: " << a << endl; + // return a pointer to internal any reinitialized + DEBTRACE( "getAnyOut::_data: " << a ); +#ifdef REFCNT + DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)a->pd_tc.in())->pd_ref_count); +#endif return a; } +std::string OutputCorbaPort::dump() +{ + CORBA::TypeCode_var tc=_data.type(); + if (tc->equivalent(CORBA::_tc_null)) + return "nil"; + string xmldump = convertCorbaXml(edGetType(), &_data); + return xmldump; +} + ostream& YACS::ENGINE::operator<<(ostream& os, const OutputCorbaPort& p) { CORBA::Double l; diff --git a/src/runtime/CORBAPorts.hxx b/src/runtime/CORBAPorts.hxx index c1c0d057d..7d13244f7 100644 --- a/src/runtime/CORBAPorts.hxx +++ b/src/runtime/CORBAPorts.hxx @@ -5,21 +5,38 @@ #include "InputPort.hxx" #include "OutputPort.hxx" +#include namespace YACS { namespace ENGINE { - +/*! \brief Class for CORBA Input Ports + * + * \ingroup Ports + * + * \see CORBANode + */ class InputCorbaPort : public InputPort { public: InputCorbaPort(const std::string& name, Node *node, TypeCode * type); + InputCorbaPort(const InputCorbaPort& other, Node *newHelder); + virtual ~InputCorbaPort(); + bool edIsManuallyInitialized() const; + void edRemoveManInit(); virtual void put(const void *data) throw(ConversionException); void put(CORBA::Any *data) throw (ConversionException); + InputPort *clone(Node *newHelder) const; + void *get() const throw(Exception); + virtual bool isEmpty(); virtual CORBA::Any * getAny(); + virtual void exSaveInit(); + virtual void exRestoreInit(); + virtual std::string dump(); protected: CORBA::Any _data; + CORBA::Any * _initData; CORBA::ORB_ptr _orb; }; @@ -27,12 +44,16 @@ namespace YACS { public: OutputCorbaPort(const std::string& name, Node *node, TypeCode * type); + OutputCorbaPort(const OutputCorbaPort& other, Node *newHelder); + virtual ~OutputCorbaPort(); virtual void put(const void *data) throw(ConversionException); void put(CORBA::Any *data) throw (ConversionException); + OutputPort *clone(Node *newHelder) const; virtual CORBA::Any * getAny(); virtual CORBA::Any * getAnyOut(); + virtual std::string dump(); friend std::ostream & operator<< ( std::ostream &os, - const OutputCorbaPort& p); + const OutputCorbaPort& p); protected: CORBA::Any _data; CORBA::ORB_ptr _orb; diff --git a/src/runtime/CORBAPythonConv.cxx b/src/runtime/CORBAPythonConv.cxx index 48227fb3e..200fe4454 100644 --- a/src/runtime/CORBAPythonConv.cxx +++ b/src/runtime/CORBAPythonConv.cxx @@ -1,96 +1,156 @@ -#include "CORBAPythonConv.hxx" #include "TypeConversions.hxx" #include "RuntimeSALOME.hxx" +#include "CORBAPythonConv.hxx" +#include "PythonPorts.hxx" #include +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + using namespace YACS::ENGINE; using namespace std; +CorbaPyDouble::CorbaPyDouble(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{} + void CorbaPyDouble::put(const void *data) throw(ConversionException) { put((CORBA::Any *)data); } -//!Convertit un CORBA::Any de type double en PyObject de type Double +//!Convert a CORBA::Any double to PyObject 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; + PyObject *ob; + { + InterpreterUnlocker loc; + ob=PyFloat_FromDouble(d); + DEBTRACE("ob refcnt: " << ob->ob_refcnt ); + } _port->put(ob); + Py_DECREF(ob); } +CorbaPyInt::CorbaPyInt(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{} + void CorbaPyInt::put(const void *data) throw(ConversionException) { put((CORBA::Any *)data); } -//!Convertit un CORBA::Any de type entier en PyObject de type entier +//!Convert a CORBA::Any long to a PyObject Int /*! * \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; + PyObject *ob; + { + InterpreterUnlocker loc; + ob=PyLong_FromLong(l); + DEBTRACE("ob refcnt: " << ob->ob_refcnt ); + } _port->put(ob); + Py_DECREF(ob); } - +CorbaPyString::CorbaPyString(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{} void CorbaPyString::put(const void *data) throw(ConversionException) { put((CORBA::Any *)data); } -//!Convertit un CORBA::Any de type string en PyObject de type string +//!Convert a CORBA::Any string to a PyObject String /*! * \param data : CORBA::Any object */ - void CorbaPyString::put(CORBA::Any *data) throw(ConversionException) { - char *s; + const char *s; *data >>=s; - PyObject *ob=PyString_FromString(s); - cerr << "ob refcnt: " << ob->ob_refcnt << endl; + PyObject *ob; + { + InterpreterUnlocker loc; + ob=PyString_FromString(s); + DEBTRACE("ob refcnt: " << ob->ob_refcnt ); + } _port->put(ob); + Py_DECREF(ob); } +CorbaPyBool::CorbaPyBool(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{} -void CorbaPyObjref::put(const void *data) throw(ConversionException) +/*!Convert a CORBA::Any boolean to a PyObject boolean + * It's only a wrapper around put(CORBA::Any *data) + */ +void CorbaPyBool::put(const void *data) throw(ConversionException) { put((CORBA::Any *)data); } -//!Convertit un CORBA::Any de type Objref en PyObject de type Objref +//!Convert a CORBA::Any boolean to a PyObject boolean /*! * \param data : CORBA::Any object */ +void CorbaPyBool::put(CORBA::Any *data) throw(ConversionException) +{ + PyObject* ob=convertCorbaPyObject(edGetType(),data); + _port->put(ob); + Py_DECREF(ob); +} + +CorbaPyObjref::CorbaPyObjref(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{} + +void CorbaPyObjref::put(const void *data) throw(ConversionException) +{ + put((CORBA::Any *)data); +} +//!Convert a CORBA::Any Objref to PyObject Objref +/*! + * \param data : CORBA::Any object + */ void CorbaPyObjref::put(CORBA::Any *data) throw(ConversionException) { - CORBA::Object_ptr ObjRef ; + CORBA::Object_var ObjRef ; *data >>= (CORBA::Any::to_object ) ObjRef ; + PyObject *ob; + { + InterpreterUnlocker loc; //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; + ob = getSALOMERuntime()->getApi()->cxxObjRefToPyObjRef(ObjRef, 1); + DEBTRACE("ob refcnt: " << ob->ob_refcnt ); + } _port->put(ob); + Py_DECREF(ob); } +//!Class to convert a CORBA::Any sequence to a PyObject Sequence +/*! + * \param p : input Python port to adapt to Corba output port + */ CorbaPySequence::CorbaPySequence(InputPyPort* p) - : ProxyPort(p), Port(p->getNode()) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) { _dynfactory = getSALOMERuntime()->getDynFactory(); } @@ -100,14 +160,50 @@ void CorbaPySequence::put(const void *data) throw(ConversionException) put((CORBA::Any *)data); } +//!Convert a CORBA::Any sequence to PyObject Sequence +/*! + * \param data : CORBA::Any object + */ 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; + PyObject *ob; + { + InterpreterUnlocker loc; + ob=convertCorbaPyObject(edGetType(),data); + DEBTRACE("ob refcnt: " << ob->ob_refcnt ); _port->put(ob); + Py_DECREF(ob); + DEBTRACE("ob refcnt: " << ob->ob_refcnt ); + } } +//!Class to convert a CORBA::Any struct into a PyObject struct +/*! + * \param p : input Python port to adapt to Corba output port + */ +CorbaPyStruct::CorbaPyStruct(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{ +} + +void CorbaPyStruct::put(const void *data) throw(ConversionException) +{ + put((CORBA::Any *)data); +} + +//!Convert a CORBA::Any sequence to PyObject Sequence +/*! + * \param data : CORBA::Any object + */ +void CorbaPyStruct::put(CORBA::Any *data) throw(ConversionException) +{ + PyObject *ob; + { + InterpreterUnlocker loc; + ob=convertCorbaPyObject(edGetType(),data); + DEBTRACE("ob refcnt: " << ob->ob_refcnt ); + _port->put(ob); + Py_DECREF(ob); + DEBTRACE("ob refcnt: " << ob->ob_refcnt ); + } +} diff --git a/src/runtime/CORBAPythonConv.hxx b/src/runtime/CORBAPythonConv.hxx index 1648910fd..1e62bf845 100644 --- a/src/runtime/CORBAPythonConv.hxx +++ b/src/runtime/CORBAPythonConv.hxx @@ -2,52 +2,87 @@ #define __CORBAPYTHONCONV_HXX__ #include - -#include "PythonPorts.hxx" +#include "InputPort.hxx" +#include "ConversionException.hxx" namespace YACS { namespace ENGINE { + class InputPyPort; - // --- convertisseurs Corba->Python pour les différents types - +/*! \brief Class for conversion from CORBA Output port to Python Input port + * + * \ingroup AdaptorPorts + * + */ class CorbaPyDouble : public ProxyPort { public: - CorbaPyDouble(InputPyPort* p) - : ProxyPort(p), Port(p->getNode()) {} + CorbaPyDouble(InputPyPort* p); virtual void put(const void *data) throw(ConversionException); void put(CORBA::Any *data) throw(ConversionException); }; +/*! \brief Class for conversion from CORBA Output port to Python Input port + * + * \ingroup AdaptorPorts + * + */ class CorbaPyInt : public ProxyPort { public: - CorbaPyInt(InputPyPort* p) - : ProxyPort(p), Port(p->getNode()) {} + CorbaPyInt(InputPyPort* p); virtual void put(const void *data) throw(ConversionException); void put(CORBA::Any *data) throw(ConversionException); }; +/*! \brief Class for conversion from CORBA Output port to Python Input port + * + * \ingroup AdaptorPorts + * + */ class CorbaPyString : public ProxyPort { public: - CorbaPyString(InputPyPort* p) - : ProxyPort(p), Port(p->getNode()) {} + CorbaPyString(InputPyPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(CORBA::Any *data) throw(ConversionException); + }; + +/*! \brief Class for conversion from CORBA Output port to Python Input port + * + * Convert boolean data + * + * \ingroup AdaptorPorts + * + */ + class CorbaPyBool : public ProxyPort + { + public: + CorbaPyBool(InputPyPort* p); virtual void put(const void *data) throw(ConversionException); void put(CORBA::Any *data) throw(ConversionException); }; +/*! \brief Class for conversion from CORBA Output port to Python Input port + * + * \ingroup AdaptorPorts + * + */ class CorbaPyObjref : public ProxyPort { public: - CorbaPyObjref(InputPyPort* p) - : ProxyPort(p), Port(p->getNode()) {} + CorbaPyObjref(InputPyPort* p); virtual void put(const void *data) throw(ConversionException); void put(CORBA::Any *data) throw(ConversionException); }; +/*! \brief Class for conversion from CORBA Output port to Python Input port + * + * \ingroup AdaptorPorts + * + */ class CorbaPySequence : public ProxyPort { public: @@ -58,6 +93,19 @@ namespace YACS DynamicAny::DynAnyFactory_ptr _dynfactory; }; +/*! \brief Class for conversion of struct objects from CORBA Output port to Python Input port + * + * \ingroup AdaptorPorts + * + */ + class CorbaPyStruct : public ProxyPort + { + public: + CorbaPyStruct(InputPyPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(CORBA::Any *data) throw(ConversionException); + }; + } } #endif diff --git a/src/runtime/CORBAXMLConv.cxx b/src/runtime/CORBAXMLConv.cxx index 88ea6a742..56326c156 100644 --- a/src/runtime/CORBAXMLConv.cxx +++ b/src/runtime/CORBAXMLConv.cxx @@ -1,21 +1,23 @@ -#include "CORBAXMLConv.hxx" #include "TypeConversions.hxx" +#include "CORBAXMLConv.hxx" #include +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + using namespace YACS::ENGINE; using namespace std; CorbaXml::CorbaXml(InputXmlPort* p) - : ProxyPort(p), Port(p->getNode()) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) { - cerr << "proxy port from CORBA to XML" << endl; } -//!Convertit un Any convertible en Xml::char * +//!Convert a CORBA::Any that is convertible to Xml::char * and send it to proxy port /*! - * \param data : CORBA::Any object + * \param data : CORBA::Any object as a void * pointer */ void CorbaXml::put(const void *data) throw(ConversionException) @@ -23,15 +25,13 @@ void CorbaXml::put(const void *data) throw(ConversionException) put((CORBA::Any *)data); } +//!Convert a CORBA::Any that is convertible to Xml::char * and send it to proxy port +/*! + * \param data : CORBA::Any object + */ 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; + DEBTRACE("CorbaXml::put" ); + std::string sss = convertCorbaXml(edGetType(),data); + ((InputXmlPort*)_port)->put((const char*)sss.c_str()); } diff --git a/src/runtime/CORBAXMLConv.hxx b/src/runtime/CORBAXMLConv.hxx index 409bc7d39..12d975e31 100644 --- a/src/runtime/CORBAXMLConv.hxx +++ b/src/runtime/CORBAXMLConv.hxx @@ -9,7 +9,7 @@ namespace YACS { namespace ENGINE { - // Ports adaptateurs Corba->Xml pour les différents types + // Adaptator Ports Corba->Xml for several types class CorbaXml : public ProxyPort { diff --git a/src/runtime/CalStreamPort.cxx b/src/runtime/CalStreamPort.cxx new file mode 100644 index 000000000..bd7d0eb87 --- /dev/null +++ b/src/runtime/CalStreamPort.cxx @@ -0,0 +1,195 @@ +#include "CalStreamPort.hxx" +#include "SalomeComponent.hxx" +#include "CORBANode.hxx" +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +const char InputCalStreamPort::NAME[]="InputCalStreamPort"; + +InputCalStreamPort::InputCalStreamPort(const std::string& name, Node *node, TypeCode* type): + InputDataStreamPort(name, node, type), + DataPort(name, node, type), + Port(node),_depend("T"),_schema("TI"),_delta(0.),_level(-1) +{ +} +InputCalStreamPort::InputCalStreamPort(const InputCalStreamPort& other, Node *newHelder): + InputDataStreamPort(other,newHelder), + DataPort(other,newHelder), + Port(other,newHelder),_depend(other._depend),_schema(other._schema),_delta(other._delta),_level(other._level) +{ +} + +InputCalStreamPort::~InputCalStreamPort() +{ +} + +void InputCalStreamPort::setDepend(const std::string& depend) +{ + DEBTRACE("InputCalStreamPort::setDepend: " << edGetNumberOfLinks()); + if(edGetNumberOfLinks() > 0) + { + throw Exception("Can not modify depend parameter on a connected port"); + } + if(depend != "T" && depend != "I") + { + throw Exception("depend parameter must be T or I"); + } + _depend=depend; +} + +void InputCalStreamPort::setSchema(const std::string& schema) +{ + if(schema != "TI" && schema != "TF" && schema != "DELTA") + { + throw Exception("schema parameter must be TI, TF or DELTA"); + } + _schema=schema; +} +void InputCalStreamPort::setLevel(const std::string& level) +{ + _level =atoi(level.c_str()); +} + +void InputCalStreamPort::setProperty(const std::string& name, const std::string& value) +{ + if(name == "depend") + setDepend(value); + else if(name == "schema") + setSchema(value); + else if(name == "level") + setLevel(value); + else + InputDataStreamPort::setProperty(name,value); +} + +#ifdef DSC_PORTS +void InputCalStreamPort::initPortProperties() +{ + + DEBTRACE(_level); + if(_level>0) + { + CORBA::Object_var objComponent=((SalomeComponent*)((SalomeNode*)_node)->getComponent())->getCompoPtr(); + Engines::Superv_Component_var compo=Engines::Superv_Component::_narrow(objComponent); + Ports::PortProperties_var port_properties=compo->get_port_properties(getName().c_str()); + CORBA::Any a; + a <<= (CORBA::Long)_level; + try + { + port_properties->set_property("StorageLevel",a); + } + catch(Ports::NotDefined& ex) + { + throw Exception("Property StorageLevel not defined on that port: "+getName()); + } + } +} +#endif + +std::string InputCalStreamPort::getNameOfTypeOfCurrentInstance() const +{ + return NAME; +} + +InputCalStreamPort *InputCalStreamPort::clone(Node *newHelder) const +{ + return new InputCalStreamPort(*this,newHelder); +} + +const char OutputCalStreamPort::NAME[]="OutputCalStreamPort"; + +OutputCalStreamPort::OutputCalStreamPort(const std::string& name, Node *node, TypeCode* type): + OutputDataStreamPort(name, node, type), + DataPort(name, node, type), + Port(node),_depend("T") +{ +} + +OutputCalStreamPort::OutputCalStreamPort(const OutputCalStreamPort& other, Node *newHelder): + OutputDataStreamPort(other,newHelder), + DataPort(other,newHelder), + Port(other,newHelder), + _depend(other._depend) +{ +} + +OutputCalStreamPort::~OutputCalStreamPort() +{ +} + +void OutputCalStreamPort::setDepend(const std::string& depend) +{ + DEBTRACE("OutputCalStreamPort::setDepend: " << edGetNumberOfOutLinks()); + if(edGetNumberOfOutLinks() > 0) + { + throw Exception("Can not modify depend parameter on a connected port"); + } + if(depend != "T" && depend != "I" ) + { + throw Exception("depend parameter must be T or I"); + } + _depend=depend; +} + +void OutputCalStreamPort::setSchema(const std::string& schema) +{ + if(schema != "TI" && schema != "TF" && schema != "DELTA") + { + throw Exception("schema parameter must be TI, TF or DELTA"); + } + _schema=schema; +} +void OutputCalStreamPort::setLevel(const std::string& level) +{ + _level =atoi(level.c_str()); +} + +void OutputCalStreamPort::setProperty(const std::string& name, const std::string& value) +{ + if(name == "depend") + setDepend(value); + else if(name == "schema") + setSchema(value); + else if(name == "level") + setLevel(value); + else + OutputDataStreamPort::setProperty(name,value); +} + +std::string OutputCalStreamPort::getNameOfTypeOfCurrentInstance() const +{ + return NAME; +} + +OutputCalStreamPort *OutputCalStreamPort::clone(Node *newHelder) const +{ + return new OutputCalStreamPort(*this,newHelder); +} + +bool OutputCalStreamPort::addInPort(InPort *inPort) throw(Exception) +{ + DEBTRACE("OutputCalStreamPort::addInPort" << InputCalStreamPort::NAME ); + if(inPort->getNameOfTypeOfCurrentInstance()!=InputCalStreamPort::NAME) + { + string what="not compatible type of port requested during building of link FROM "; + what+=NAME; what+=" TO "; what+=inPort->getNameOfTypeOfCurrentInstance(); + throw Exception(what); + } + + InputCalStreamPort* port=static_cast(inPort); + if(port->getDepend() != _depend) + { + std::string what= "incompatible depend parameters: "+_depend+" != "+ port->getDepend(); + throw Exception(what); + } + bool ret; + ret= edAddInputDataStreamPort(port); + return ret; +} + + diff --git a/src/runtime/CalStreamPort.hxx b/src/runtime/CalStreamPort.hxx new file mode 100644 index 000000000..8319bdb9f --- /dev/null +++ b/src/runtime/CalStreamPort.hxx @@ -0,0 +1,78 @@ +#ifndef __CALSTREAMPORT_HXX__ +#define __CALSTREAMPORT_HXX__ + +#include "yacsconfig.h" +#ifdef DSC_PORTS +#include "DSC_Engines.hh" +#endif + +#include "InputDataStreamPort.hxx" +#include "OutputDataStreamPort.hxx" + +namespace YACS +{ + namespace ENGINE + { + /*! \brief Class for Input Calcium DataStream Ports + * + * \ingroup Ports + * + */ + class InputCalStreamPort : public InputDataStreamPort + { + public: + static const char NAME[]; + InputCalStreamPort(const std::string& name, Node *node, TypeCode* type); + InputCalStreamPort(const InputCalStreamPort& other, Node *newHelder); + virtual ~InputCalStreamPort(); + void setDepend(const std::string& depend); + std::string getDepend(){return _depend;}; + void setLevel(const std::string& schema); + void setSchema(const std::string& schema); + std::string getSchema(){return _schema;}; + int getLevel(){return _level;}; + void setProperty(const std::string& name, const std::string& value); + std::string getNameOfTypeOfCurrentInstance() const; + InputCalStreamPort * clone(Node *newHelder) const; +#ifdef DSC_PORTS + virtual void initPortProperties(); +#endif + protected: + std::string _depend; + std::string _schema; + int _level; + double _delta; + }; + + /*! \brief Class for Output Calcium DataStream Ports + * + * \ingroup Ports + * + */ + class OutputCalStreamPort : public OutputDataStreamPort + { + public: + static const char NAME[]; + OutputCalStreamPort(const std::string& name, Node *node, TypeCode* type); + OutputCalStreamPort(const OutputCalStreamPort& other, Node *newHelder); + virtual ~OutputCalStreamPort(); + void setDepend(const std::string& depend); + void setLevel(const std::string& schema); + std::string getDepend(){return _depend;}; + int getLevel(){return _level;}; + void setSchema(const std::string& schema); + std::string getSchema(){return _schema;}; + void setProperty(const std::string& name, const std::string& value); + virtual bool addInPort(InPort *inPort) throw(Exception); + std::string getNameOfTypeOfCurrentInstance() const; + OutputCalStreamPort * clone(Node *newHelder) const; + protected: + std::string _depend; + std::string _schema; + int _level; + double _delta; + }; + } +} + +#endif diff --git a/src/runtime/CppCORBAConv.cxx b/src/runtime/CppCORBAConv.cxx new file mode 100644 index 000000000..a2eac2c8e --- /dev/null +++ b/src/runtime/CppCORBAConv.cxx @@ -0,0 +1,43 @@ + +#include "TypeConversions.hxx" +#include "CppCORBAConv.hxx" +#include "RuntimeSALOME.hxx" + +#include +#include + +using namespace std; + +namespace YACS +{ + namespace ENGINE + { + CORBA::Any *convertCppCorba(const TypeCode *t,Any *data) + { + return convertNeutralCorba(t, data); + } + + void CppCorba::put(const void *data) throw(ConversionException) + { + put((Any *)data); + } + + //!Convert a C++ object into CORBA::Any object + /*! + * \param data : python object + */ + + void CppCorba::put(Any *data) throw(ConversionException) + { + CORBA::Any* a = convertCppCorba(edGetType(), data); + _port->put(a); + //delete Any that has been allocated by convertCppCorba + delete a; + } + + int isAdaptableCorbaCpp(const TypeCode *t1, const TypeCode *t2) + { + return isAdaptableCorbaNeutral(t1, t2); + } + } +} diff --git a/src/runtime/CppCORBAConv.hxx b/src/runtime/CppCORBAConv.hxx new file mode 100644 index 000000000..60fca98c6 --- /dev/null +++ b/src/runtime/CppCORBAConv.hxx @@ -0,0 +1,24 @@ +#ifndef __CPPCORBACONV_HXX__ +#define __CPPCORBACONV_HXX__ + +#include "CORBAPorts.hxx" + +namespace YACS +{ + namespace ENGINE + { + + // --- adaptator ports C++ -> Corba for several types + + class CppCorba : public ProxyPort + { + public: + CppCorba(InputCorbaPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(Any *data) throw(ConversionException); + }; + int isAdaptableCorbaCpp(const TypeCode *t1, const TypeCode *t2); + } +} +#endif diff --git a/src/runtime/CppComponent.cxx b/src/runtime/CppComponent.cxx new file mode 100644 index 000000000..331bf0e1c --- /dev/null +++ b/src/runtime/CppComponent.cxx @@ -0,0 +1,204 @@ +#include "RuntimeSALOME.hxx" +#include "CppComponent.hxx" +#include "CppContainer.hxx" +#include "TypeCode.hxx" +#include "CppNode.hxx" +#include "DynLibLoader.hxx" + +using namespace YACS::ENGINE; + +#include +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +const char CppComponent::KIND[] = "Cpp"; + +static std::ostream & operator<<(std::ostream & f, const Any & A) +{ + const TypeCode * t = A.getType(); + if (NULL == t) + f << "(type NULL)"; + else + switch (t->kind()) { + case None : + f << "(type None)"; + break; + case Double : + f << "(type Double) " << A.getDoubleValue(); + break; + case Int : + f << "(type Int) " << A.getIntValue(); + break; + case String : + f << "(type String) " << A.getStringValue(); + break; + case Bool : + f << "(type Bool) " << A.getBoolValue(); + break; + case Objref : + f << "(type Objref)"; + break; + case Sequence : + f << "(type Sequence) "; + { + int i; + const SequenceAny * sA = dynamic_cast(&A); + for (i=0; isize(); i++) + f << " " << *((*sA)[i]); + } + break; + } + return f; +} + +std::string CppComponent::getKind() const +{ + return CppComponent::KIND; +} + +//! CppComponent constructor +CppComponent::CppComponent(const std::string &name) : ComponentInstance(name) +{ + _container = getRuntime()->createContainer(CppNode::KIND); + if (!_container->isAlreadyStarted()) + _container->start(); + + CppContainer * _containerC = dynamic_cast (_container); + _containerC->createInternalInstance(name, __obj, __run, __terminate); +} + +//! CppComponent copy constructor +CppComponent::CppComponent(const CppComponent& other) : ComponentInstance(other._name), __run(other.__run), + __terminate(other.__terminate), __obj(0) +{ + _container = getRuntime()->createContainer(CppNode::KIND); + if (!_container->isAlreadyStarted()) + _container->start(); + + CppContainer * _containerC = dynamic_cast (_container); + _containerC->createInternalInstance(_name, __obj, __run, __terminate); +} + +CppComponent::~CppComponent() +{ + DEBTRACE("CppComponent::~CppComponent()"); + if (__terminate) __terminate(&__obj); + if (_container) + ((CppContainer *) _container)->unregisterComponentInstance(this); +} + +void CppComponent::run (const char * service, int nbIn, int nbOut, + Any ** argIn, Any ** argOut) throw (YACS::Exception) +{ + int i; + returnInfo return_code; + +#ifdef _DEVDEBUG_ + std::ostringstream sDebug; + sDebug << _name << "::" << service << "("; + for (i=0; i 0) { + sDebug << "->"; + for (i=0; icreateContainer(CppNode::KIND); + } + + if(_container) { + + CppContainer * containerC= dynamic_cast< CppContainer *> (_container); + + containerC->lock();//To be sure + if(!_container->isAlreadyStarted()) + { + try + { + _container->start(); + } + catch(Exception& e) + { + containerC->unLock(); + throw e; + } + } + containerC->unLock(); + containerC->lock();//To be sure + + YACS::BASES::DynLibLoader D(_name + "Local"); + + bool isLoadable = containerC->loadComponentLibrary(_name); + if (isLoadable) + containerC->createInternalInstance(_name, __obj, __run, __terminate); + + if(NULL == __obj) + { + containerC->unLock(); + throw Exception("CppComponent::load : Error while trying to create a new component."); + } + containerC->unLock(); + return; + } + +} + +ServiceNode* CppComponent::createNode(const std::string& name) +{ + CppNode* node=new CppNode(name); + node->setComponent(this); + return node; +} + +//! Clone the component instance +ComponentInstance* CppComponent::clone() const +{ + if(_isAttachedOnCloning) + { + incrRef(); + return (ComponentInstance*) (this); + } + else + return new CppComponent(*this); +} + diff --git a/src/runtime/CppComponent.hxx b/src/runtime/CppComponent.hxx new file mode 100644 index 000000000..080abbc29 --- /dev/null +++ b/src/runtime/CppComponent.hxx @@ -0,0 +1,53 @@ +#ifndef __YACS_CppCOMPONENT__ +#define __YACS_CppCOMPONENT__ + +#include +#include "Any.hxx" +#include "ComponentInstance.hxx" + +namespace YACS +{ + namespace ENGINE + { + + struct returnInfo { + int code; + std::string message; + }; + + typedef void * (*InitFunction)(); + typedef void (*RunFunction) (void *, const char *, int, int, Any **, Any **, returnInfo *); + typedef void (*TerminateFunction)(void **); + typedef void (*PingFunction) (); + + class CppComponent : public ComponentInstance { + public: + + CppComponent(const std::string & name); + CppComponent(void * obj, RunFunction r, TerminateFunction t, + const std::string & name) + : __obj(obj), __run(r), __terminate(t), ComponentInstance(name) {} + CppComponent(const CppComponent& other); + virtual ~CppComponent(); + + void run(const char * service, int nbIn, int nbOut, + Any ** argIn, Any ** argOut) throw (YACS::Exception); + + static const char KIND[]; + virtual std::string getKind() const; + virtual void load(); + virtual void unload(); + virtual bool isLoaded(); + virtual ServiceNode* createNode(const std::string& name); + virtual YACS::ENGINE::ComponentInstance* clone() const; + + protected: + + void * __obj; + YACS::ENGINE::RunFunction __run; + YACS::ENGINE::TerminateFunction __terminate; + }; + }; +}; + +#endif diff --git a/src/runtime/CppContainer.cxx b/src/runtime/CppContainer.cxx new file mode 100644 index 000000000..e43f6265a --- /dev/null +++ b/src/runtime/CppContainer.cxx @@ -0,0 +1,371 @@ +#include +#include +#include + +#include "CppContainer.hxx" +#include "CppComponent.hxx" +#include "Exception.hxx" +#include +#include + + +using namespace YACS::ENGINE; + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +//============================================================================= +/*! + * Local C++ container class constructor + */ +//============================================================================= + +CppContainer::CppContainer() : _trueCont(0L) +{ + DEBTRACE("CppContainer::CppContainer()"); +} + + +//============================================================================= +/*! + * Local C++ container class destructor + */ +//============================================================================= + +CppContainer::~CppContainer() +{ + DEBTRACE("CppContainer::~CppContainer()"); +} + +void CppContainer::lock() +{ + _mutex.lock(); +} + +void CppContainer::unLock() +{ + _mutex.unlock(); +} + +bool CppContainer::isAlreadyStarted() const +{ + return NULL != _trueCont; +} + +void CppContainer::start() throw (YACS::Exception) +{ + _trueCont = LocalContainer::get(); +} + +Container *CppContainer::clone() const +{ + if(_isAttachedOnCloning) + { + incrRef(); + return (Container*) (this); + } + else + return new CppContainer(*this); +} + +bool CppContainer::loadComponentLibrary(const std::string & componentName) throw (YACS::Exception) +{ + if (_trueCont) + { + LocalLibrary L = _trueCont->loadComponentLibrary(componentName); + return L.good(); + } + else + { + std::string mesg = "CppContainer not started"; + throw YACS::Exception(mesg); + } + return false; +} + +CppComponent * CppContainer::createComponentInstance(const std::string & componentName, int /* studyID */) +{ + DEBTRACE("CppContainer::createComponentInstance"); + if (_trueCont) + return _trueCont->createComponentInstance(componentName.c_str()); + else + { + std::string mesg = "CppContainer not started"; + throw YACS::Exception(mesg); + } +} + +void CppContainer::createInternalInstance(const std::string & name, void *&obj, + RunFunction &r, TerminateFunction &t) +{ + DEBTRACE("CppContainer::createInternalInstance"); + if (_trueCont) + _trueCont->createInternalInstance(name.c_str(), obj, r, t); + else + { + std::string mesg = "CppContainer not started"; + throw YACS::Exception(mesg); + } +} + +void CppContainer::unregisterComponentInstance(CppComponent * C) +{ + if (_trueCont) + { + _trueCont->unregisterComponentInstance(C); + } +} + + +std::string CppContainer::getPlacementId() const +{ + return "/"; +} + +void CppContainer::checkCapabilityToDealWith(const ComponentInstance *inst) const throw (Exception) +{ + if(inst->getKind()!=CppComponent::KIND) + throw Exception("CppContainer::checkCapabilityToDealWith : CppContainer is not able to deal with this type of ComponentInstance."); +} + +std::map LocalContainer::_library_map; // libraries, loaded +std::multimap LocalContainer::_instance_map; + +LocalContainer * LocalContainer::_singleton = NULL; + +LocalContainer::LocalContainer() +{ +} + +LocalContainer::~LocalContainer() +{ + destroy(); +} + +LocalContainer * LocalContainer::get() +{ + if (NULL == _singleton) + { + _singleton = new LocalContainer; + } + return _singleton; +} + +void LocalContainer::destroy() +{ + if (NULL == _singleton) + return; + + // destroy all component instances + _instance_mapMutex.lock(); // lock + std::multimap::iterator iI, iJ; + for (iI=_instance_map.begin(); iI != _instance_map.end(); iI = iJ) + { + iJ = iI++; + iI->second->setContainer(NULL); + delete iI->second; + } + _instance_map.clear(); + _instance_mapMutex.unlock(); // unlock + + // unload all dynamic libraries + _library_mapMutex.lock(); + std::map::iterator iL; + for (iL=_library_map.begin(); iL != _library_map.end(); iL++) + dlclose(iL->second.handle); + _library_map.clear(); + _library_mapMutex.unlock(); + + delete _singleton; + _singleton = NULL; +} + + +//============================================================================= +//! Find or create a new C++ component instance +/*! + * Create a new component class (C++ implementation) + * \param name : component name + * + * Try to return a handle to an new instance of a C++ component + * If the associated library is not loaded, try to load it + * + * \return a handle to the component instance or throw an exception + * if it's not possible + */ +//============================================================================= +CppComponent * LocalContainer::createComponentInstance(const char * name) +{ + void *o; + RunFunction r; + TerminateFunction t; + + createInternalInstance(name, o, r, t); + + CppComponent * C; + C = new CppComponent(o, r, t, name); + _instance_mapMutex.lock(); // lock to be alone + _instance_map.insert(std::pair(name, C)); + _instance_mapMutex.unlock(); // unlock + return C; +} + +void LocalContainer::createInternalInstance(const char *name, void *&obj, + RunFunction &r, TerminateFunction &t) +{ + LocalLibrary L; + + std::map::iterator foundL = _library_map.find(name); + if (foundL != _library_map.end()) + L = foundL->second; + else + L = loadComponentLibrary(name, NULL, false); + + r = L.runHandle; + InitFunction i = L.initHandle; + t = L.terminateHandle; + + PingFunction p = L.pingHandle; + if (p) p(); + + obj = i(); + +} + +void LocalContainer::unregisterComponentInstance(CppComponent * C) +{ + _instance_mapMutex.lock(); // lock to be alone + _instance_map.erase(C->getName()); + _instance_mapMutex.unlock(); // unlock +} + +//============================================================================= +/*! + * load a new component class (C++ implementation) + * \param componentName like COMPONENT + * try to load libCOMPONENTLocal.so + * \return true if dlopen successfull or already done, false otherwise + */ +//============================================================================= + +inline void toupper (std::string & s) +{ + transform (s.begin (), s.end (), s.begin (), (int(*)(int)) toupper); +} + +LocalLibrary LocalContainer::loadComponentLibrary(const std::string & aCompName, const char * prefix, bool forcedLoad) +{ + + // if forcedLoad is true, unload library if it exists + // if forcedLoad is false, return the existing library or load it + + if (forcedLoad) + unLoadComponentLibrary(aCompName); + else + { + std::map::iterator itLib + = _library_map.find(aCompName); + if (itLib != _library_map.end()) return itLib->second; + } + + // --- try dlopen C++ component + + std::string sprefix; + if (prefix) + sprefix = prefix; + else + { + std::string s = aCompName + "_ROOT_DIR"; + toupper(s); + const char * t = getenv(s.c_str()); + sprefix=""; + if (t) + { + sprefix = t; + sprefix += "/lib/salome"; + } + } + +#ifndef WNT + std::string impl_name = std::string ("lib") + aCompName + std::string("Local.so"); + if(sprefix != "") + impl_name = sprefix + std::string("/") + impl_name; +#else + std::string impl_name = aCompName + std::string("Local.dll"); + impl_name = sprefix + std::string("\\") + impl_name; +#endif + DEBTRACE("impl_name = " << impl_name); + + void* handle; +#if defined( WNT ) + handle = dlopen( impl_name.c_str() , 0 ) ; +#else + handle = dlopen( impl_name.c_str() , RTLD_LAZY ) ; +#endif + + const char * sError; + sError = dlerror(); + + if ((sError = dlerror()) || !handle) + { + std::stringstream msg; + msg << "Can't load shared library : " << impl_name + << " (dlopen error : " << sError << ") at " + << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + + void *ihandle, *rhandle, *phandle = NULL, *thandle = NULL; + + ihandle = dlsym(handle, "__init"); + if (sError = dlerror()) + { + dlclose(handle); + std::stringstream msg; + msg << "Library " << impl_name + << " doesn't contains initialization function (" << sError << ") at " + << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + + rhandle = dlsym(handle, "__run"); + if (sError = dlerror()) + { + dlclose(handle); + std::stringstream msg; + msg << "Library " << impl_name + << " doesn't contains main switch function (" << sError << ") at " + << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + + thandle = dlsym(handle, "__terminate"); + if (sError = dlerror()) + { + dlclose(handle); + std::stringstream msg; + msg << "Library " << impl_name + << " doesn't contains terminate function (" << sError << ") at " + << __FILE__ << ":" << __LINE__; + throw YACS::Exception(msg.str()); + } + phandle = dlsym(handle, "__ping"); + + _library_map[aCompName] = LocalLibrary(handle, (InitFunction) ihandle, + (RunFunction) rhandle, + (PingFunction) phandle, + (TerminateFunction) thandle); + return _library_map[aCompName]; +} + +void LocalContainer::unLoadComponentLibrary(const std::string & aCompName) +{ + std::map::iterator itLib + = _library_map.find(aCompName); + + if (itLib == _library_map.end()) return; + + dlclose(itLib->second.handle); + _library_map.erase(itLib); + +} diff --git a/src/runtime/CppContainer.hxx b/src/runtime/CppContainer.hxx new file mode 100644 index 000000000..a2dc91520 --- /dev/null +++ b/src/runtime/CppContainer.hxx @@ -0,0 +1,106 @@ +#ifndef __Cpp_CONTAINER_HXX__ +#define __Cpp_CONTAINER_HXX__ + +#include +#include +#include "Any.hxx" +#include "Mutex.hxx" +#include "CppComponent.hxx" +#include "Container.hxx" + +namespace YACS +{ + namespace ENGINE + { + + struct LocalLibrary { + + void * handle; + + InitFunction initHandle; + RunFunction runHandle; + PingFunction pingHandle; + TerminateFunction terminateHandle; + + LocalLibrary(void *h, InitFunction i, RunFunction r, + PingFunction p, TerminateFunction t) + : handle(h), initHandle(i), runHandle(r), + pingHandle(p), terminateHandle(t) {} + LocalLibrary() + : handle(NULL), initHandle(NULL), runHandle(NULL), + pingHandle(NULL), terminateHandle(NULL) {} + + bool good() { + return (handle != NULL) && (initHandle != NULL) && + (runHandle != NULL) && (terminateHandle != NULL); + } + + }; + + // Local container singleton + class LocalContainer { + + friend class CppComponent; + + public: + + static YACS::ENGINE::LocalContainer * get(); + void destroy(); + LocalLibrary loadComponentLibrary(const std::string &, const char * prefix = NULL, + bool forcedLoad = false); + CppComponent * createComponentInstance(const char * componentName); + void createInternalInstance(const char * componentName, + void *& obj, RunFunction &r, TerminateFunction &t); + void unLoadComponentLibrary(const std::string & aCompName); + void unregisterComponentInstance(CppComponent * C); + + protected: + + LocalContainer(); + virtual ~LocalContainer(); + + YACS::BASES::Mutex _instance_mapMutex, _library_mapMutex; + static std::map _library_map; // libraries, loaded + static std::multimap _instance_map; + + + private: + static LocalContainer *_singleton; + + + }; + + class CppContainer : public Container { + + friend class CppComponent; + friend class LocalContainer; + + public: + + CppContainer(); + virtual ~CppContainer(); + bool isAlreadyStarted() const; + void start() throw (YACS::Exception); + std::string getPlacementId() const; + YACS::ENGINE::Container *clone() const; + + void lock(); + void unLock(); + + void checkCapabilityToDealWith(const ComponentInstance *inst) const throw (YACS::Exception); + bool loadComponentLibrary(const std::string & componentName) throw (YACS::Exception); + CppComponent * createComponentInstance(const std::string & componentName, int studyID = 0); + void createInternalInstance(const std::string & componentName, + void *& obj, RunFunction &r, TerminateFunction &t); + void unregisterComponentInstance(CppComponent * C); + + protected: + YACS::BASES::Mutex _mutex; + LocalContainer * _trueCont; + + }; + }; +}; + +#endif + diff --git a/src/runtime/CppCppConv.cxx b/src/runtime/CppCppConv.cxx new file mode 100644 index 000000000..196f026b8 --- /dev/null +++ b/src/runtime/CppCppConv.cxx @@ -0,0 +1,55 @@ +#include "TypeConversions.hxx" +#include "CppCppConv.hxx" +#include "CppPorts.hxx" + +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; + +namespace YACS +{ + namespace ENGINE + { + Any * convertCppCpp(const TypeCode *t, Any *data) + { + return convertNeutralNeutral(t, data); + } + + CppCpp::CppCpp(InputCppPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) + { + } + + //!Convert a Any to a Any + /*! + * transition method from const void* to Any* + * \param data : const void * data + */ + void CppCpp::put(const void *data) throw(ConversionException) + { + put((Any *)data); + } + + //!Convert a Any to a Any + /*! + * \param data : Any object + */ + void CppCpp::put(Any *data) throw(ConversionException) + { + Any *a = convertCppCpp(edGetType(),data); + DEBTRACE( "before put refcnt: " << a->getRefCnt() ); + _port->put(a); + DEBTRACE( "after put refcnt: " << a->getRefCnt() ); + //_port has called incRef + a->decrRef(); + } + + int isAdaptableCppCpp(const TypeCode *t1, const TypeCode *t2) + { + return isAdaptableNeutralNeutral(t1, t2); + } + } +} diff --git a/src/runtime/CppCppConv.hxx b/src/runtime/CppCppConv.hxx new file mode 100644 index 000000000..aeff60c86 --- /dev/null +++ b/src/runtime/CppCppConv.hxx @@ -0,0 +1,30 @@ +#ifndef CPPCPPCONV_HXX_ +#define CPPCPPCONV_HXX_ + +#include "CppPorts.hxx" +#include "ConversionException.hxx" + +namespace YACS +{ + namespace ENGINE + { + class InputCppPort; +/*! \brief Class for conversion from C++ Output port to C++ Input port + * + * \ingroup Ports + * + */ + class CppCpp : public ProxyPort + { + public: + CppCpp(InputCppPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(Any *data) throw(ConversionException); + }; + + } +} + + + +#endif /*CPPCPPCONV_HXX_*/ diff --git a/src/runtime/CppNeutralConv.cxx b/src/runtime/CppNeutralConv.cxx new file mode 100644 index 000000000..fb7cbc169 --- /dev/null +++ b/src/runtime/CppNeutralConv.cxx @@ -0,0 +1,56 @@ + +#include "TypeConversions.hxx" +#include "CppNeutralConv.hxx" + +#include +#include +#include "Any.hxx" + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; + +namespace YACS +{ + namespace ENGINE + { + Any* convertCppNeutral(const TypeCode *t, Any *a) + { + return convertNeutralNeutral(t, a); + } + + CppNeutral::CppNeutral(InputPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) + { + } + + void CppNeutral::put(const void *data) throw(ConversionException) + { + DEBTRACE(" CppNeutral::put(const void *data)"); + put((Any *)data); + } + + //! Send received C++/Neutral (Any *) value to proxy port + /*! + * \param data : Neutral (Any *) value + */ + + void CppNeutral::put(Any *data) throw(ConversionException) + { + DEBTRACE("CppNeutral::put " << data); + Any *ob; + ob=convertCppNeutral(edGetType(), data); + DEBTRACE("before put refcnt: " << ob->getRefCnt()); + _port->put(ob); + DEBTRACE( "after put refcnt: " << ob->getRefCnt() ); + //_port has called incRef + ob->decrRef(); + } + + int isAdaptableNeutralCpp(const TypeCode *t1, const TypeCode *t2) + { + return isAdaptableNeutralNeutral(t1, t2); + } + } +} diff --git a/src/runtime/CppNeutralConv.hxx b/src/runtime/CppNeutralConv.hxx new file mode 100644 index 000000000..33b851ed8 --- /dev/null +++ b/src/runtime/CppNeutralConv.hxx @@ -0,0 +1,23 @@ +#ifndef __CPPNEUTRALCONV_HXX__ +#define __CPPNEUTRALCONV_HXX__ + +#include "InputPort.hxx" + +namespace YACS +{ + namespace ENGINE + { + //Proxy port to adapt Neutral port to Python port + + class CppNeutral : public ProxyPort + { + public: + CppNeutral(InputPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(Any *data) throw(ConversionException); + }; + int isAdaptableNeutralCpp(const TypeCode * t1, const TypeCode * t2); + } +} + +#endif diff --git a/src/runtime/CppNode.cxx b/src/runtime/CppNode.cxx index d351ca7b4..720b48f4e 100644 --- a/src/runtime/CppNode.cxx +++ b/src/runtime/CppNode.cxx @@ -2,47 +2,158 @@ #include "CppNode.hxx" #include "InputPort.hxx" #include "OutputPort.hxx" +#include "CppPorts.hxx" +#include "CppContainer.hxx" +#include "CppComponent.hxx" #include #include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" using namespace YACS::ENGINE; using namespace std; -CppNode::CppNode(const string name): ElementaryNode(name) +const char CppNode::IMPL_NAME[]="Cpp"; +const char CppNode::KIND[]="Cpp"; + +CppNode::CppNode(const CppNode& other,ComposedNode *father):ServiceNode(other,father), + _run(other._run), + _componentName(other._componentName) { - _implementation = "Cpp"; - cerr << "CppNode::CppNode: " << name << endl; + DEBTRACE("CppNode::CppNode"); + _implementation=IMPL_NAME; } -void CppNode::execute() +CppNode::CppNode(const std::string & name) : ServiceNode(name), _run(NULL) { -// // --- Input Ports ready, read data + _implementation=IMPL_NAME; +} -// int nbin = _setOfInputPort.size(); -// int nbout = _setOfOutputPort.size(); -// void **input = new (void *)[nbin]; -// void **output = new (void *)[nbout]; +void CppNode::setCode(const::string & componentName, const string & method) +{ + _method = method; + _componentName = componentName; + _run = NULL; +} -// 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; -// } +void CppNode::setFunc(MYRUN fonc) { + + if (_component) + { + _component->decrRef(); + _component = NULL; + _componentName = ""; + _method = ""; + _component = NULL; + } + _run = fonc; +} -// // --- invoke service (in a thread) +void CppNode::load() +{ + if (_run) return; + + if (!_component) { + setRef(_componentName); + } + ServiceNode::load(); +} -// bool ret = (_run)(nbin, nbout, input, output); +void CppNode::execute() +{ + std::list::iterator iter1; + int nIn, nOut, it; + + nIn = _setOfInputPort.size(); + nOut = _setOfOutputPort.size(); + + Any ** In = new Any * [nIn], ** Out = new Any * [nOut]; + + try + { + + for(iter1 = _setOfInputPort.begin(), it = 0; iter1 != _setOfInputPort.end(); + iter1++, it++) + { + InputCppPort *p = dynamic_cast (*iter1); + In[it] = p->getCppObj(); + } + + if (_component) + { + CppComponent * _componentC = dynamic_cast(_component); + if (!_componentC) + throw YACS::Exception("CppNode::execute : bad type of component"); + _componentC->run(_method.c_str(), nIn, nOut, In, Out); + } + else if (_run) + _run(nIn, nOut, In, Out); + + //output parameters + std::list::iterator iter2; + for(iter2 = _setOfOutputPort.begin(), it=0; iter2 != _setOfOutputPort.end(); iter2++, it++) + { + OutputCppPort *p = dynamic_cast (*iter2); + p->put(Out[it]); + //decref it, we don't need it more + Out[it]->decrRef(); + DEBTRACE("ref count: " << Out[it]->getRefCnt()); + } + } + catch (YACS::Exception & e) { + delete [] In; + delete [] Out; + throw e; + } + + delete [] In; + delete [] Out; +} -// // --- get results, fill OutputPort with copy, then put converted data in linked InputPort +ServiceNode* CppNode::createNode(const std::string& name) +{ + CppNode* node= new CppNode(name); + node->setComponent(_component); + return node; +} -// i=0; -// for (std::set::iterator it = _setOfOutputPort.begin(); it != _setOfOutputPort.end(); it++) -// { -// Data container((*it)->edGetType()); -// container.put(output[i++]); -// (*it)->put(container); -// } +//! Clone the node : must also clone the component instance ? +Node * CppNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new CppNode(*this,father); } + +//! Create a new node of same type with a given name +CppNode* CppNode::cloneNode(const std::string& name) +{ + DEBTRACE("CppNode::cloneNode"); + CppNode* n=new CppNode(name); + + if (_run) + n->setFunc(_run); + + if (_component) + n->setCode(_componentName, _method); + + list::iterator iter; + for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++) + { + InputCppPort *p=(InputCppPort *)*iter; + DEBTRACE("port name: " << p->getName()); + DEBTRACE("port kind: " << p->edGetType()->kind()); + n->edAddInputPort(p->getName(),p->edGetType()); + } + list::iterator iter2; + for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++) + { + OutputCppPort *p=(OutputCppPort *)*iter2; + DEBTRACE("port name: " << p->getName()); + DEBTRACE("port kind: " << p->edGetType()->kind()); + n->edAddOutputPort(p->getName(),p->edGetType()); + } + return n; +} + diff --git a/src/runtime/CppNode.hxx b/src/runtime/CppNode.hxx index 56ec4c3aa..af202608b 100644 --- a/src/runtime/CppNode.hxx +++ b/src/runtime/CppNode.hxx @@ -2,24 +2,46 @@ #ifndef _CPPNODE_HXX_ #define _CPPNODE_HXX_ -#include "ElementaryNode.hxx" +#include "ServiceNode.hxx" namespace YACS { namespace ENGINE { // local C++ implementation - single process + + class CppComponent; + + typedef void (*MYRUN)(int nbin, int nbout, + YACS::ENGINE::Any **in, YACS::ENGINE::Any ** out); - typedef bool (*MYRUN)(int nbin, int nbout, void **in, void** out); - - class CppNode: public ENGINE::ElementaryNode +/*! \brief Class for C++ Nodes (in process component) + * + * local C++ implementation - single process + * + * \ingroup Nodes + * + */ + class CppNode : public YACS::ENGINE::ServiceNode { + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; public: - CppNode(const std::string name); + CppNode(const CppNode &other, ComposedNode *father); + CppNode(const std::string &name); + virtual void load(); virtual void execute(); - void setfunc(MYRUN fonc) { _run = fonc;} - + virtual ServiceNode* createNode(const std::string& name); + CppNode* cloneNode(const std::string& name); + + void setCode(const std::string & componentName, const std::string & service); + void setFunc(MYRUN fonc); + + static const char IMPL_NAME[]; + static const char KIND[]; + std::string getKind() const { return CppNode::KIND; } protected: + std::string _componentName; MYRUN _run; }; diff --git a/src/runtime/CppPorts.cxx b/src/runtime/CppPorts.cxx new file mode 100644 index 000000000..e60169027 --- /dev/null +++ b/src/runtime/CppPorts.cxx @@ -0,0 +1,177 @@ + +#include "TypeConversions.hxx" +#include "CppPorts.hxx" +#include "Node.hxx" + +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +InputCppPort::InputCppPort(const std::string& name, Node *node, TypeCode * type) + : InputPort(name, node, type), DataPort(name, node, type), Port(node), _data(NULL),_initData(NULL) +{ +} + +InputCppPort::~InputCppPort() +{ + if(_data) + { + DEBTRACE("_data ref count: " << _data->getRefCnt()); + _data->decrRef(); + } +} + +InputCppPort::InputCppPort(const InputCppPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder) +{ + _initData=other._initData; + _data=other._data; +} + +bool InputCppPort::edIsManuallyInitialized() const +{ + return _initData!= NULL; +} + +void InputCppPort::edRemoveManInit() +{ + _initData=NULL; + InputPort::edRemoveManInit(); +} + +void InputCppPort::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +void InputCppPort::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + if(_data) + _data->decrRef(); + _data=data; + _data->incrRef(); + DEBTRACE("value ref count: " << _data->getRefCnt()); +} + +InputPort *InputCppPort::clone(Node *newHelder) const +{ + return new InputCppPort(*this,newHelder); +} + +YACS::ENGINE::Any * InputCppPort::getCppObj() const +{ + return _data; +} + +void *InputCppPort::get() const throw(Exception) +{ + return (void*) _data; +} + +bool InputCppPort::isEmpty() +{ + return _data == NULL; +} + +//! Save the current data value for further reinitialization of the port +/*! + * + */ +void InputCppPort::exSaveInit() +{ + _initData=_data; + //DEBTRACE("_initData.ob refcnt: " << _initData->ob_refcnt); + //DEBTRACE("_data.ob refcnt: " << _data->ob_refcnt); +} + +//! Restore the saved data value to current data value +/*! + * If no data has been saved (_initData == 0) don't restore + */ +void InputCppPort::exRestoreInit() +{ + if(!_initData)return; + _data=_initData; + //DEBTRACE("_initData.ob refcnt: " << _initData->ob_refcnt); + //DEBTRACE("_data.ob refcnt: " << _data->ob_refcnt); +} + +std::string InputCppPort::dump() +{ + if( _data == NULL) + return "None"; + + if (edGetType()->kind() != YACS::ENGINE::Objref) + return convertNeutralXml(edGetType(), _data); + //return convertCppXml(edGetType(), _data); + if (! _stringRef.empty()) + return _stringRef; + else + return convertNeutralXml(edGetType(), _data); +// { +// stringstream msg; +// msg << "Cannot retreive init reference string for port " << _name +// << " on node " << _node->getName(); +// throw Exception(msg.str()); +// } +} + + +OutputCppPort::OutputCppPort(const std::string& name, Node *node, TypeCode * type) + : OutputPort(name, node, type), DataPort(name, node, type), Port(node) +{ + _data = NULL; +} + +OutputCppPort::~OutputCppPort() +{ + if(_data) + { + DEBTRACE("_data ref count: " << _data->getRefCnt()); + _data->decrRef(); + } +} + +OutputCppPort::OutputCppPort(const OutputCppPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder), + _data(NULL) +{ +} + +void OutputCppPort::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +void OutputCppPort::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + InputPort *p; + if(_data) + _data->decrRef(); + _data = data; + if(_data) + _data->incrRef(); + OutputPort::put(data); +} + +OutputPort *OutputCppPort::clone(Node *newHelder) const +{ + return new OutputCppPort(*this,newHelder); +} + +YACS::ENGINE::Any * OutputCppPort::get() const +{ + return _data; +} + +std::string OutputCppPort::dump() +{ + if( _data == NULL) + return "None"; + string xmldump = convertNeutralXml(edGetType(), _data); + return xmldump; +} + diff --git a/src/runtime/CppPorts.hxx b/src/runtime/CppPorts.hxx new file mode 100644 index 000000000..9745e6f91 --- /dev/null +++ b/src/runtime/CppPorts.hxx @@ -0,0 +1,63 @@ + +#ifndef _CPPPORTS_HXX_ +#define _CPPPORTS_HXX_ + +#include "Any.hxx" + +#include "InputPort.hxx" +#include "OutputPort.hxx" + +namespace YACS +{ + namespace ENGINE + { + +/*! \brief Class for C++ Ports + * + * \ingroup Ports + * + * \see CppNode + */ + class InputCppPort : public InputPort + { + public: + InputCppPort(const std::string& name, Node * node, TypeCode * type); + InputCppPort(const InputCppPort& other, Node *newHelder); + ~InputCppPort(); + bool edIsManuallyInitialized() const; + void edRemoveManInit(); + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + InputPort *clone(Node *newHelder) const; + virtual YACS::ENGINE::Any * getCppObj() const; + void *get() const throw(Exception); + virtual bool isEmpty(); + virtual void exSaveInit(); + virtual void exRestoreInit(); + virtual std::string dump(); + protected: + YACS::ENGINE::Any* _data; + YACS::ENGINE::Any* _initData; + }; + + class OutputCppPort : public OutputPort + { + public: + OutputCppPort(const std::string& name, Node * node, TypeCode * type); + OutputCppPort(const OutputCppPort& other, Node *newHelder); + ~OutputCppPort(); + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + OutputPort *clone(Node *newHelder) const; + virtual YACS::ENGINE::Any * get() const; + virtual std::string dump(); + protected: + YACS::ENGINE::Any* _data; + }; + + + + } +} + +#endif diff --git a/src/runtime/CppPythonConv.cxx b/src/runtime/CppPythonConv.cxx new file mode 100644 index 000000000..aad26be01 --- /dev/null +++ b/src/runtime/CppPythonConv.cxx @@ -0,0 +1,57 @@ + +#include "CppPythonConv.hxx" +#include "TypeConversions.hxx" + +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; + +namespace YACS +{ + namespace ENGINE + { + + PyObject *convertCppPyObject(const TypeCode *t, Any *a) + { + return convertNeutralPyObject(t, (Any *) a); + } + + CppPy::CppPy(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) + { + } + + //!Convert the received C++ value to PyObject * and send it to proxy port + /*! + * \param data : C++ value received + */ + void CppPy::put(const void *data) throw(ConversionException) + { + put((Any *) data); + } + + void CppPy::put(Any *data) throw(ConversionException) + { + DEBTRACE(" CppPython::put(Any *data)"); + PyObject *ob; + { + InterpreterUnlocker l; + ob=convertCppPyObject(edGetType(), data); + PyObject_Print(ob,stderr,Py_PRINT_RAW); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); + } + _port->put(ob); + Py_DECREF(ob); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); + } + + int isAdaptablePyObjectCpp(const TypeCode *t1, const TypeCode *t2) + { + return isAdaptablePyObjectNeutral(t1, t2); + } + + } +} diff --git a/src/runtime/CppPythonConv.hxx b/src/runtime/CppPythonConv.hxx new file mode 100644 index 000000000..949886b30 --- /dev/null +++ b/src/runtime/CppPythonConv.hxx @@ -0,0 +1,23 @@ +#ifndef __CPPPYTHONCONV_HXX__ +#define __CPPPYTHONCONV_HXX__ + +#include "PythonPorts.hxx" + +namespace YACS +{ + namespace ENGINE + { + //Proxy port to adapt Python port to Cpp + + class CppPy : public ProxyPort + { + public: + CppPy(InputPyPort* p); + virtual void put(const void *data) throw(ConversionException); + virtual void put(Any *a) throw(ConversionException); + }; + int isAdaptablePyObjectCpp(const TypeCode *t1, const TypeCode *t2); + } +} + +#endif diff --git a/src/runtime/CppXMLConv.cxx b/src/runtime/CppXMLConv.cxx new file mode 100644 index 000000000..b6b1f1327 --- /dev/null +++ b/src/runtime/CppXMLConv.cxx @@ -0,0 +1,56 @@ + +#include "TypeConversions.hxx" +#include "CppXMLConv.hxx" + +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; + +namespace YACS +{ + namespace ENGINE + { + std::string convertCppXml(const TypeCode *t, void *ob) + { + return convertNeutralXml(t, (Any *) ob); + } + + CppXml::CppXml(InputXmlPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) + { + DEBTRACE("proxy port from C++ to XML"); + } + + //!Convert a YACS::ENGINE::Any that is convertible to Xml::char * and send it to proxy port + /*! + * \param data : YACS::ENGINE::Any object as a void * pointer + */ + + void CppXml::put(const void *data) throw(ConversionException) + { + put((YACS::ENGINE::Any *)data); + } + + //!Convert a YACS::ENGINE::Any that is convertible to Xml::char * and send it to proxy port + /*! + * \param data : YACS::ENGINE::Any object + */ + void CppXml::put(YACS::ENGINE::Any *data) throw(ConversionException) + { + DEBTRACE("CppXml::put"); + std::string s = convertCppXml(edGetType(), data); + DEBTRACE(s); + DEBTRACE(_port->getName()); + ((InputXmlPort*)_port)->put(s.c_str()); + DEBTRACE("End CppXml::put"); + } + + int isAdaptableXmlCpp(const TypeCode *t1, const TypeCode *t2) + { + return isAdaptableXmlNeutral(t1, t2); + } + } +} diff --git a/src/runtime/CppXMLConv.hxx b/src/runtime/CppXMLConv.hxx new file mode 100644 index 000000000..545a22af0 --- /dev/null +++ b/src/runtime/CppXMLConv.hxx @@ -0,0 +1,22 @@ +#ifndef __CPPXMLCONV_HXX__ +#define __CPPXMLCONV_HXX__ + +#include "XMLPorts.hxx" + +namespace YACS +{ + namespace ENGINE + { + // Adaptator Ports Corba->Xml for several types + + class CppXml : public ProxyPort + { + public: + CppXml(InputXmlPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + int isAdaptableXmlCpp(const TypeCode *t1, const TypeCode *t2); + } +} +#endif diff --git a/src/runtime/Makefile.am b/src/runtime/Makefile.am index 8b34bb667..f9b9f0ddb 100644 --- a/src/runtime/Makefile.am +++ b/src/runtime/Makefile.am @@ -3,36 +3,155 @@ include $(top_srcdir)/adm/unix/make_begin.am SUBDIRS = Test + + lib_LTLIBRARIES = libYACSRuntimeSALOME.la libYACSRuntimeSALOME_la_SOURCES = \ + TypeConversions.cxx \ CORBACORBAConv.cxx \ - CORBANode.cxx \ - CORBAPorts.cxx \ CORBAPythonConv.cxx \ CORBAXMLConv.cxx \ + CORBANeutralConv.cxx \ + XMLCORBAConv.cxx \ + XMLPythonConv.cxx \ + XMLNeutralConv.cxx \ + CORBANode.cxx \ + CORBAPorts.cxx \ CppNode.cxx \ + CppPorts.cxx \ + NeutralPythonConv.cxx \ + NeutralCORBAConv.cxx \ + NeutralXMLConv.cxx \ PythonCORBAConv.cxx \ + PythonNeutralConv.cxx \ + PythonXMLConv.cxx \ PythonNode.cxx \ + SalomePythonNode.cxx \ + SalomePythonComponent.cxx \ + SalomeContainer.cxx \ PythonPorts.cxx \ - RuntimeSALOME.cxx \ - TypeConversions.cxx \ - XMLCORBAConv.cxx \ XMLNode.cxx \ XMLPorts.cxx \ + RuntimeSALOME.cxx \ + SALOMEDispatcher.cxx \ + SalomeProc.cxx \ + CalStreamPort.cxx \ + CORBAComponent.cxx \ + SalomeComponent.cxx \ + CppComponent.cxx \ + CppContainer.cxx \ + CppCORBAConv.cxx \ + CppNeutralConv.cxx \ + CppXMLConv.cxx \ + CppCppConv.cxx \ + CppPythonConv.cxx \ + CORBACppConv.cxx \ + NeutralCppConv.cxx \ + XMLCppConv.cxx \ + PythonCppConv.cxx \ $(__dummy__) + EXTRA_libYACSRuntimeSALOME_la_SOURCES = \ $(__dummy__) -libYACSRuntimeSALOME_la_LIBADD = ../bases/libYACSBases.la +if SALOME_KERNEL +libYACSRuntimeSALOME_la_SOURCES += ../../idl/yacsguiSK.cc + +SALOME_IDL = \ + $(KERNEL_ROOT_DIR)/idl/salome/SALOME_ContainerManager.idl \ + $(KERNEL_ROOT_DIR)/idl/salome/SALOME_Component.idl \ + $(KERNEL_ROOT_DIR)/idl/salome/SALOME_Exception.idl + +SALOME_INCLUDES =SALOME_ContainerManager.hh SALOME_Exception.hh SALOME_Component.hh +SALOME_LIBS=-L$(KERNEL_ROOT_DIR)/lib@LIB_LOCATION_SUFFIX@/salome -lSalomeLifeCycleCORBA +SALOME_INCL_PATH=-I$(KERNEL_ROOT_DIR)/include/salome $(QT_INCLUDES) +SALOME_OMNIPY= +endif + +if DSC_PORTS +DSC_IDL = $(KERNEL_ROOT_DIR)/idl/salome/DSC_Engines.idl \ + $(KERNEL_ROOT_DIR)/idl/salome/SALOME_Ports.idl +DSC_INCLUDES = DSC_Engines.hh SALOME_Ports.hh +DSC_LIBS=-L$(KERNEL_ROOT_DIR)/lib@LIB_LOCATION_SUFFIX@/salome -lSalomeDSCContainer +DSC_INCL_PATH=-I$(KERNEL_ROOT_DIR)/include +DSC_OMNIPY=DSC_Engines_idl.py +endif + +IDL_FILES=$(DSC_IDL) $(SALOME_IDL) +BUILT_SOURCES=$(DSC_INCLUDES) $(SALOME_INCLUDES) SALOMERuntimeWRAP.cxx + +libYACSRuntimeSALOME_la_LIBADD = \ + $(DSC_LIBS) $(SALOME_LIBS) $(OMNIORB_LIBS) \ + ../engine/libYACSEngine.la + +AM_CXXFLAGS = \ + $(THREAD_DEF) \ + $(PYTHON_CPPFLAGS) \ + $(OMNIORB_INCLUDES) \ + -I$(OMNIORB_ROOT)/include/omniORB4/internal \ + $(OMNIORB_CXXFLAGS) \ + $(SALOME_INCL_PATH) \ + $(DSC_INCL_PATH) \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + -I../../idl \ + -I/usr/include/libxml2 + + + +############################################################ + +if SALOME_KERNEL +SALOME_Component.hh:$(KERNEL_ROOT_DIR)/idl/salome/SALOME_Component.idl + $(OMNIORB_IDL) $(OMNIORB_IDLCXXFLAGS) -bcxx -I$(KERNEL_ROOT_DIR)/idl/salome $< +SALOME_Exception.hh:$(KERNEL_ROOT_DIR)/idl/salome/SALOME_Exception.idl + $(OMNIORB_IDL) $(OMNIORB_IDLCXXFLAGS) -bcxx -I$(KERNEL_ROOT_DIR)/idl/salome $< +SALOME_ContainerManager.hh:$(KERNEL_ROOT_DIR)/idl/salome/SALOME_ContainerManager.idl + $(OMNIORB_IDL) $(OMNIORB_IDLCXXFLAGS) -bcxx -I$(KERNEL_ROOT_DIR)/idl/salome $< + +SALOME_Component_idl.py:$(KERNEL_ROOT_DIR)/idl/salome/SALOME_Component.idl + $(OMNIORB_IDL) -bpython -I. -I$(KERNEL_ROOT_DIR)/idl/salome $< +endif + +if DSC_PORTS +DSC_Engines.hh:$(KERNEL_ROOT_DIR)/idl/salome/DSC_Engines.idl + $(OMNIORB_IDL) $(OMNIORB_IDLCXXFLAGS) -bcxx -I$(KERNEL_ROOT_DIR)/idl $< +SALOME_Ports.hh:$(KERNEL_ROOT_DIR)/idl/salome/SALOME_Ports.idl + $(OMNIORB_IDL) $(OMNIORB_IDLCXXFLAGS) -bcxx -I$(KERNEL_ROOT_DIR)/idl $< + +SALOME_Ports_idl.py :$(KERNEL_ROOT_DIR)/idl/salome/SALOME_Ports.idl + $(OMNIORB_IDL) -bpython -I. -I$(KERNEL_ROOT_DIR)/idl $< +endif + +################################################################# + +pkgpython_PYTHON = SALOMERuntime.py +pkgpyexec_LTLIBRARIES = _SALOMERuntime.la + +_SALOMERuntime_la_SOURCES = \ + SALOMERuntimeWRAP.cxx + +MYSWIG_FLAGS = -noexcept -I$(srcdir)/../bases -I$(srcdir)/../engine + +_SALOMERuntime_la_CXXFLAGS = \ + $(THREAD_DEF) \ + $(PYTHON_CPPFLAGS) \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CXXFLAGS) \ + -I$(KERNEL_ROOT_DIR)/include/salome \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + -I../../idl \ + -I/usr/include/libxml2 + +_SALOMERuntime_la_LDFLAGS = -module + +_SALOMERuntime_la_LIBADD = libYACSRuntimeSALOME.la \ + ../engine/libYACSEngine.la \ + $(DSC_LIBS) $(SALOME_LIBS) \ + -lxml2 -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/NeutralCORBAConv.cxx b/src/runtime/NeutralCORBAConv.cxx new file mode 100644 index 000000000..b8e9b119f --- /dev/null +++ b/src/runtime/NeutralCORBAConv.cxx @@ -0,0 +1,124 @@ + +#include "TypeConversions.hxx" +#include "RuntimeSALOME.hxx" +#include "NeutralCORBAConv.hxx" + +#include + +using namespace YACS::ENGINE; +using namespace std; + + +void NeutralCorbaInt::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +//!Convert a YACS::ENGINE::Any (integer) to CORBA::Any (integer) +/*! + * \param data : YACS::ENGINE::Any object + */ + +void NeutralCorbaInt::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + CORBA::Long l= data->getIntValue(); + CORBA::Any a; + a <<= l; + _port->put(&a); +} + +void NeutralCorbaBool::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +//!Convert a YACS::ENGINE::Any (boolean) to CORBA::Any (boolean) +/*! + * \param data : YACS::ENGINE::Any object + */ + +void NeutralCorbaBool::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + CORBA::Any *a =convertNeutralCorba(edGetType(),data); + _port->put(a); + //delete Any that has been allocated by convertNeutralCorba + delete a; +} + + +void NeutralCorbaDouble::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +//!Convert a YACS::ENGINE::Any (double) to CORBA::Any (double) +/*! + * \param data : YACS::ENGINE::Any object + */ + +void NeutralCorbaDouble::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + CORBA::Double d = data->getDoubleValue(); + CORBA::Any a; + a <<= d; + _port->put(&a); +} + +void NeutralCorbaSequence::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +//!Convert a Neutral::Any sequence to CORBA::Any* Sequence +/*! + * \param data : Neutral::Any object + */ +void NeutralCorbaSequence::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + CORBA::Any *a =convertNeutralCorba(edGetType(),data); + _port->put(a); + //delete Any that has been allocated by convertNeutralCorba + delete a; +} + +NeutralCorbaString::NeutralCorbaString(InputCorbaPort* p):ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{ +} + +void NeutralCorbaString::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +//!Convert a Neutral::Any string to CORBA::Any* string +/*! + * \param data : Neutral::Any object + */ +void NeutralCorbaString::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + string val=data->getStringValue(); + CORBA::Any a; + a <<= val.c_str(); + _port->put(&a); +} + +NeutralCorbaObjref::NeutralCorbaObjref(InputCorbaPort* p):ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{ +} + +void NeutralCorbaObjref::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +//!Convert a Neutral::Any Objref to CORBA::Any* Objref +/*! + * \param data : Neutral::Any object + */ +void NeutralCorbaObjref::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + CORBA::Any *a =convertNeutralCorba(edGetType(),data); + _port->put(a); + //delete Any that has been allocated by convertNeutralCorba + delete a; +} diff --git a/src/runtime/NeutralCORBAConv.hxx b/src/runtime/NeutralCORBAConv.hxx new file mode 100644 index 000000000..692260a35 --- /dev/null +++ b/src/runtime/NeutralCORBAConv.hxx @@ -0,0 +1,68 @@ +#ifndef __NEUTRALCORBACONV_HXX__ +#define __NEUTRALCORBACONV_HXX__ + +#include "ConversionException.hxx" +#include "CORBAPorts.hxx" +#include "Any.hxx" + +namespace YACS +{ + namespace ENGINE + { + + // --- adaptator ports Neutral->Corba for several types + + class NeutralCorbaInt : public ProxyPort + { + public: + NeutralCorbaInt(InputCorbaPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + + class NeutralCorbaDouble : public ProxyPort + { + public: + NeutralCorbaDouble(InputCorbaPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + + class NeutralCorbaBool : public ProxyPort + { + public: + NeutralCorbaBool(InputCorbaPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + + class NeutralCorbaSequence : public ProxyPort + { + public: + NeutralCorbaSequence(InputCorbaPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + + class NeutralCorbaString : public ProxyPort + { + public: + NeutralCorbaString(InputCorbaPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + + class NeutralCorbaObjref : public ProxyPort + { + public: + NeutralCorbaObjref(InputCorbaPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + } +} +#endif diff --git a/src/runtime/NeutralCppConv.cxx b/src/runtime/NeutralCppConv.cxx new file mode 100644 index 000000000..d149e8c57 --- /dev/null +++ b/src/runtime/NeutralCppConv.cxx @@ -0,0 +1,56 @@ +#include "TypeConversions.hxx" +#include "NeutralCppConv.hxx" +#include "CppPorts.hxx" + +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; + +namespace YACS +{ + namespace ENGINE + { + Any * convertNeutralCpp(const TypeCode *t, Any *data) + { + return convertNeutralNeutral(t, data); + } + + NeutralCpp::NeutralCpp(InputCppPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) + { + } + + //!Convert a Any to a Any + /*! + * transition method from const void* to Any* + * \param data : const void * data + */ + void NeutralCpp::put(const void *data) throw(ConversionException) + { + put((Any *)data); + } + + //!Convert a Any to a Any + /*! + * \param data : Any object + */ + void NeutralCpp::put(Any *data) throw(ConversionException) + { + Any *a = convertNeutralCpp(edGetType(),data); + DEBTRACE( "before put refcnt: " << a->getRefCnt() ); + _port->put(a); + DEBTRACE( "after put refcnt: " << a->getRefCnt() ); + //_port has called incRef + a->decrRef(); + } + + int isAdaptableCppNeutral(const TypeCode *t1, const TypeCode *t2) + { + return isAdaptableNeutralNeutral(t1, t2); + } + + } +} diff --git a/src/runtime/NeutralCppConv.hxx b/src/runtime/NeutralCppConv.hxx new file mode 100644 index 000000000..c523b60fe --- /dev/null +++ b/src/runtime/NeutralCppConv.hxx @@ -0,0 +1,29 @@ +#ifndef NEUTRALCPPCONV_HXX_ +#define NEUTRALCPPCONV_HXX_ + +#include "InputPort.hxx" +#include "ConversionException.hxx" + +namespace YACS +{ + namespace ENGINE + { + class InputCppPort; +/*! \brief Class for conversion from Neutral Output port to Xml Input port + * + * \ingroup Ports + * + */ + class NeutralCpp : public ProxyPort + { + public: + NeutralCpp(InputCppPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + int isAdaptableCppNeutral(const TypeCode * t1, const TypeCode * t2); + } +} + + +#endif /*NEUTRALCPPCONV_HXX_*/ diff --git a/src/runtime/NeutralPythonConv.cxx b/src/runtime/NeutralPythonConv.cxx new file mode 100644 index 000000000..ed6c156ea --- /dev/null +++ b/src/runtime/NeutralPythonConv.cxx @@ -0,0 +1,142 @@ + +#include "NeutralPythonConv.hxx" +#include "TypeConversions.hxx" +#include "RuntimeSALOME.hxx" + +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +void NeutralPyDouble::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +//!Convert a YACS::ENGINE::Any (double) to a PyObject (PyFloat) +/*! + * \param data : YACS::ENGINE::Any object + */ +void NeutralPyDouble::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + double d = data->getDoubleValue(); + PyObject *ob=PyFloat_FromDouble(d); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); + _port->put(ob); + Py_DECREF(ob); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); +} + + +void NeutralPyInt::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +//!Convert a YACS::ENGINE::Any (integer) to a PyObject (PyLong) +/*! + * \param data : YACS::ENGINE::Any object + */ +void NeutralPyInt::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + int l = data->getIntValue(); + PyObject *ob=PyLong_FromLong(l); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); + _port->put(ob); + Py_DECREF(ob); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); +} + +void NeutralPyString::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +//!Convert a YACS::ENGINE::Any (string) to a PyObject (PyString) +/*! + * \param data : YACS::ENGINE::Any object + */ +void NeutralPyString::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + string val=data->getStringValue(); + PyObject *ob=PyString_FromString(val.c_str()); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); + _port->put(ob); + Py_DECREF(ob); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); +} + +void NeutralPyBool::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +//!Convert a YACS::ENGINE::Any (bool) to a PyObject (PyLong) +/*! + * \param data : YACS::ENGINE::Any object + */ +void NeutralPyBool::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + int l = data->getBoolValue(); + PyObject *ob=PyLong_FromLong(l); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); + _port->put(ob); + Py_DECREF(ob); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); +} + +void NeutralPyObjref::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +//!Convert a Neutral::Any Objref to a PyObject Objref +/*! + * \param data : Neutral::Any object + */ +void NeutralPyObjref::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + PyObject *ob; + { + InterpreterUnlocker loc; + ob=convertNeutralPyObject(edGetType(),data); + } + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); + _port->put(ob); + Py_DECREF(ob); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); +} + +void NeutralPySequence::put(const void *data) throw(ConversionException) +{ + put((YACS::ENGINE::Any *)data); +} + +//!Convert a Neutral::Any sequence to a PyObject Sequence +/*! + * \param data : Neutral::Any object + */ +void NeutralPySequence::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + DEBTRACE( "--------NeutralPySequence::put" ); + PyObject *ob; + { + InterpreterUnlocker loc; + ob=convertNeutralPyObject(edGetType(),data); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); +#ifdef _DEVDEBUG_ + cerr << "Sequence= "; + PyObject_Print(ob,stderr,Py_PRINT_RAW); + cerr << endl; +#endif + } + _port->put(ob); + Py_DECREF(ob); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); +} + + diff --git a/src/runtime/NeutralPythonConv.hxx b/src/runtime/NeutralPythonConv.hxx new file mode 100644 index 000000000..b1fc4e053 --- /dev/null +++ b/src/runtime/NeutralPythonConv.hxx @@ -0,0 +1,69 @@ +#ifndef __NEUTRALPYTHONCONV_HXX__ +#define __NEUTRALPYTHONCONV_HXX__ + +#include "PythonPorts.hxx" +#include "Any.hxx" + +namespace YACS +{ + namespace ENGINE + { + + // --- adaptator ports Neutral->Python for several types + + class NeutralPyDouble : public ProxyPort + { + public: + NeutralPyDouble(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + + class NeutralPyInt : public ProxyPort + { + public: + NeutralPyInt(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + + class NeutralPyString : public ProxyPort + { + public: + NeutralPyString(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + + class NeutralPyBool : public ProxyPort + { + public: + NeutralPyBool(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + + class NeutralPyObjref : public ProxyPort + { + public: + NeutralPyObjref(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + + class NeutralPySequence : public ProxyPort + { + public: + NeutralPySequence(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + } +} +#endif diff --git a/src/runtime/NeutralXMLConv.cxx b/src/runtime/NeutralXMLConv.cxx new file mode 100644 index 000000000..50f17895a --- /dev/null +++ b/src/runtime/NeutralXMLConv.cxx @@ -0,0 +1,35 @@ +#include "TypeConversions.hxx" +#include "NeutralXMLConv.hxx" + +#include +#include +#include "Any.hxx" + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +NeutralXml::NeutralXml(InputXmlPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{ +} + +void NeutralXml::put(const void *data) throw(ConversionException) +{ + DEBTRACE(" NeutralXml::put(const void *data)"); + put((YACS::ENGINE::Any *)data); +} + +//!Convert received Neutral (Any *) value to XML value and send it to proxy port + /*! + * \param data : YACS::ENGINE::Any object + */ + +void NeutralXml::put(YACS::ENGINE::Any *data) throw(ConversionException) +{ + DEBTRACE("NeutralXml::put " << data); + std::string sss = convertNeutralXml(edGetType(),data); + ((InputXmlPort*)_port)->put((const char*)sss.c_str()); +} diff --git a/src/runtime/NeutralXMLConv.hxx b/src/runtime/NeutralXMLConv.hxx new file mode 100644 index 000000000..a5647d22c --- /dev/null +++ b/src/runtime/NeutralXMLConv.hxx @@ -0,0 +1,27 @@ +#ifndef __NEUTRALXMLCONV_HXX__ +#define __NEUTRALXMLCONV_HXX__ + +#include "XMLPorts.hxx" + +namespace YACS +{ + namespace ENGINE + { + class Any; + +/*! \brief Class for conversion from Neutral Output port to XML Input port + * + * \ingroup AdaptorPorts + * + */ + class NeutralXml : public ProxyPort + { + public: + NeutralXml(InputXmlPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(YACS::ENGINE::Any *data) throw(ConversionException); + }; + } +} + +#endif diff --git a/src/runtime/PythonCORBAConv.cxx b/src/runtime/PythonCORBAConv.cxx index ce08d4626..c5657e71c 100644 --- a/src/runtime/PythonCORBAConv.cxx +++ b/src/runtime/PythonCORBAConv.cxx @@ -1,46 +1,89 @@ +//#define REFCNT +#ifdef REFCNT +#define private public +#define protected public +#include +#include +#endif + #include "PythonCORBAConv.hxx" #include "TypeConversions.hxx" #include "RuntimeSALOME.hxx" #include +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + using namespace YACS::ENGINE; using namespace std; - +/*!Convert a PyObject (integer) to CORBA::Any (integer) + * It's only a wrapper around put(PyObject *data) + */ void PyCorbaInt::put(const void *data) throw(ConversionException) { put((PyObject *)data); } -//!Convertit un PyObject de type entier en CORBA::Any entier +//!Convert a PyObject (integer) to CORBA::Any (integer) /*! * \param data : python object */ - void PyCorbaInt::put(PyObject *data) throw(ConversionException) { - CORBA::Long l= PyLong_AsLong(data); + CORBA::Long l= 0; + if (PyInt_Check(data))l=PyInt_AS_LONG(data); + else if(PyLong_Check(data))l=PyLong_AsLong(data); + else throw ConversionException("Not an int"); + CORBA::Any a; a <<= l; _port->put(&a); } +//!Convert a PyObject (boolean) to CORBA::Any (boolean) +/*! + * It's only a wrapper around PyCorbaBool::put(PyObject *data) + * + * \param data : python object + */ +void PyCorbaBool::put(const void *data) throw(ConversionException) +{ + put((PyObject *)data); +} + +//!Convert a PyObject (boolean) to CORBA::Any (boolean) +/*! + * Convert it and push it to proxy port + * + * \param data : python object + */ +void PyCorbaBool::put(PyObject *data) throw(ConversionException) +{ + CORBA::Any *a= convertPyObjectCorba(_port->edGetType(),data); + _port->put(a); + //delete Any that has been allocated by convertPyObjectCorba + delete a; +} void PyCorbaString::put(const void *data) throw(ConversionException) { put((PyObject *)data); } -//!Convertit un PyObject de type string en CORBA::Any string +//!Convert a PyObject (string) to CORBA::Any (string) /*! * \param data : python object */ void PyCorbaString::put(PyObject *data) throw(ConversionException) { - char * s=PyString_AsString(data); + char * s; + if(PyString_Check(data))s=PyString_AsString(data); + else throw ConversionException("Not a string"); + CORBA::Any a; a <<= s; _port->put(&a); @@ -52,7 +95,7 @@ void PyCorbaDouble::put(const void *data) throw(ConversionException) put((PyObject *)data); } -//!Convertit un PyObject de type double en CORBA::Any Double +//!Convert a PyObject (double) to CORBA::Any (double) /*! * \param data : python object */ @@ -60,24 +103,26 @@ void PyCorbaDouble::put(const void *data) throw(ConversionException) 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); + if (PyFloat_Check(data)) d = (CORBA::Double)PyFloat_AS_DOUBLE(data); + else if (PyInt_Check(data)) d = (CORBA::Double)PyInt_AS_LONG(data); + else if (PyLong_Check(data)) d = (CORBA::Double)PyLong_AsDouble(data); + else throw ConversionException("Not a double"); + CORBA::Any a; a <<= d; _port->put(&a); } +//!Class PyCorbaSequence is a proxy port that converts a PyObject object (of type sequence) to a CORBA::Any object (of type sequence) +/*! + * \param p : the input CORBA port to adapt to Python output port + */ PyCorbaSequence::PyCorbaSequence(InputCorbaPort* p) - : ProxyPort(p), Port(p->getNode()) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) { - cerr << "CorbaPySequence" << endl; } -//!Convertit un PyObject de type Sequence en CORBA::Any Sequence +//!Convert a PyObject (sequence) to CORBA::Any (sequence) /*! * \param data : python object */ @@ -89,26 +134,36 @@ void PyCorbaSequence::put(const void *data) throw(ConversionException) 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); + DEBTRACE("data refcnt: " << data->ob_refcnt); +#ifdef _DEVDEBUG_ + PyObject_Print(data,stderr,Py_PRINT_RAW); + std::cerr << std::endl; +#endif + CORBA::Any *a= convertPyObjectCorba(_port->edGetType(),data); _port->put(a); +#ifdef REFCNT + DEBTRACE("refcount CORBA seqTC: " << ((omni::TypeCode_base*)a->pd_tc.in())->pd_ref_count); +#endif + //delete Any that has been allocated by convertPyObjectCorba + delete a; +#ifdef REFCNT + DEBTRACE("refcount CORBA seqTC: " << ((omni::TypeCode_base*)((InputCorbaPort*)_port)->getAny()->pd_tc.in())->pd_ref_count); +#endif } - +//!Class PyCorbaObjref is a proxy port that converts a PyObject object (of type objref) to a CORBA::Any object (of type objref) +/*! + * \param p : the input CORBA port to adapt to Python output port + */ PyCorbaObjref::PyCorbaObjref(InputCorbaPort* p) - : ProxyPort(p), Port(p->getNode()) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) { _pyorb = getSALOMERuntime()->getPyOrb(); _orb = getSALOMERuntime()->getOrb(); // _dynFactory = getSALOMERuntime()->getDynFactory(); } -//!Convertit un PyObject de type Objref en CORBA::Any Objref +//!Convert a PyObject (Objref) to CORBA::Any (Objref) /*! * \param data : python object */ @@ -120,33 +175,65 @@ void PyCorbaObjref::put(const void *data) throw(ConversionException) 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; + DEBTRACE("data refcnt: " << data->ob_refcnt); +#ifdef _DEVDEBUG_ + PyObject_Print(data,stderr,Py_PRINT_RAW); + std::cerr << std::endl; +#endif - //ne marche pas ??? + //does not work : replace by a call to object_to_string - string_to_object //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"); + throw ConversionException("can't get objref"); } - - PyObject_Print(pystring,stdout,Py_PRINT_RAW); - cerr << endl; - CORBA::Object_ptr ob= _orb->string_to_object(PyString_AsString(pystring)); + CORBA::Object_var 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); } +//!Class PyCorbaStruct is a proxy port that converts a PyObject object (of type struct) to a CORBA::Any object (of type struct) +/*! + * \param p : the input CORBA port to adapt to Python output port + */ +PyCorbaStruct::PyCorbaStruct(InputCorbaPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{ +} + +void PyCorbaStruct::put(const void *data) throw(ConversionException) +{ + put((PyObject *)data); +} + +//!Convert a PyObject (struct) to CORBA::Any (struct) +/*! + * \param data : python object + */ +void PyCorbaStruct::put(PyObject *data) throw(ConversionException) +{ + DEBTRACE("data refcnt: " << data->ob_refcnt); +#ifdef _DEVDEBUG_ + PyObject_Print(data,stderr,Py_PRINT_RAW); + std::cerr << std::endl; +#endif + CORBA::Any *a= convertPyObjectCorba(_port->edGetType(),data); + _port->put(a); +#ifdef REFCNT + DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)a->pd_tc.in())->pd_ref_count); +#endif + //delete Any that has been allocated by convertPyObjectCorba + delete a; +#ifdef REFCNT + DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)((InputCorbaPort*)_port)->getAny()->pd_tc.in())->pd_ref_count); +#endif +} + diff --git a/src/runtime/PythonCORBAConv.hxx b/src/runtime/PythonCORBAConv.hxx index 180e170be..824e66975 100644 --- a/src/runtime/PythonCORBAConv.hxx +++ b/src/runtime/PythonCORBAConv.hxx @@ -10,13 +10,13 @@ namespace YACS namespace ENGINE { - // --- convertisseurs Python->Corba pour les différents types + // --- adaptator ports Python->Corba for several types class PyCorbaInt : public ProxyPort { public: PyCorbaInt(InputCorbaPort* p) - : ProxyPort(p), Port(p->getNode()) {} + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} virtual void put(const void *data) throw(ConversionException); void put(PyObject *data) throw(ConversionException); }; @@ -25,7 +25,7 @@ namespace YACS { public: PyCorbaDouble(InputCorbaPort* p) - : ProxyPort(p), Port(p->getNode()) {} + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} virtual void put(const void *data) throw(ConversionException); void put(PyObject *data) throw(ConversionException); }; @@ -34,7 +34,16 @@ namespace YACS { public: PyCorbaString(InputCorbaPort* p) - : ProxyPort(p), Port(p->getNode()) {} + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(PyObject *data) throw(ConversionException); + }; + + class PyCorbaBool : public ProxyPort + { + public: + PyCorbaBool(InputCorbaPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} virtual void put(const void *data) throw(ConversionException); void put(PyObject *data) throw(ConversionException); }; @@ -47,7 +56,7 @@ namespace YACS void put(PyObject *data) throw(ConversionException); protected: PyObject * _pyorb; - CORBA::ORB_var _orb; + CORBA::ORB_ptr _orb; }; class PyCorbaSequence : public ProxyPort @@ -58,6 +67,14 @@ namespace YACS void put(PyObject *data) throw(ConversionException); }; + class PyCorbaStruct : public ProxyPort + { + public: + PyCorbaStruct(InputCorbaPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(PyObject *data) throw(ConversionException); + }; + } } #endif diff --git a/src/runtime/PythonCppConv.cxx b/src/runtime/PythonCppConv.cxx new file mode 100644 index 000000000..2b80f87eb --- /dev/null +++ b/src/runtime/PythonCppConv.cxx @@ -0,0 +1,49 @@ + +#include "PythonCppConv.hxx" +#include "TypeConversions.hxx" +#include "RuntimeSALOME.hxx" + +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; + +namespace YACS +{ + namespace ENGINE + { + Any * convertPyObjectCpp(const TypeCode *t, PyObject *data) + { + return convertPyObjectNeutral(t, data); + } + + void PyCpp::put(const void *data) throw(ConversionException) + { + put((PyObject *)data); + } + + //!Convertit un PyObject de type entier en YACS::ENGINE::Any entier + /*! + * \param data : python object + */ + + void PyCpp::put(PyObject *data) throw(ConversionException) + { + YACS::ENGINE::Any *a; + //Do not need to take the Python GIL as put is called from Python node + a = convertPyObjectCpp(edGetType(), data); + DEBTRACE( "before put refcnt: " << a->getRefCnt() ); + _port->put(a); + //_port has called incRef + a->decrRef(); + DEBTRACE( "after put refcnt: " << a->getRefCnt() ); + } + + int isAdaptableCppPyObject(const TypeCode *t1, const TypeCode *t2) + { + return isAdaptableNeutralPyObject(t1, t2); + } + } +} diff --git a/src/runtime/PythonCppConv.hxx b/src/runtime/PythonCppConv.hxx new file mode 100644 index 000000000..8258f62bb --- /dev/null +++ b/src/runtime/PythonCppConv.hxx @@ -0,0 +1,25 @@ +#ifndef __PYTHONCPPCONV_HXX__ +#define __PYTHONCPPCONV_HXX__ + +#include +#include "CppPorts.hxx" + +namespace YACS +{ + namespace ENGINE + { + //Proxy port to adapt C++ port to Python port + + class PyCpp : public ProxyPort + { + public: + PyCpp(InputCppPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) {} + virtual void put(const void *data) throw(ConversionException); + void put(PyObject *data) throw(ConversionException); + }; + int isAdaptableCppPyObject(const TypeCode *t1, const TypeCode *t2); + } +} + +#endif diff --git a/src/runtime/PythonNeutralConv.cxx b/src/runtime/PythonNeutralConv.cxx new file mode 100644 index 000000000..6887f05aa --- /dev/null +++ b/src/runtime/PythonNeutralConv.cxx @@ -0,0 +1,42 @@ + +#include "TypeConversions.hxx" +#include "PythonNeutralConv.hxx" + +#include +#include +#include "Any.hxx" + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +PyNeutral::PyNeutral(InputPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{ +} + +void PyNeutral::put(const void *data) throw(ConversionException) +{ + DEBTRACE( " PyNeutral::put(const void *data)" ); + put((PyObject *)data); +} + +//!Convert received Python (PyObject *) value to Neutral (Any *) value and send it to proxy port + /*! + * \param data : Python value + */ + +void PyNeutral::put(PyObject *data) throw(ConversionException) +{ + DEBTRACE( "PyNeutral::put " ); + YACS::ENGINE::Any *ob; + //Do not need to take the Python GIL as put is called from Python node + ob=convertPyObjectNeutral(edGetType(),data); + DEBTRACE( "before put refcnt: " << ob->getRefCnt() ); + _port->put(ob); + //_port has called incRef + ob->decrRef(); + DEBTRACE( "after put refcnt: " << ob->getRefCnt() ); +} diff --git a/src/runtime/PythonNeutralConv.hxx b/src/runtime/PythonNeutralConv.hxx new file mode 100644 index 000000000..ef9521603 --- /dev/null +++ b/src/runtime/PythonNeutralConv.hxx @@ -0,0 +1,23 @@ +#ifndef __PYTHONNEUTRALCONV_HXX__ +#define __PYTHONNEUTRALCONV_HXX__ + +#include +#include "InputPort.hxx" + +namespace YACS +{ + namespace ENGINE + { + //Proxy port to adapt Neutral port to Python port + + class PyNeutral : public ProxyPort + { + public: + PyNeutral(InputPort* 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 index 913346b17..2f5667873 100644 --- a/src/runtime/PythonNode.cxx +++ b/src/runtime/PythonNode.cxx @@ -1,79 +1,360 @@ -#include "PythonNode.hxx" #include "RuntimeSALOME.hxx" +#include "PythonNode.hxx" +#include "PythonPorts.hxx" #include #include +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + using namespace YACS::ENGINE; using namespace std; -PythonNode::PythonNode(const string& name): ElementaryNode(name) +const char PythonNode::IMPL_NAME[]="Python"; +const char PythonNode::KIND[]="Python"; + +PythonNode::PythonNode(const PythonNode& other, ComposedNode *father):InlineNode(other,father) { - _implementation = "Python"; - cerr << "PythonNode::PythonNode " << name << endl; + _implementation=IMPL_NAME; + PyGILState_STATE gstate=PyGILState_Ensure(); + _context=PyDict_New(); + PyGILState_Release(gstate); } -void PythonNode::set_script(const string& script) +PythonNode::PythonNode(const std::string& name):InlineNode(name) +{ + _implementation=IMPL_NAME; + PyGILState_STATE gstate = PyGILState_Ensure(); + _context=PyDict_New(); + PyGILState_Release(gstate); +} + +PythonNode::~PythonNode() +{ + PyGILState_STATE gstate = PyGILState_Ensure(); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + Py_DECREF(_context); + PyGILState_Release(gstate); +} + +void PythonNode::load() { - _script = script; } void PythonNode::execute() { - cerr << "PyNode::run" << endl; - PyObject* context=PyDict_New(); - if( PyDict_SetItemString( context, "__builtins__", getSALOMERuntime()->getBuiltins() )) + DEBTRACE( "++++++++++++++ PyNode::execute: " << getName() << " ++++++++++++++++++++" ); + PyGILState_STATE gstate = PyGILState_Ensure(); + if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) { stringstream msg; msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__; + PyGILState_Release(gstate); throw Exception(msg.str()); } - cerr << "---------------PyNode::inputs---------------" << endl; - set::iterator iter2; + DEBTRACE( "---------------PyNode::inputs---------------" ); + list::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; + DEBTRACE( "port name: " << p->getName() ); + DEBTRACE( "port kind: " << p->edGetType()->kind() ); PyObject* ob=p->getPyObj(); - cerr << "ob refcnt: " << ob->ob_refcnt << endl; - PyObject_Print(ob,stdout,Py_PRINT_RAW); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); +#ifdef _DEVDEBUG_ + PyObject_Print(ob,stderr,Py_PRINT_RAW); cerr << endl; - int ier=PyDict_SetItemString(context,p->getName().c_str(),ob); - cerr << "ob refcnt: " << ob->ob_refcnt << endl; +#endif + int ier=PyDict_SetItemString(_context,p->getName().c_str(),ob); + DEBTRACE( "after PyDict_SetItemString:ob refcnt: " << ob->ob_refcnt ); } - cerr << "---------------End PyNode::inputs---------------" << endl; + DEBTRACE( "---------------End PyNode::inputs---------------" ); //calculation - cerr << "PyNode::calculation " << _script << endl; - PyObject *res=PyRun_String(_script.c_str(),Py_file_input,context,context); + DEBTRACE( "----------------PyNode::calculation---------------" ); + DEBTRACE( _script ); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + PyObject *res=PyRun_String(_script.c_str(),Py_file_input,_context,_context); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); if(res == NULL) { PyErr_Print(); - return; + PyGILState_Release(gstate); + throw Exception("Error during execution"); } Py_DECREF(res); - cerr << "-----------------PyNode::outputs-----------------" << endl; - set::iterator iter; + DEBTRACE( "-----------------PyNode::outputs-----------------" ); + list::iterator iter; + try + { + for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++) + { + OutputPyPort *p=(OutputPyPort *)*iter; + DEBTRACE( "port name: " << p->getName() ); + DEBTRACE( "port kind: " << p->edGetType()->kind() ); + PyObject *ob=PyDict_GetItemString(_context,p->getName().c_str()); + if(ob==NULL){ + PyGILState_Release(gstate); + std::string msg="Error during execution: there is no variable "; + msg=msg+p->getName()+" in node context"; + throw Exception(msg); + } + DEBTRACE( "PyNode::outputs::ob refcnt: " << ob->ob_refcnt ); +#ifdef _DEVDEBUG_ + PyObject_Print(ob,stderr,Py_PRINT_RAW); + cerr << endl; +#endif + p->put(ob); + } + } + catch(ConversionException) + { + PyGILState_Release(gstate); + throw; + } + + DEBTRACE( "-----------------End PyNode::outputs-----------------" ); + PyGILState_Release(gstate); + DEBTRACE( "++++++++++++++ End PyNode::execute: " << getName() << " ++++++++++++++++++++" ); +} + +Node *PythonNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new PythonNode(*this,father); +} + +//! Create a new node of same type with a given name +PythonNode* PythonNode::cloneNode(const std::string& name) +{ + PythonNode* n=new PythonNode(name); + n->setScript(_script); + list::iterator iter; + for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++) + { + InputPyPort *p=(InputPyPort *)*iter; + DEBTRACE( "port name: " << p->getName() ); + DEBTRACE( "port kind: " << p->edGetType()->kind() ); + n->edAddInputPort(p->getName(),p->edGetType()); + } + list::iterator iter2; + for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++) + { + OutputPyPort *p=(OutputPyPort *)*iter2; + DEBTRACE( "port name: " << p->getName() ); + DEBTRACE( "port kind: " << p->edGetType()->kind() ); + n->edAddOutputPort(p->getName(),p->edGetType()); + } + return n; +} + +PyFuncNode::PyFuncNode(const PyFuncNode& other, ComposedNode *father):InlineFuncNode(other,father),_pyfunc(0) +{ + _implementation = PythonNode::IMPL_NAME; + PyGILState_STATE gstate = PyGILState_Ensure(); + _context=PyDict_New(); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) + { + stringstream msg; + msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__; + PyGILState_Release(gstate); + throw Exception(msg.str()); + } + PyGILState_Release(gstate); +} + +PyFuncNode::PyFuncNode(const std::string& name): InlineFuncNode(name),_pyfunc(0) +{ + + _implementation = PythonNode::IMPL_NAME; + DEBTRACE( "PyFuncNode::PyFuncNode " << name ); + PyGILState_STATE gstate = PyGILState_Ensure(); + _context=PyDict_New(); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) + { + stringstream msg; + msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__; + PyGILState_Release(gstate); + throw Exception(msg.str()); + } + PyGILState_Release(gstate); +} + +PyFuncNode::~PyFuncNode() +{ + DEBTRACE( getName() ); + PyGILState_STATE gstate = PyGILState_Ensure(); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + if(_pyfunc)DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt ); + Py_DECREF(_context); + PyGILState_Release(gstate); +} + +void PyFuncNode::load() +{ + DEBTRACE( "---------------PyFuncNode::load function " << getName() << " ---------------" ); + DEBTRACE( _script ); +#ifdef _DEVDEBUG_ + list::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); + DEBTRACE( "port name: " << p->getName() ); + DEBTRACE( "port kind: " << p->edGetType()->kind() ); + } +#endif + PyGILState_STATE gstate = PyGILState_Ensure(); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + PyObject *res=PyRun_String(_script.c_str(),Py_file_input,_context,_context); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + if(res == NULL) + { + PyErr_Print(); + PyGILState_Release(gstate); + throw Exception("Error during execution"); + return; + } + Py_DECREF(res); + _pyfunc=PyDict_GetItemString(_context,_fname.c_str()); + DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt ); + if(_pyfunc == NULL) + { + PyErr_Print(); + PyGILState_Release(gstate); + throw Exception("Error during execution"); + } + DEBTRACE( "---------------End PyFuncNode::load function---------------" ); + PyGILState_Release(gstate); +} + +void PyFuncNode::execute() +{ + DEBTRACE( "++++++++++++++ PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" ); + int pos=0; + PyObject* ob; + if(!_pyfunc)throw Exception("PyFuncNode badly loaded"); + PyGILState_STATE gstate = PyGILState_Ensure(); + + DEBTRACE( "---------------PyFuncNode::inputs---------------" ); + PyObject* args = PyTuple_New(getNumberOfInputPorts()) ; + list::iterator iter2; + for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++) + { + InputPyPort *p=(InputPyPort *)*iter2; + DEBTRACE( "port name: " << p->getName() ); + DEBTRACE( "port kind: " << p->edGetType()->kind() ); + ob=p->getPyObj(); +#ifdef _DEVDEBUG_ + PyObject_Print(ob,stderr,Py_PRINT_RAW); cerr << endl; - //Faut-il incrémenter ici ? +#endif + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); Py_INCREF(ob); - cerr << "ob refcnt: " << ob->ob_refcnt << endl; - p->put(ob); + PyTuple_SetItem(args,pos,ob); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); + pos++; } + DEBTRACE( "---------------End PyFuncNode::inputs---------------" ); - cerr << "-----------------End PyNode::outputs-----------------" << endl; - Py_DECREF(context); + DEBTRACE( "----------------PyFuncNode::calculation---------------" ); +#ifdef _DEVDEBUG_ + PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW); + cerr << endl; + PyObject_Print(args,stderr,Py_PRINT_RAW); + cerr << endl; +#endif + DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt ); + PyObject* result = PyObject_CallObject( _pyfunc , args ) ; + DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt ); + Py_DECREF(args); + if(result == NULL) + { + PyErr_Print(); + PyGILState_Release(gstate); + throw Exception("Error during execution"); + } + DEBTRACE( "----------------End PyFuncNode::calculation---------------" ); + + DEBTRACE( "-----------------PyFuncNode::outputs-----------------" ); + int nres=1; + if(result == Py_None) + nres=0; + else if(PyTuple_Check(result)) + nres=PyTuple_Size(result); + + if(getNumberOfOutputPorts() != nres) + { + Py_DECREF(result); + PyGILState_Release(gstate); + throw Exception("Number of output arguments : Mismatch between definition and execution"); + } + + pos=0; +#ifdef _DEVDEBUG_ + PyObject_Print(result,stderr,Py_PRINT_RAW); + cerr << endl; +#endif + list::iterator iter; + try + { + for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++) + { + OutputPyPort *p=(OutputPyPort *)*iter; + DEBTRACE( "port name: " << p->getName() ); + DEBTRACE( "port kind: " << p->edGetType()->kind() ); + DEBTRACE( "port pos : " << pos ); + if(PyTuple_Check(result))ob=PyTuple_GetItem(result,pos) ; + else ob=result; + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); +#ifdef _DEVDEBUG_ + PyObject_Print(ob,stderr,Py_PRINT_RAW); + cerr << endl; +#endif + p->put(ob); + pos++; + } + } + catch(ConversionException) + { + Py_DECREF(result); + PyGILState_Release(gstate); + throw; + } + DEBTRACE( "-----------------End PyFuncNode::outputs-----------------" ); + + Py_DECREF(result); + PyGILState_Release(gstate); + DEBTRACE( "++++++++++++++ End PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" ); +} + +Node *PyFuncNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new PyFuncNode(*this,father); +} + +//! Create a new node of same type with a given name +PyFuncNode* PyFuncNode::cloneNode(const std::string& name) +{ + PyFuncNode* n=new PyFuncNode(name); + n->setScript(_script); + n->setFname(_fname); + list::iterator iter; + for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++) + { + InputPyPort *p=(InputPyPort *)*iter; + n->edAddInputPort(p->getName(),p->edGetType()); + } + list::iterator iter2; + for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++) + { + OutputPyPort *p=(OutputPyPort *)*iter2; + n->edAddOutputPort(p->getName(),p->edGetType()); + } + return n; } diff --git a/src/runtime/PythonNode.hxx b/src/runtime/PythonNode.hxx index a972f3933..db28bed06 100644 --- a/src/runtime/PythonNode.hxx +++ b/src/runtime/PythonNode.hxx @@ -2,22 +2,44 @@ #ifndef _PYTHONNODE_HXX_ #define _PYTHONNODE_HXX_ -#include "ElementaryNode.hxx" +#include "InlineNode.hxx" +#include namespace YACS { namespace ENGINE { - - class PythonNode: public ElementaryNode + class PythonNode : public InlineNode { + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; public: + PythonNode(const PythonNode& other, ComposedNode *father); PythonNode(const std::string& name); + virtual ~PythonNode(); virtual void execute(); - virtual void set_script(const std::string& script); + virtual void load(); + PythonNode* cloneNode(const std::string& name); + static const char KIND[]; + static const char IMPL_NAME[]; + protected: + PyObject* _context; + }; + class PyFuncNode : public InlineFuncNode + { + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + public: + PyFuncNode(const PyFuncNode& other, ComposedNode *father); + PyFuncNode(const std::string& name); + virtual ~PyFuncNode(); + virtual void execute(); + virtual void load(); + PyFuncNode* cloneNode(const std::string& name); protected: - std::string _script; + PyObject* _context; + PyObject* _pyfunc; }; } } diff --git a/src/runtime/PythonPorts.cxx b/src/runtime/PythonPorts.cxx index cc2ebbeba..e1c97bbc5 100644 --- a/src/runtime/PythonPorts.cxx +++ b/src/runtime/PythonPorts.cxx @@ -1,27 +1,70 @@ #include "PythonPorts.hxx" +#include "TypeConversions.hxx" +#include "Node.hxx" #include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" using namespace YACS::ENGINE; using namespace std; -InputPyPort::InputPyPort(const string& name, Node *node, TypeCode * type) - : InputPort(name, node, type), Port(node) +InputPyPort::InputPyPort(const std::string& name, Node *node, TypeCode * type) + : InputPort(name, node, type), DataPort(name, node, type), Port(node), _data(Py_None),_initData(Py_None) +{ + Py_INCREF(_data); + Py_INCREF(_initData); +} +InputPyPort::~InputPyPort() +{ + PyGILState_STATE gstate = PyGILState_Ensure(); + DEBTRACE( "_data refcnt: " << _data->ob_refcnt ); + DEBTRACE( "_initData refcnt: " << _initData->ob_refcnt ); + Py_XDECREF(_data); + Py_XDECREF(_initData); + PyGILState_Release(gstate); +} + +InputPyPort::InputPyPort(const InputPyPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder) { - _impl = "Python"; + _initData=other._initData; + Py_INCREF(_initData); + _data=other._data; + Py_INCREF(_data); +} + +bool InputPyPort::edIsManuallyInitialized() const +{ + return _initData!=Py_None; +} + +void InputPyPort::edRemoveManInit() +{ + Py_XDECREF(_initData); + _initData=Py_None; + Py_INCREF(_initData); + InputPort::edRemoveManInit(); } void InputPyPort::put(const void *data) throw(ConversionException) { put((PyObject *)data); - _empty = false; } void InputPyPort::put(PyObject *data) throw(ConversionException) { - cerr << "InputPyPort::put" << endl; + Py_XDECREF(_data); _data = data; + Py_INCREF(_data); + DEBTRACE( "_data refcnt: " << _data->ob_refcnt ); +} + +InputPort *InputPyPort::clone(Node *newHelder) const +{ + return new InputPyPort(*this,newHelder); } PyObject * InputPyPort::getPyObj() const @@ -29,12 +72,81 @@ PyObject * InputPyPort::getPyObj() const return _data; } +void *InputPyPort::get() const throw(Exception) +{ + return (void*) _data; +} +bool InputPyPort::isEmpty() +{ + return _data == Py_None; +} -OutputPyPort::OutputPyPort(const string& name, Node *node, TypeCode * type) - : OutputPort(name, node, type), Port(node) +//! Save the current data value for further reinitialization of the port +/*! + * + */ +void InputPyPort::exSaveInit() +{ + Py_XDECREF(_initData); + _initData=_data; + Py_INCREF(_initData); + DEBTRACE( "_initData.ob refcnt: " << _initData->ob_refcnt ); + DEBTRACE( "_data.ob refcnt: " << _data->ob_refcnt ); +} + +//! Restore the saved data value to current data value +/*! + * If no data has been saved (_initData == 0) don't restore + */ +void InputPyPort::exRestoreInit() +{ + if(!_initData)return; + Py_XDECREF(_data); + _data=_initData; + Py_INCREF(_data); + DEBTRACE( "_initData.ob refcnt: " << _initData->ob_refcnt ); + DEBTRACE( "_data.ob refcnt: " << _data->ob_refcnt ); +} + +std::string InputPyPort::dump() +{ + if( _data == Py_None) + return "None"; + + InterpreterUnlocker l; + if (edGetType()->kind() != YACS::ENGINE::Objref) + return convertPyObjectXml(edGetType(), _data); + if (! _stringRef.empty()) + return _stringRef; + else + return convertPyObjectXml(edGetType(), _data); +// { +// stringstream msg; +// msg << "Cannot retreive init reference string for port " << _name +// << " on node " << _node->getName(); +// throw Exception(msg.str()); +// } +} + + +OutputPyPort::OutputPyPort(const std::string& name, Node *node, TypeCode * type) + : OutputPort(name, node, type), DataPort(name, node, type), Port(node) +{ + _data = Py_None; + Py_INCREF(_data); +} +OutputPyPort::~OutputPyPort() +{ + PyGILState_STATE gstate = PyGILState_Ensure(); + DEBTRACE( "_data refcnt: " << _data->ob_refcnt ); + Py_XDECREF(_data); + PyGILState_Release(gstate); +} + +OutputPyPort::OutputPyPort(const OutputPyPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder), + _data(Py_None) { - _impl = "Python"; } void OutputPyPort::put(const void *data) throw(ConversionException) @@ -44,22 +156,35 @@ void OutputPyPort::put(const void *data) throw(ConversionException) 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); + DEBTRACE( "OutputPyPort::put.ob refcnt: " << data->ob_refcnt ); +#ifdef _DEVDEBUG_ + PyObject_Print(data,stderr,Py_PRINT_RAW); cerr << endl; +#endif + Py_XDECREF(_data); _data = data; - set::iterator iter; - for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++) - { - p = *iter; - p->put(data); - } + Py_INCREF(_data); + DEBTRACE( "OutputPyPort::put.ob refcnt: " << data->ob_refcnt ); + OutputPort::put(data); +} + +OutputPort *OutputPyPort::clone(Node *newHelder) const +{ + return new OutputPyPort(*this,newHelder); } -PyObject * OutputPyPort:: get() const +PyObject * OutputPyPort::get() const { return _data; } +std::string OutputPyPort::dump() +{ + if( _data == Py_None) + return "None"; + InterpreterUnlocker l; + string xmldump = convertPyObjectXml(edGetType(), _data); + return xmldump; +} + diff --git a/src/runtime/PythonPorts.hxx b/src/runtime/PythonPorts.hxx index 4aa08499a..71982a497 100644 --- a/src/runtime/PythonPorts.hxx +++ b/src/runtime/PythonPorts.hxx @@ -11,25 +11,58 @@ namespace YACS { namespace ENGINE { + class InterpreterUnlocker + { + public: + InterpreterUnlocker() { + gstate_ = PyGILState_Ensure(); + } + ~InterpreterUnlocker() { + PyGILState_Release(gstate_); + } + private: + PyGILState_STATE gstate_; + }; +/*! \brief Class for Python Ports + * + * \ingroup Ports + * + * \see PythonNode + */ class InputPyPort : public InputPort { public: InputPyPort(const std::string& name, Node * node, TypeCode * type); + InputPyPort(const InputPyPort& other, Node *newHelder); + ~InputPyPort(); + bool edIsManuallyInitialized() const; + void edRemoveManInit(); virtual void put(const void *data) throw(ConversionException); void put(PyObject *data) throw(ConversionException); + InputPort *clone(Node *newHelder) const; virtual PyObject * getPyObj() const; + void *get() const throw(Exception); + virtual bool isEmpty(); + virtual void exSaveInit(); + virtual void exRestoreInit(); + virtual std::string dump(); protected: PyObject* _data; + PyObject* _initData; }; class OutputPyPort : public OutputPort { public: OutputPyPort(const std::string& name, Node * node, TypeCode * type); + OutputPyPort(const OutputPyPort& other, Node *newHelder); + ~OutputPyPort(); virtual void put(const void *data) throw(ConversionException); void put(PyObject *data) throw(ConversionException); + OutputPort *clone(Node *newHelder) const; virtual PyObject * get() const; + virtual std::string dump(); protected: PyObject* _data; }; diff --git a/src/runtime/PythonXMLConv.cxx b/src/runtime/PythonXMLConv.cxx new file mode 100644 index 000000000..5d658cd89 --- /dev/null +++ b/src/runtime/PythonXMLConv.cxx @@ -0,0 +1,37 @@ +#include "TypeConversions.hxx" +#include "PythonXMLConv.hxx" +#include "Node.hxx" + +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +PyXml::PyXml(InputXmlPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{ +} + +//!Convert a PyObject that is convertible to Xml::char * and send it to proxy port +/*! + * \param data : PyObject object as a void * pointer + */ + +void PyXml::put(const void *data) throw(ConversionException) +{ + put((PyObject *)data); +} + +//!Convert a PyObject that is convertible to Xml::char * and send it to proxy port +/*! + * \param data : PyObject object + */ +void PyXml::put(PyObject *data) throw(ConversionException) +{ + DEBTRACE("PyXml::put" ); + std::string sss = convertPyObjectXml(edGetType(),data); + ((InputXmlPort*)_port)->put((const char*)sss.c_str()); +} diff --git a/src/runtime/PythonXMLConv.hxx b/src/runtime/PythonXMLConv.hxx new file mode 100644 index 000000000..d6d0158d8 --- /dev/null +++ b/src/runtime/PythonXMLConv.hxx @@ -0,0 +1,22 @@ +#ifndef __PYTHONXMLCONV_HXX__ +#define __PYTHONXMLCONV_HXX__ + +#include +#include "XMLPorts.hxx" + +namespace YACS +{ + namespace ENGINE + { + // Adaptator Ports Python->Xml for several types + + class PyXml : public ProxyPort + { + public: + PyXml(InputXmlPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(PyObject *data) throw(ConversionException); + }; + } +} +#endif diff --git a/src/runtime/RuntimeSALOME.cxx b/src/runtime/RuntimeSALOME.cxx index 2980487b2..b3755924d 100644 --- a/src/runtime/RuntimeSALOME.cxx +++ b/src/runtime/RuntimeSALOME.cxx @@ -1,28 +1,99 @@ +//#define REFCNT +#ifdef REFCNT +#define private public +#define protected public +#include +#include +#include +#endif +#include "yacsconfig.h" #include "RuntimeSALOME.hxx" +#include "SALOMEDispatcher.hxx" +#include "Proc.hxx" +#include "WhileLoop.hxx" +#include "ForLoop.hxx" +#include "Bloc.hxx" +#include "InputPort.hxx" +#include "OutputPort.hxx" +#include "InputDataStreamPort.hxx" +#include "OutputDataStreamPort.hxx" +#include "SalomeProc.hxx" +//Components +#include "CORBAComponent.hxx" +#include "SalomeComponent.hxx" +#include "SalomePythonComponent.hxx" +#include "CppComponent.hxx" + +#include "SalomeContainer.hxx" +#include "CppContainer.hxx" + +//Nodes #include "PythonNode.hxx" #include "CORBANode.hxx" #include "XMLNode.hxx" #include "CppNode.hxx" #include "TypeConversions.hxx" +#include "SalomePythonNode.hxx" +//CORBA proxy ports #include "CORBACORBAConv.hxx" -#include "PythonCORBAConv.hxx" #include "CORBAPythonConv.hxx" +#include "CORBAXMLConv.hxx" +#include "CORBACppConv.hxx" +#include "CORBANeutralConv.hxx" + +//Python proxy ports +#include "PythonCORBAConv.hxx" +#include "PythonXMLConv.hxx" +#include "PythonCppConv.hxx" +#include "PythonNeutralConv.hxx" + +//Neutral proxy ports +#include "NeutralCORBAConv.hxx" +#include "NeutralPythonConv.hxx" +#include "NeutralXMLConv.hxx" +#include "NeutralCppConv.hxx" + +//C++ proxy ports +#include "CppCORBAConv.hxx" +#include "CppPythonConv.hxx" +#include "CppXMLConv.hxx" +#include "CppCppConv.hxx" +#include "CppNeutralConv.hxx" + +//XML proxy ports #include "XMLCORBAConv.hxx" +#include "XMLPythonConv.hxx" +#include "XMLCppConv.hxx" +#include "XMLNeutralConv.hxx" + +//Calcium specific ports +#include "CalStreamPort.hxx" +#ifdef SALOME_KERNEL +#include "SALOME_NamingService.hxx" +#include "SALOME_LifeCycleCORBA.hxx" +#endif + +#include #include #include #include #include +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + using namespace std; using namespace YACS::ENGINE; - - -void RuntimeSALOME::setRuntime() // singleton creation (not thread safe!) +void RuntimeSALOME::setRuntime(long flags) // singleton creation (not thread safe!) { - if (! Runtime::_singleton) Runtime::_singleton = new RuntimeSALOME(); + if (! Runtime::_singleton) + { + Runtime::_singleton = new RuntimeSALOME(flags); + } + DEBTRACE("RuntimeSALOME::setRuntime() done !"); } RuntimeSALOME* YACS::ENGINE::getSALOMERuntime() @@ -37,118 +108,319 @@ RuntimeSALOME* YACS::ENGINE::getSALOMERuntime() RuntimeSALOME::RuntimeSALOME() { - _setOfImplementation.insert("Cpp"); - _setOfImplementation.insert("Python"); - _setOfImplementation.insert("CORBA"); - init(); + assert(0); +} + +RuntimeSALOME::RuntimeSALOME(long flags) +{ + // If all flags (apart the IsPyExt flags) are unset, force them to true + if ((flags - flags & RuntimeSALOME::IsPyExt) == 0) + flags += RuntimeSALOME::UseCorba + RuntimeSALOME::UsePython + + RuntimeSALOME::UseCpp + RuntimeSALOME::UseXml; + + // Salome Nodes implies Corba Nodes + if (flags & RuntimeSALOME::UseSalome) + flags |= RuntimeSALOME::UseCorba; + + // Corba Nodes implies Python Nodes + if (flags & RuntimeSALOME::UseCorba) + flags |= RuntimeSALOME::UsePython; + + _useCorba = flags & RuntimeSALOME::UseCorba; + _usePython = flags & RuntimeSALOME::UsePython; + _useCpp = flags & RuntimeSALOME::UseCpp; + _useXml = flags & RuntimeSALOME::UseXml; + + if (_useCpp) _setOfImplementation.insert(CppNode::IMPL_NAME); + if (_usePython) _setOfImplementation.insert(PythonNode::IMPL_NAME); + if (_useCorba) _setOfImplementation.insert(CORBANode::IMPL_NAME); + if (_useXml) _setOfImplementation.insert(XmlNode::IMPL_NAME); + init(flags); +} + +RuntimeSALOME::~RuntimeSALOME() +{ } +//! CORBA and Python initialization +/*! + * \param flags contains several bits + * bit0 (ispyext) true when method is called from Python + * (Python initialization must not be done!) + * bit1 (UsePython) true if python nodes are needed + * bit1 (UseCorba) true if CORBA nodes are needed + * bit1 (UseXml) true if python nodes are needed + * bit1 (UseCpp) true if C++ nodes are needed + * bit1 (UseSalome) true if Salome nodes are needed + * + */ -void RuntimeSALOME::init() +void RuntimeSALOME::init(long flags) { - 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); + bool ispyext = flags & RuntimeSALOME::IsPyExt; + if (_useCorba) + { + int nbargs = 0; char **args = 0; + _orb = CORBA::ORB_init (nbargs, args); +#ifdef REFCNT + DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount); +#endif + CORBA::Object_var obj = _orb->resolve_initial_references("DynAnyFactory"); + _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj); + } - PyObject *mainmod ; - cerr << "RuntimeSALOME::init" << endl; - Py_Initialize(); + if (_usePython) + { + DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext); - mainmod = PyImport_AddModule("__main__"); - PyObject *globals; - globals = PyModule_GetDict(mainmod); + // Initialize Python interpreter in embedded mode + if (!Py_IsInitialized()) + { + Py_InitializeEx(0); // do not install signal handlers + PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/ + PyEval_SaveThread(); /* Release the thread state */ + //here we do not have the Global Interpreter Lock + } - /* globals is a borrowed reference */ - Py_INCREF(globals); - /* globals is a new reference */ + PyObject *mainmod,*pyapi,*res ; + PyObject *globals; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock + + mainmod = PyImport_AddModule("__main__"); + globals = PyModule_GetDict(mainmod); + /* globals is a borrowed reference */ - _bltins = PyEval_GetBuiltins(); /* borrowed ref */ + if (PyDict_GetItemString(globals, "__builtins__") == NULL) + { + PyObject *bimod = PyImport_ImportModule("__builtin__"); + if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0) + Py_FatalError("can't add __builtins__ to __main__"); + Py_DECREF(bimod); + } + + _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 */ -} + if (_useCorba) + { + + //init section + PyObject* omnipy = PyImport_ImportModule((char*)"_omnipy"); + if (!omnipy) + { + PyErr_Print(); + PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy"); + goto out; + } + pyapi = PyObject_GetAttrString(omnipy, (char*)"API"); + if (!pyapi) + { + goto out; + } + _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi); + Py_DECREF(pyapi); + + res=PyRun_String("\n" + "import sys\n" + "sys.path.insert(0,'.')\n" + "from omniORB 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(); + goto out; + } + Py_DECREF(res); + + _pyorb = PyDict_GetItemString(globals,"orb"); + /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */ + PyObject *pyany; + pyany = PyDict_GetItemString(globals,"any"); + /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */ + +#ifdef REFCNT + DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount); +#endif + } + out: + PyGILState_Release(gstate); // Release the Global Interpreter Lock + } +} void RuntimeSALOME::fini() { - cerr << "RuntimeSALOME::fini" << endl; - Py_Finalize(); + if (_usePython) + { + PyGILState_STATE gstate = PyGILState_Ensure(); +#ifdef REFCNT + DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount); +#endif + PyObject *mainmod, *globals; + mainmod = PyImport_AddModule("__main__"); + globals = PyModule_GetDict(mainmod); + if (_useCorba) + { + PyObject* res; + res=PyRun_String("orb.destroy()\n" + "\n", + Py_file_input,globals,globals ); + if(res == NULL) + PyErr_Print(); + else + Py_DECREF(res); + } + Py_Finalize(); +#ifdef REFCNT + DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount); +#endif + } + else + { + if (_useCorba) + { +#ifdef REFCNT + DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount); +#endif + _orb->destroy(); + } + } } +Proc* RuntimeSALOME::createProc(const std::string& name) +{ + return new SalomeProc(name); +} + +Bloc* RuntimeSALOME::createBloc(const std::string& name) +{ + return new Bloc(name); +} + +WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name) +{ + return new WhileLoop(name); +} -ElementaryNode* RuntimeSALOME::createNode(string implementation, - string name) throw(Exception) +ForLoop* RuntimeSALOME::createForLoop(const std::string& name) { - 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 + return new ForLoop(name); +} + +InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name) +{ + InlineFuncNode* node; + if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND) { - string what ="RuntimeSALOME does not handle this implementation: " + implementation; - throw Exception(what); + node = new PyFuncNode(name); + return node; } - return node; + std::string msg="FuncNode kind ("+kind+") unknown"; + throw Exception(msg); } -InputPort * RuntimeSALOME::createInputPort(const string& name, - const string& impl, - Node * node, - TypeCode * type) +InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name) { - if(impl == "CPP") + InlineNode* node; + if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND) { - throw Exception("Cannot create InputCppPort "); + node = new PythonNode(name); + return node; } - else if(impl == "Python") + std::string msg="ScriptNode kind ("+kind+") unknown"; + throw Exception(msg); +} + +ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name) +{ + ServiceNode* node; + if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND) + { + node = new CORBANode(name); + return node; + } + else if(kind == XmlNode::KIND) + { + node = new XmlNode(name); + return node; + } + std::string msg="RefNode kind ("+kind+") unknown"; + throw Exception(msg); +} + +ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name) +{ + ServiceNode* node; + if(kind == "" || kind == SalomeNode::KIND ) + { + node=new SalomeNode(name); + return node; + } + else if (kind == CppNode::KIND) + { + node = new CppNode(name); + return node; + } + std::string msg="CompoNode kind ("+kind+") unknown"; + throw Exception(msg); +} + +ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name) +{ + if(kind == "" || kind == SalomeNode::KIND ) + return new SalomePythonNode(name); + std::string msg="CompoNode kind ("+kind+") unknown"; + throw Exception(msg); +} + +ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name, + const std::string& kind) +{ + ComponentInstance* compo; + if(kind == "" || kind == SalomeComponent::KIND) + return new SalomeComponent(name); + else if(kind == CORBAComponent::KIND) + return new CORBAComponent(name); + else if(kind == SalomePythonComponent::KIND) + return new SalomePythonComponent(name); + else if (kind == CppComponent::KIND) + return new CppComponent(name); + std::string msg="Component Instance kind ("+kind+") unknown"; + throw Exception(msg); +} + +Container *RuntimeSALOME::createContainer(const std::string& kind) +{ + if(kind == "" || kind == SalomeComponent::KIND) + return new SalomeContainer; + else if (kind == CppComponent::KIND) + return new CppContainer; + std::string msg="Container kind ("+kind+") unknown"; + throw Exception(msg); +} + +InputPort * RuntimeSALOME::createInputPort(const std::string& name, + const std::string& impl, + Node * node, + TypeCode * type) +{ + if(impl == CppNode::IMPL_NAME) + { + return new InputCppPort(name, node, type); + } + else if(impl == PythonNode::IMPL_NAME) { return new InputPyPort(name, node, type); } - else if(impl == "CORBA") + else if(impl == CORBANode::IMPL_NAME) { return new InputCorbaPort(name, node, type); } - else if(impl == "XML") + else if(impl == XmlNode::IMPL_NAME) { return new InputXmlPort(name, node, type); } @@ -161,24 +433,24 @@ InputPort * RuntimeSALOME::createInputPort(const string& name, } } -OutputPort * RuntimeSALOME::createOutputPort(const string& name, - const string& impl, - Node * node, - TypeCode * type) +OutputPort * RuntimeSALOME::createOutputPort(const std::string& name, + const std::string& impl, + Node * node, + TypeCode * type) { - if(impl == "CPP") + if(impl == CppNode::IMPL_NAME) { - throw Exception("Cannot create OutputCppPort "); + return new OutputCppPort(name, node, type); } - else if(impl == "Python") + else if(impl == PythonNode::IMPL_NAME) { return new OutputPyPort(name, node, type); } - else if(impl == "CORBA") + else if(impl == CORBANode::IMPL_NAME) { return new OutputCorbaPort(name, node, type); } - else if(impl == "XML") + else if(impl == XmlNode::IMPL_NAME) { return new OutputXmlPort(name, node, type); } @@ -191,24 +463,67 @@ OutputPort * RuntimeSALOME::createOutputPort(const string& name, } } -InputPort* RuntimeSALOME::adapt(const string& imp_source, - InputPort* source, - const string& impl, - TypeCode * type) throw (ConversionException) +InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name, + Node *node,TypeCode *type) +{ + DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName()); + if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM") + { + return new InputCalStreamPort(name,node,type); + } + else + { + return new InputDataStreamPort(name,node,type); + } +} + +OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name, + Node *node,TypeCode *type) { - cerr<<"RuntimeSALOME::adapt(InputPort* source" << endl; - if(imp_source == "Python") + DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName()); + if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM") + { + return new OutputCalStreamPort(name,node,type); + } + else + { + return new OutputDataStreamPort(name,node,type); + } +} + +//! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation +/*! + * \param source : InputPort to be adapted + * \param impl : new implementation (C++, python, CORBA, XML, Neutral) + * \param type : data type provided by the InputPort + * + * \return : adapted InputPort + */ +InputPort* RuntimeSALOME::adapt(InputPort* source, + const std::string& impl, + TypeCode * type) throw (ConversionException) +{ + string imp_source=source->getNode()->getImplementation(); + if(imp_source == PythonNode::IMPL_NAME) { return adapt((InputPyPort*)source,impl,type); } - else if(imp_source == "CORBA") + else if(imp_source == CppNode::IMPL_NAME) + { + return adapt((InputCppPort*)source,impl,type); + } + else if(imp_source == CORBANode::IMPL_NAME) { return adapt((InputCorbaPort*)source,impl,type); } - else if(imp_source == "XML") + else if(imp_source == XmlNode::IMPL_NAME) { return adapt((InputXmlPort*)source,impl,type); } + else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME) + { + return adaptNeutral(source,impl,type); + } else { stringstream msg; @@ -218,348 +533,895 @@ InputPort* RuntimeSALOME::adapt(const string& imp_source, } } -//! Retourne un adaptateur d'un port entrant Xml pour un port sortant dont l'implémentation est donnée par impl +//! Adapt a Neutral input port to a Corba output port /*! - * \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 + * \param inport : Neutral input port to adapt to Corba type type + * \param type : output port type + * \return an adaptated input port of type InputCorbaPort */ +InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport, + TypeCode * type) throw (ConversionException) +{ + // BEWARE : using the generic check + if(inport->edGetType()->isAdaptable(type)) + { + //the output data is convertible to inport type + return new CorbaNeutral(inport); + } + //non convertible type + stringstream msg; + msg << "Cannot connect Neutral InputPort to OutputCorbaPort : " ; + msg << "(" <<__FILE__ << ":" <<__LINE__<< ")"; + throw ConversionException(msg.str()); +} -InputPort* RuntimeSALOME::adapt(InputXmlPort* source, - const string& impl, - TypeCode * type) throw (ConversionException) +//! Adapt a Neutral input port to a Python output port +/*! + * \param inport : input port to adapt to Python type type + * \param type : output port type + * \return an adaptated input port of type InputPyPort + */ +InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport, + TypeCode * type) throw (ConversionException) { - cerr<<"RuntimeSALOME::adapt(InputXmlPort* source" << endl; - if(impl == "CORBA") + // BEWARE : using the generic check + if(inport->edGetType()->isAdaptable(type)) { - return adaptXmlToCorba(source,type); + //convertible type + return new PyNeutral(inport); } - else + //non convertible type + stringstream msg; + msg << "Cannot connect Neutral InputPort to OutputPyPort : " ; + msg << "(" <<__FILE__ << ":" <<__LINE__<< ")"; + throw ConversionException(msg.str()); +} + +//! Adapt a Neutral input port to a Xml output port +/*! + * \param inport : input port to adapt to Xml type type + * \param type : output port type + * \return an input port of type InputXmlPort + */ +InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport, + TypeCode * type) throw (ConversionException) +{ + // BEWARE : using the generic check + if(inport->edGetType()->isAdaptable(type)) { - stringstream msg; - msg << "Cannot connect InputXmlPort to " << impl << " implementation"; - msg << " ("__FILE__ << ":" << __LINE__ << ")"; - throw ConversionException(msg.str()); + //convertible type + return new XmlNeutral(inport); + } + //non convertible type + stringstream msg; + msg << "Cannot connect Neutral InputPort to OutputXmlPort : " ; + msg << "(" <<__FILE__ << ":" <<__LINE__<< ")"; + throw ConversionException(msg.str()); +} + +//! Adapt a Neutral input port to a C++ output port +/*! + * \param inport : input port to adapt to C++ type type + * \param type : output port type + * \return an input port of type InputCppPort + */ +InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport, + TypeCode * type) throw (ConversionException) +{ + DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" ); + if(isAdaptableNeutralCpp(type,inport->edGetType())) + { + //convertible type + return new CppNeutral(inport); + } + //non convertible type + stringstream msg; + msg << "Cannot connect Neutral " << inport->edGetType()->getKindRepr() + << " InputPort to " << type->getKindRepr() << " OutputCppPort : " ; + msg << "(" <<__FILE__ << ":" <<__LINE__<< ")"; + throw ConversionException(msg.str()); +} + +//! Adapt a Neutral input port to connect it to an output port with a given implementation +/*! + * \param source : Neutral input port to adapt to implementation impl and type type + * \param impl : output port implementation (C++, Python, Corba, Xml or Neutral) + * \param type : output port supported type + * \return the adaptated port + */ +InputPort* RuntimeSALOME::adaptNeutral(InputPort* source, + const std::string& impl, + TypeCode * type) throw (ConversionException) +{ + if(impl == CppNode::IMPL_NAME) + { + return adaptNeutralToCpp(source,type); + } + else if(impl == PythonNode::IMPL_NAME) + { + return adaptNeutralToPython(source,type); + } + else if(impl == CORBANode::IMPL_NAME) + { + return adaptNeutralToCorba(source,type); + } + else if(impl == XmlNode::IMPL_NAME) + { + return adaptNeutralToXml(source,type); } + else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME) + { + return new ProxyPort(source); + } + stringstream msg; + msg << "Cannot connect InputPort : unknown implementation " << impl; + msg << " (" <<__FILE__ << ":" <<__LINE__ << ")"; + throw ConversionException(msg.str()); } -//! Retourne un adaptateur d'un port entrant XML pour un port sortant CORBA +//! Adapt a XML input port to connect it to a CORBA output port /*! * \param inport : input port to adapt to CORBA type type - * \param type : le type supporté par le port sortant - * \return a InputCorbaPort port + * \param type : type supported by output port + * \return an adaptator port of type InputCorbaPort */ InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport, - TypeCode * type) throw (ConversionException) + TypeCode * type) throw (ConversionException) { - cerr <<"RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport" << endl; - if(isAdaptableXmlCorba(type,inport->type())) + if(isAdaptableXmlCorba(type,inport->edGetType())) { - //les types sont convertibles + //output type is convertible to input type return new CorbaXml(inport); } - //les types sont non convertibles + //output type is not convertible stringstream msg; msg << "Cannot connect InputXmlPort to Corba output port " ; - msg << type->id() << " != " << inport->type()->id(); + msg << type->id() << " != " << inport->edGetType()->id(); msg << " ("__FILE__ << ":" << __LINE__ << ")"; throw ConversionException(msg.str()); } -//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant Xml +//! Adapt a XML input port to a Python output port /*! - * \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 + * \param inport : input port to adapt to Python type type + * \param type : output port type + * \return an adaptated input port of type InputPyPort */ +InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport, + TypeCode * type) throw (ConversionException) +{ + if(inport->edGetType()->isAdaptable(type)) + { + //the output data is convertible to inport type + return new PyXml(inport); + } + //non convertible type + stringstream msg; + msg << "Cannot connect Xml InputPort to OutputPyPort : " ; + msg << "(" <<__FILE__ << ":" <<__LINE__<< ")"; + throw ConversionException(msg.str()); +} -InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport, - TypeCode * type) throw (ConversionException) +//! Adapt a XML input port to a C++ output port +/*! + * \param inport : input port to adapt to C++ type type + * \param type : output port type + * \return an adaptated input port of type InputPyPort + */ +InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport, + TypeCode * type) throw (ConversionException) { - //ATTENTION : on utilise isAdaptableCorbaPyObject (meme fonction) - cerr << "RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport" << endl; - if(isAdaptableCorbaPyObject(type,inport->type())) + DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" ); + DEBTRACE(type->kind() << " " << inport->edGetType()->kind() ); + if(type->isAdaptable(inport->edGetType())) { - //les types sont convertibles - return new XmlCorba(inport); + //the output data is convertible to inport type + return new CppXml(inport); } - //les types sont non convertibles + //non convertible type stringstream msg; - msg << "Cannot connect InputCorbaPort with OutputXmlPort : " ; - msg << __FILE__ << ":" <<__LINE__; + msg << "Cannot connect Xml InputPort to OutputCppPort : " ; + msg << "(" <<__FILE__ << ":" <<__LINE__<< ")"; throw ConversionException(msg.str()); } +//! Adapt a XML input port to a Neutral output port +/*! + * \param inport : input port to adapt to Neutral type type + * \param type : output port type + * \return an adaptated input port of type Neutralxxxx + */ +InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport, + TypeCode * type) throw (ConversionException) +{ + if(inport->edGetType()->isAdaptable(type)) + { + //the output data is convertible to inport type + return new NeutralXml(inport); + } + //non convertible type + stringstream msg; + msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ; + msg << "(" <<__FILE__ << ":" <<__LINE__<< ")"; + throw ConversionException(msg.str()); +} -//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant CORBA +//! Adapt an Xml input port to an output port which implementation is given by impl /*! - * \param inport : input port to adapt to CORBA type type - * \param type : le type supporté par le port sortant + * \param source : input port to adapt to implementation impl and type type + * \param impl : output port implementation (C++, Python or Corba) + * \param type : output port supported type + * \return the adaptated port */ +InputPort* RuntimeSALOME::adapt(InputXmlPort* source, + const std::string& impl, + TypeCode * type) throw (ConversionException) +{ + if(impl == CORBANode::IMPL_NAME) + { + return adaptXmlToCorba(source,type); + } + else if(impl == PythonNode::IMPL_NAME) + { + return adaptXmlToPython(source,type); + } + else if(impl == CppNode::IMPL_NAME) + { + return adaptXmlToCpp(source,type); + } + else if(impl == XmlNode::IMPL_NAME) + { + return new ProxyPort(source); + } + else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME) + { + return adaptXmlToNeutral(source,type); + } + else + { + stringstream msg; + msg << "Cannot connect InputXmlPort to " << impl << " implementation"; + msg << " ("__FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } +} + + +//! Adapt a CORBA input port to a CORBA output port +/*! + * \param inport : input port to adapt to CORBA outport data type + * \param type : outport data type + * \return an adaptator port of type InputCORBAPort + */ InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport, - TypeCode * type) throw (ConversionException) + TypeCode * type) throw (ConversionException) { - if(type->is_a(inport->type())) + if(type->isA(inport->edGetType())) { - //les types sont compatibles : pas de conversion - return inport; + //types are compatible : no conversion + //outport data type is more specific than inport required type + //so the inport can be used safely + return new ProxyPort(inport); } - else if(isAdaptableCorbaCorba(type,inport->type())) + else if(isAdaptableCorbaCorba(type,inport->edGetType())) { - //les types sont convertibles + //ouport data can be converted to inport data type return new CorbaCorba(inport); } - //les types sont non convertibles + //outport data can not be converted stringstream msg; msg << "Cannot connect 2 CorbaPort with non convertible types: " ; - msg << type->id() << " != " << inport->type()->id(); + msg << type->id() << " != " << inport->edGetType()->id(); throw ConversionException(msg.str()); } -//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant Python +//! Adapt a CORBA input port to a Python output port /*! * \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 + * \param type : outport data type + * \return an adaptator port of type InputPyPort */ InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport, - TypeCode * type) throw (ConversionException) + TypeCode * type) throw (ConversionException) { - if(inport->type()->kind() == Double) + if(inport->edGetType()->kind() == Double) { - if(isAdaptableCorbaPyObject(type,inport->type()))return new PyCorbaDouble(inport); + if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport); } - else if(inport->type()->kind() == Int) + else if(inport->edGetType()->kind() == Int) { - if(isAdaptableCorbaPyObject(type,inport->type()))return new PyCorbaInt(inport); + if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport); } - else if(inport->type()->kind() == String) + else if(inport->edGetType()->kind() == String) { - if(isAdaptableCorbaPyObject(type,inport->type()))return new PyCorbaString(inport); + if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport); + } + else if(inport->edGetType()->kind() == Bool) + { + if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport); + } + else if(inport->edGetType()->kind() == Objref ) + { + if(isAdaptableCorbaPyObject(type,inport->edGetType())) + { + return new PyCorbaObjref(inport); + } + else + { + stringstream msg; + msg << "Cannot connect InputPyPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id(); + msg << " " << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); + } } - else if(inport->type()->kind() == Objref ) + else if(inport->edGetType()->kind() == Sequence) { - if(isAdaptableCorbaPyObject(type,inport->type())) - { - return new PyCorbaObjref(inport); + if(isAdaptableCorbaPyObject(type,inport->edGetType())) + { + return new PyCorbaSequence(inport); } else - { - stringstream msg; - msg << "Cannot connect InputPyPort : incompatible objref types "; - msg << __FILE__ << ":" <<__LINE__; - throw ConversionException(msg.str()); + { + stringstream msg; + msg << "Cannot convert this sequence type " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); } } - else if(inport->type()->kind() == Sequence) + else if(inport->edGetType()->kind() == YACS::ENGINE::Struct) { - if(isAdaptableCorbaPyObject(type,inport->type())) - { - return new PyCorbaSequence(inport); + if(isAdaptableCorbaPyObject(type,inport->edGetType())) + { + return new PyCorbaStruct(inport); } else - { - stringstream msg; - msg << "Cannot convert this sequence type " ; - msg << __FILE__ << ":" <<__LINE__; - throw ConversionException(msg.str()); + { + stringstream msg; + msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id(); + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); } } - // Adaptation not found + // Adaptation not possible 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++ +//! Adapt a CORBA input port to connect it to a XML output port +/*! + * \param inport : input port to adapt to Xml type type + * \param type : type supported by output port + * \return an adaptator port of type InputXmlPort + */ + +InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport, + TypeCode * type) throw (ConversionException) +{ + // BEWARE : using the generic check + if(inport->edGetType()->isAdaptable(type)) + { + //output type is convertible to input type + return new XmlCorba(inport); + } + //output type is not convertible + stringstream msg; + msg << "Cannot connect InputCorbaPort with OutputXmlPort : " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); +} + +//! Adapt a CORBA input port to a C++ output port /*! * \param inport : input port to adapt to C++ type type - * \param type : le type supporté par le port sortant + * \param type : outport data type + * \return an adaptator port of type InputCPPPort */ InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport, - TypeCode * type) throw (ConversionException) + TypeCode * type) throw (ConversionException) { - throw ConversionException("Cannot connect InputCorbaPort to C++ "); + DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" ); + if(isAdaptableCorbaCpp(type,inport->edGetType())) + { + //output type is convertible to input type + return new CppCorba(inport); + } + //output type is not convertible + stringstream msg; + msg << "Cannot connect InputCorbaPort with OutputCppPort : " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); } -//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant dont l'implémentation est donnée par impl +//! Adapt a CORBA input port to a neutral data +/*! + * \param inport : InputPort to adapt to Neutral type type + * \param type : outport data type + * \return an adaptator port of type Neutralxxxx + */ + +InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport, + TypeCode * type) throw (ConversionException) +{ + if(inport->edGetType()->kind() == Double) + { + if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport); + } + else if(inport->edGetType()->kind() == Int) + { + if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport); + } + else if(inport->edGetType()->kind() == String) + { + if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport); + } + else if(inport->edGetType()->kind() == Bool) + { + if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport); + } + else if(inport->edGetType()->kind() == Objref) + { + if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport); + } + else if(inport->edGetType()->kind() == Sequence) + { + if(isAdaptableCorbaNeutral(type,inport->edGetType())) + return new NeutralCorbaSequence(inport); + else + { + stringstream msg; + msg << "Cannot convert this sequence type " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); + } + } + + // Adaptation not possible + stringstream msg; + msg << "Cannot connect InputCorbaPort to Neutral output " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); +} + +//! Adapt a CORBA input port to an output which implementation and type are given by impl and type /*! * \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 + * \param type : outport data type + * \return an adaptator port which type depends on impl */ InputPort* RuntimeSALOME::adapt(InputCorbaPort* source, - const string& impl, - TypeCode * type) throw (ConversionException) + const std::string& impl, + TypeCode * type) throw (ConversionException) { - cerr<<"RuntimeSALOME::adapt(InputPyPort* source" << endl; - if(impl == "CPP") + if(impl == CppNode::IMPL_NAME) { return adaptCorbaToCpp(source,type); } - else if(impl == "Python") + else if(impl == PythonNode::IMPL_NAME) { return adaptCorbaToPython(source,type); } - else if(impl == "CORBA") + else if(impl == CORBANode::IMPL_NAME) { return adaptCorbaToCorba(source,type); } - else if(impl == "XML") + else if(impl == XmlNode::IMPL_NAME) { return adaptCorbaToXml(source,type); } - else + else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME) + { + return adaptCorbaToNeutral(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 +//! Adapt a Python input port to a Python output port /*! - * 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. + * No need to make conversion or cast. + * Only check, it's possible. * \param inport : InputPort to adapt to Python type type - * \param type : le TypeCode supporté par le port sortant - * \return InputPort de type Python (InputPyPort) + * \param type : outport data type + * \return an adaptator port of type InputPyPort */ InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport, - TypeCode * type) throw (ConversionException) + TypeCode * type) throw (ConversionException) { - if(isAdaptablePyObjectPyObject(type,inport->type())) + if(isAdaptablePyObjectPyObject(type,inport->edGetType())) { - //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; + //output data is convertible to input type + //With python, no need to convert. Conversion will be done automatically + //by the interpreter + return new ProxyPort(inport); } - //les types sont non convertibles + //output data is not convertible to input type stringstream msg; msg << "Cannot connect 2 Python Port with non convertible types: " ; - msg << type->id() << " != " << inport->type()->id(); + msg << type->id() << " != " << inport->edGetType()->id(); + msg << " ("<<__FILE__ << ":" << __LINE__<<")"; throw ConversionException(msg.str()); } -//! Retourne un adaptateur d'un port entrant Python pour un port sortant C++ +//! Adapt a Python input port to a C++ output port /*! - * 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) + * \param type : outport data type + * \return an adaptator port of C++ type (InputCppPort) */ InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport, - TypeCode * type) throw (ConversionException) + TypeCode * type) throw (ConversionException) { - throw ConversionException("Cannot connect InputPyPort to C++ "); + DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" ); + if(isAdaptablePyObjectCpp(type,inport->edGetType())) + { + //output type is convertible to input type + return new CppPy(inport); + } + //output type is not convertible + stringstream msg; + msg << "Cannot connect InputPythonPort with OutputCppPort : " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); } -//! Retourne un adaptateur d'un port entrant Python pour un port sortant Corba +//! Adapt a Python input port to a Neutral data port /*! - * On convertit dans tous les cas + * \param inport : InputPort to adapt to Neutral type type + * \param type : outport data type + * \return an adaptator port of Neutral type (Neutralxxxx) + */ + +InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport, + TypeCode * type) throw (ConversionException) +{ + if(inport->edGetType()->kind() == Double) + { + if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport); + } + else if(inport->edGetType()->kind() == Int) + { + if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport); + } + else if(inport->edGetType()->kind() == String) + { + if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport); + } + else if(inport->edGetType()->kind() == Bool) + { + if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport); + } + else if(inport->edGetType()->kind() == Objref) + { + if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport); + } + else if(inport->edGetType()->kind() == Sequence) + { + if(isAdaptablePyObjectNeutral(type,inport->edGetType())) + return new NeutralPySequence(inport); + else + { + stringstream msg; + msg << "Cannot convert this sequence type " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); + } + } + // Adaptation not possible + stringstream msg; + msg << "Cannot connect InputPyPort to Neutral output " ; + msg << "Output typeid: " << type->id() << " Input typeid: " << inport->edGetType()->id(); + msg << " ("__FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); +} + +//! Adapt a Python input port to a Corba output port +/*! + * Always convert the data * \param inport : InputPort to adapt to Corba type type - * \param type : le TypeCode supporté par le port sortant - * \return InputPort de type Corba (InputCorbaPort) + * \param type : outport data type + * \return an adaptator port of Corba type (InputCorbaPort) */ InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport, - TypeCode * type) throw (ConversionException) + TypeCode * type) throw (ConversionException) { - cerr << "RuntimeSALOME::adaptPythonToCorba:" ; - cerr << inport->type()->kind() << ":" << type->kind()<< endl; - - if(inport->type()->kind() == Double) + if(inport->edGetType()->kind() == Double) { - if(isAdaptablePyObjectCorba(type,inport->type()))return new CorbaPyDouble(inport); + if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport); } - else if(inport->type()->kind() == Int) + else if(inport->edGetType()->kind() == Int) { - if(isAdaptablePyObjectCorba(type,inport->type()))return new CorbaPyInt(inport); + if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport); } - else if(inport->type()->kind() == String) + else if(inport->edGetType()->kind() == String) { - if(isAdaptablePyObjectCorba(type,inport->type()))return new CorbaPyString(inport); + if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport); } - else if(inport->type()->kind() == Objref) + else if(inport->edGetType()->kind() == Bool) { - if(isAdaptablePyObjectCorba(type,inport->type())) - { - return new CorbaPyObjref(inport); + if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport); + } + else if(inport->edGetType()->kind() == Objref) + { + if(isAdaptablePyObjectCorba(type,inport->edGetType())) + { + return new CorbaPyObjref(inport); } else - { - stringstream msg; - msg << "Cannot connect InputCorbaPort : incompatible objref types "; - msg << __FILE__ << ":" <<__LINE__; - throw ConversionException(msg.str()); + { + stringstream msg; + msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id(); + msg << " " << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); } } - else if(inport->type()->kind() == Sequence) + else if(inport->edGetType()->kind() == Sequence) { - if(isAdaptablePyObjectCorba(type,inport->type())) - { - return new CorbaPySequence(inport); + if(isAdaptablePyObjectCorba(type,inport->edGetType())) + { + return new CorbaPySequence(inport); } else - { - stringstream msg; - msg << "Cannot convert this sequence type " ; - msg << __FILE__ << ":" <<__LINE__; - throw ConversionException(msg.str()); + { + stringstream msg; + msg << "Cannot convert this sequence type " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); } } - // Adaptation not found + else if(inport->edGetType()->kind() == YACS::ENGINE::Struct) + { + if(isAdaptablePyObjectCorba(type,inport->edGetType())) + { + return new CorbaPyStruct(inport); + } + else + { + stringstream msg; + msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id(); + msg << " " << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); + } + } + // Adaptation not possible 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 +//! Adapt a Python input port to a Xml output port +/*! + * \param inport : input port to adapt to Xml type type + * \param type : output port type + * \return an input port of type InputXmlPort + */ + +InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport, + TypeCode * type) throw (ConversionException) +{ + // BEWARE : using the generic check + if(inport->edGetType()->isAdaptable(type)) + { + //convertible type + return new XmlPython(inport); + } + //non convertible type + stringstream msg; + msg << "Cannot connect InputPyPort with OutputXmlPort : " ; + msg << "(" <<__FILE__ << ":" <<__LINE__<< ")"; + throw ConversionException(msg.str()); +} + +//! Adapt a Python input port to an output port with a given implementation /*! * \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 + * \param type : output port type + * \return adaptated input port */ InputPort* RuntimeSALOME::adapt(InputPyPort* source, - const string& impl, - TypeCode * type) throw (ConversionException) + const std::string& impl, + TypeCode * type) throw (ConversionException) { - cerr<<"RuntimeSALOME::adapt(InputPyPort* source" << endl; - if(impl == "CPP") + if(impl == CppNode::IMPL_NAME) { return adaptPythonToCpp(source,type); } - else if(impl == "Python") + else if(impl == PythonNode::IMPL_NAME) { return adaptPythonToPython(source,type); } - else if(impl == "CORBA") + else if(impl == CORBANode::IMPL_NAME) { return adaptPythonToCorba(source,type); } + else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME) + { + return adaptPythonToNeutral(source,type); + } + else if(impl == XmlNode::IMPL_NAME) + { + return adaptPythonToXml(source,type); + } + else + { + stringstream msg; + msg << "Cannot connect InputPyPort : unknown implementation " << impl; + msg << " ("<<__FILE__ << ":" << __LINE__<<")"; + throw ConversionException(msg.str()); + } +} + + +//! Adapt a C++ input port to connect it to a CORBA output port +/*! + * \param inport : input port to adapt to CORBA type type + * \param type : type supported by output port + * \return an adaptator port of type InputCorbaPort + */ + +InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport, + TypeCode * type) throw (ConversionException) +{ + DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)"); + if(isAdaptableCppCorba(type,inport->edGetType())) + { + //output type is convertible to input type + return new CorbaCpp(inport); + } + //output type is not convertible + stringstream msg; + msg << "Cannot connect InputCppPort to Corba output port " ; + msg << type->id() << " != " << inport->edGetType()->id(); + msg << " ("__FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); +} + +//! Adapt a C++ input port to a Python output port +/*! + * \param inport : input port to adapt to Python type type + * \param type : output port type + * \return an adaptated input port of type InputPyPort + */ +InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport, + TypeCode * type) throw (ConversionException) +{ + DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)"); + if(isAdaptableCppPyObject(type,inport->edGetType())) + { + //output type is convertible to input type + return new PyCpp(inport); + } + //output type is not convertible + stringstream msg; + msg << "Cannot connect InputCppPort with OutputPythonPort : " ; + msg << __FILE__ << ":" <<__LINE__; + throw ConversionException(msg.str()); +} + +//! Adapt a C++ input port to a C++ output port +/*! + * \param inport : input port to adapt to C++ type type + * \param type : output port type + * \return an adaptated input port of type InputPyPort + */ +InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport, + TypeCode * type) throw (ConversionException) +{ + DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" ); + DEBTRACE(type->kind() << " " << inport->edGetType()->kind() ); + if(type->isAdaptable(inport->edGetType())) + { + //the output data is convertible to inport type + return new CppCpp(inport); + } + //non convertible type + stringstream msg; + msg << "Cannot connect Cpp InputPort to OutputCppPort : " ; + msg << "(" <<__FILE__ << ":" <<__LINE__<< ")"; + throw ConversionException(msg.str()); +} + +//! Adapt a C++ input port to a Neutral output port +/*! + * \param inport : input port to adapt to C++ type type + * \param type : output port type + * \return an adaptated input port of type InputPyPort + */ +InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport, + TypeCode * type) throw (ConversionException) +{ + DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" ); + DEBTRACE(type->kind() << " " << inport->edGetType()->kind() ); + if(type->isAdaptable(inport->edGetType())) + { + //the output data is convertible to inport type + return new NeutralCpp(inport); + } + //non convertible type + stringstream msg; + msg << "Cannot connect Cpp InputPort to OutputNeutralPort : " ; + msg << "(" <<__FILE__ << ":" <<__LINE__<< ")"; + throw ConversionException(msg.str()); +} + +InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport, + TypeCode * type) throw (ConversionException) +{ + DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" ); + if(isAdaptableCppXml(type,inport->edGetType())) + { + //convertible type + return new XmlCpp(inport); + } + //non convertible type + stringstream msg; + msg << "Cannot connect InputCppPort with OutputXmlPort : " ; + msg << "(" <<__FILE__ << ":" <<__LINE__<< ")"; + throw ConversionException(msg.str()); +} + +//! Adapt a C++ input port to connect it to an output port with a given implementation +/*! + * \param source : input port to adapt to implementation impl and type type + * \param impl : output port implementation (C++, Python or Corba) + * \param type : output port supported type + * \return the adaptated port + */ + +InputPort* RuntimeSALOME::adapt(InputCppPort* source, + const std::string& impl, + TypeCode * type) throw (ConversionException) +{ + DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)"); + if(impl == CORBANode::IMPL_NAME) + { + return adaptCppToCorba(source,type); + } + else if(impl == PythonNode::IMPL_NAME) + { + return adaptCppToPython(source,type); + } + else if(impl == XmlNode::IMPL_NAME) + { + return adaptCppToXml(source,type); + } + else if(impl == CppNode::IMPL_NAME) + { + return adaptCppToCpp(source, type); + } + else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME) + { + return adaptCppToNeutral(source, type); + } else { - throw ConversionException("Cannot connect InputPyPort : unknown implementation "); + stringstream msg; + msg << "Cannot connect InputCppPort to " << impl << " implementation"; + msg << " ("__FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); } } // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort, -// const InputPort* inputPort) +// const InputPort* inputPort) // { // bool result=true; // return result; diff --git a/src/runtime/RuntimeSALOME.hxx b/src/runtime/RuntimeSALOME.hxx index c92e08706..b64312d35 100644 --- a/src/runtime/RuntimeSALOME.hxx +++ b/src/runtime/RuntimeSALOME.hxx @@ -2,11 +2,9 @@ #ifndef _RUNTIMESALOME_HXX_ #define _RUNTIMESALOME_HXX_ +#include +#include #include "Runtime.hxx" -#include "CORBAPorts.hxx" -#include "PythonPorts.hxx" -#include "XMLPorts.hxx" -#include "CORBAXMLConv.hxx" #include #include @@ -22,12 +20,12 @@ namespace YACS { PyObject* (*cxxObjRefToPyObjRef)(const CORBA::Object_ptr cxx_obj, - CORBA::Boolean hold_lock); + 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); + 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. @@ -36,73 +34,159 @@ namespace YACS omniORBpyAPI(); // Constructor for the singleton. Sets up the function pointers. }; + class RuntimeSALOME; RuntimeSALOME* getSALOMERuntime(); + class InputCorbaPort; + class InputPyPort; + class InputXmlPort; + class InputCppPort; + + class RuntimeSALOME: public Runtime { public: - static void setRuntime(); // singleton creation + static enum + { + IsPyExt = 1, + UsePython = 2, + UseCorba = 4, + UseXml = 8, + UseCpp = 16, + UseSalome = 32 + } FLAGS; + + static void setRuntime(long flags = UsePython+UseCorba+UseXml+UseCpp+UseSalome); // singleton creation friend RuntimeSALOME* getSALOMERuntime(); - virtual void init(); + virtual void init(long flags); virtual void fini(); virtual InputPort* createInputPort(const std::string& name, - const std::string& impl, - Node * node, - TypeCode * type); + 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); + const std::string& impl, + Node * node, + TypeCode * type); + virtual InputDataStreamPort* createInputDataStreamPort(const std::string& name, + Node *node,TypeCode *type); + + virtual OutputDataStreamPort* createOutputDataStreamPort(const std::string& name, + Node *node,TypeCode *type); + + virtual InlineFuncNode* createFuncNode(const std::string& kind,const std::string& name); + virtual InlineNode* createScriptNode(const std::string& kind,const std::string& name); + + virtual ServiceNode* createRefNode(const std::string& kind,const std::string& name); + virtual ServiceNode* createCompoNode(const std::string& kind,const std::string& name); + virtual ServiceInlineNode *createSInlineNode(const std::string& kind, const std::string& name); + virtual ComponentInstance* createComponentInstance(const std::string& name, + const std::string& kind=""); + virtual Container *createContainer(const std::string& kind=""); + virtual WhileLoop* createWhileLoop(const std::string& name); + virtual ForLoop* createForLoop(const std::string& name); + virtual Bloc* createBloc(const std::string& name); + virtual Proc* createProc(const std::string& name); + + virtual InputPort* adapt(InputPort* source, + const std::string& impl, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptNeutral(InputPort* source, + const std::string& impl, + TypeCode * type) throw (ConversionException); virtual InputPort* adapt(InputCorbaPort* source, - const std::string& impl, - TypeCode * type) throw (ConversionException); + const std::string& impl, + TypeCode * type) throw (ConversionException); virtual InputPort* adaptCorbaToCorba(InputCorbaPort* source, - TypeCode * type) throw (ConversionException); + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptCorbaToNeutral(InputCorbaPort* source, + TypeCode * type) throw (ConversionException); virtual InputPort* adaptCorbaToPython(InputCorbaPort* source, - TypeCode * type) throw (ConversionException); + TypeCode * type) throw (ConversionException); virtual InputPort* adaptCorbaToCpp(InputCorbaPort* source, - TypeCode * type) throw (ConversionException); + TypeCode * type) throw (ConversionException); virtual InputPort* adaptCorbaToXml(InputCorbaPort* source, - TypeCode * type) throw (ConversionException); + TypeCode * type) throw (ConversionException); virtual InputPort* adapt(InputPyPort* source, - const std::string& impl, - TypeCode * type) throw (ConversionException); + const std::string& impl, + TypeCode * type) throw (ConversionException); virtual InputPort* adaptPythonToCorba(InputPyPort* source, - TypeCode * type) throw (ConversionException); + TypeCode * type) throw (ConversionException); + virtual InputPort* adaptPythonToNeutral(InputPyPort* source, + TypeCode * type) throw (ConversionException); + virtual InputPort* adaptPythonToPython(InputPyPort* source, - TypeCode * type) throw (ConversionException); + TypeCode * type) throw (ConversionException); + virtual InputPort* adaptPythonToXml(InputPyPort* source, + TypeCode * type) throw (ConversionException); + virtual InputPort* adaptPythonToCpp(InputPyPort* source, - TypeCode * type) throw (ConversionException); + TypeCode * type) throw (ConversionException); + + virtual InputPort* adapt(InputCppPort* source, + const std::string& impl, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptCppToCorba(InputCppPort* source, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptCppToNeutral(InputCppPort* source, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptCppToPython(InputCppPort* source, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptCppToXml(InputCppPort* source, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptCppToCpp(InputCppPort* source, + TypeCode * type) throw (ConversionException); virtual InputPort* adapt(InputXmlPort* source, - const std::string& impl, - TypeCode * type) throw (ConversionException); + const std::string& impl, + TypeCode * type) throw (ConversionException); virtual InputPort* adaptXmlToCorba(InputXmlPort* source, - TypeCode * type) throw (ConversionException); + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptXmlToPython(InputXmlPort* inport, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptXmlToCpp(InputXmlPort* inport, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptXmlToNeutral(InputXmlPort* inport, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptNeutralToXml(InputPort* inport, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptNeutralToPython(InputPort* inport, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptNeutralToCorba(InputPort* inport, + TypeCode * type) throw (ConversionException); + + virtual InputPort* adaptNeutralToCpp(InputPort* inport, + TypeCode * type) throw (ConversionException); + virtual ~RuntimeSALOME(); CORBA::ORB_ptr getOrb(); PyObject * getPyOrb(); @@ -112,11 +196,15 @@ namespace YACS protected: RuntimeSALOME(); // singleton + RuntimeSALOME(long flags); // singleton CORBA::ORB_var _orb; PyObject * _pyorb; PyObject * _bltins; DynamicAny::DynAnyFactory_var _dynFactory; omniORBpyAPI* _api; + long _flags; + bool _usePython, _useCorba, _useCpp, _useXml; + }; } } diff --git a/src/runtime/SALOMEDispatcher.cxx b/src/runtime/SALOMEDispatcher.cxx new file mode 100644 index 000000000..b900a766c --- /dev/null +++ b/src/runtime/SALOMEDispatcher.cxx @@ -0,0 +1,57 @@ + +#include "SALOMEDispatcher.hxx" +#include "Node.hxx" + +#include + +using namespace std; +using namespace YACS::BASES; +using namespace YACS::ENGINE; + +map< pair , set > SALOMEDispatcher::_observers; +SALOMEDispatcher* SALOMEDispatcher::_disp = 0; + +SALOMEDispatcher::SALOMEDispatcher() +{ +} + +SALOMEDispatcher::~SALOMEDispatcher() +{ +} + +void SALOMEDispatcher::setSALOMEDispatcher() +{ + cerr << "SALOMEDispatcher::setSALOMEDispatcher" << endl; + _disp=new SALOMEDispatcher(); + YACS::ENGINE::Dispatcher::setDispatcher(_disp); +} + +SALOMEDispatcher* SALOMEDispatcher::getSALOMEDispatcher() +{ + return _disp; +} + +void SALOMEDispatcher::dispatch(Node* object, const std::string& event) +{ + cerr << "SALOMEDispatcher::dispatch " << event << " " << object->getNumId() << endl; + CORBA::Long numId = object->getNumId(); + typedef set::iterator jt; + std::pair key(numId, event); + for(jt iter = _observers[key].begin(); iter!=_observers[key].end(); iter++) + { + if (! CORBA::is_nil(*iter)) + { + cerr << "numId, event " << numId << " " << event << endl; + (*iter)->notifyObserver(numId, event.c_str()); + } + else + cerr << "************************** dispatch on a CORBA::nil *******************************" <(numid,event)].insert(YACSGui_ORB::Observer::_duplicate(observer)); +} diff --git a/src/runtime/SALOMEDispatcher.hxx b/src/runtime/SALOMEDispatcher.hxx new file mode 100644 index 000000000..76fb20860 --- /dev/null +++ b/src/runtime/SALOMEDispatcher.hxx @@ -0,0 +1,40 @@ + +#ifndef __SALOMEDISPATCHER_HXX__ +#define __SALOMEDISPATCHER_HXX__ + +#include "Dispatcher.hxx" +#include "yacsgui.hh" +#include "Thread.hxx" +#include "Semaphore.hxx" + +#include +#include +#include +#include + +namespace YACS +{ + namespace ENGINE + { + class SALOMEDispatcher: public Dispatcher + { + public: + SALOMEDispatcher(); + void dispatch(Node* object, const std::string& event); + void addObserver(YACSGui_ORB::Observer_ptr observer,int numid, std::string event); + static void setSALOMEDispatcher(); + static SALOMEDispatcher* getSALOMEDispatcher(); + virtual ~SALOMEDispatcher(); + protected: + static std::map< std::pair , std::set > _observers; + static SALOMEDispatcher* _disp; + static void *ThDisp( void *a); + static YACS::BASES::Semaphore _s1; + static std::list< std::pair > _listOfEvents; + }; + + + } +} + +#endif diff --git a/src/runtime/SALOMERuntime.i b/src/runtime/SALOMERuntime.i new file mode 100644 index 000000000..75b2ced9f --- /dev/null +++ b/src/runtime/SALOMERuntime.i @@ -0,0 +1,123 @@ +// ---------------------------------------------------------------------------- +%define SALOMEDOCSTRING +"SALOMERuntime docstring +Implementation of nodes for SALOME platform." +%enddef + +%module(docstring=SALOMEDOCSTRING) SALOMERuntime + +%feature("autodoc", "0"); +%include std_string.i + +// ---------------------------------------------------------------------------- + +%{ +#include "RuntimeSALOME.hxx" +#include "SALOMEDispatcher.hxx" + +#include +#include +#include +#include +#include +#include "utilities.h" + +using namespace std; +using namespace YACS::ENGINE; + +//--- from omniORBpy.h (not present on Debian Sarge packages) +// (rename omniORBpyAPI in omniORBpy_API) +struct omniORBpy_API +{ + + 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. + + + omniORBpy_API(); + // Constructor for the singleton. Sets up the function pointers. +}; + + omniORBpy_API* api; + +%} + + +// ---------------------------------------------------------------------------- + + +%init +%{ + // 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 = (omniORBpy_API*)PyCObject_AsVoidPtr(pyapi); + Py_DECREF(pyapi); +%} + +// ---------------------------------------------------------------------------- + +%typemap(python,out) YACSGui_ORB::Observer_ptr +{ + MESSAGE("typemap out on CORBA object ptr"); + SCRUTE($1); + $result = api->cxxObjRefToPyObjRef($1, 1); + SCRUTE($result); +} + +%typemap(python,in) YACSGui_ORB::Observer_ptr +{ + MESSAGE("typemap in on CORBA object ptr"); + try + { + CORBA::Object_ptr obj = api->pyObjRefToCxxObjRef($input,1); + $1 = YACSGui_ORB::Observer::_narrow(obj); + SCRUTE($1); + } + catch (...) + { + PyErr_SetString(PyExc_RuntimeError, "not a valid CORBA object ptr"); + } +} + +// ---------------------------------------------------------------------------- + +namespace YACS +{ + namespace ENGINE + { + class RuntimeSALOME: public Runtime + { + public: + static void setRuntime(bool ispyext=false); // singleton creation + virtual ~RuntimeSALOME(); + protected: + RuntimeSALOME(); // singleton + RuntimeSALOME(bool ispyext); // singleton + }; + + class SALOMEDispatcher: public Dispatcher + { + public: + void addObserver(YACSGui_ORB::Observer_ptr observer,int numid, std::string event); + static void setSALOMEDispatcher(); + static SALOMEDispatcher* getSALOMEDispatcher(); + }; + + } +} diff --git a/src/runtime/SALOMEconfig.h b/src/runtime/SALOMEconfig.h new file mode 100644 index 000000000..931f209cd --- /dev/null +++ b/src/runtime/SALOMEconfig.h @@ -0,0 +1,57 @@ +/*---------------------------------------------------------------------------------- + Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +------------------------------------------------------------------------------------*/ + +#ifndef SALOME_CONFIG_H +#define SALOME_CONFIG_H + +#define DEBUG + +#define QUOTE(x) #x +#define CORBA_CLIENT_HEADER(x) QUOTE(x.hh) +#define CORBA_SERVER_HEADER(x) QUOTE(x.hh) + +#ifndef PCLINUX + #define PCLINUX +#endif + + +/* A path to a rcp-like command */ +#define RCP "/usr/bin/rcp" + +/* A path to a rm-like command */ +#define RM "/bin/rm" + +/* A path to a cp-like command */ +#define CP "/bin/cp" + +/* A path to a rsh-like command */ +#define RSH "/usr/bin/rsh" + +/* A path to a scp-like command */ +#define SCP "/usr/bin/scp" + +/* A path to a sh-like command */ +#define SH "/bin/sh" + +/* A path to a ssh-like command */ +#define SSH "/usr/bin/ssh" + +#endif diff --git a/src/runtime/SalomeComponent.cxx b/src/runtime/SalomeComponent.cxx new file mode 100644 index 000000000..552996def --- /dev/null +++ b/src/runtime/SalomeComponent.cxx @@ -0,0 +1,142 @@ +#include "RuntimeSALOME.hxx" +#include "SalomeComponent.hxx" +#include "SalomeContainer.hxx" +#include "CORBANode.hxx" + +#ifdef SALOME_KERNEL +#include "SALOME_NamingService.hxx" +#include "SALOME_LifeCycleCORBA.hxx" +#endif + +#include +#include +#include + +using namespace YACS::ENGINE; +using namespace std; + +const char SalomeComponent::KIND[]="Salome"; + +//! SalomeComponent constructor +SalomeComponent::SalomeComponent(const std::string& name): ComponentInstance(name) +{ + _objComponent=CORBA::Object::_nil(); +} + +//! SalomeComponent copy constructor +SalomeComponent::SalomeComponent(const SalomeComponent& other):ComponentInstance(other) +{ + _objComponent=CORBA::Object::_nil(); +} + +SalomeComponent::~SalomeComponent() +{ +} + +std::string SalomeComponent::getKind() const +{ + return KIND; +} + +//! Unload the component +void SalomeComponent::unload() +{ + //Not implemented + std::cerr << "SalomeComponent::unload : not implemented " << std::endl; +} + +//! Is the component instance already loaded ? +bool SalomeComponent::isLoaded() +{ + if(CORBA::is_nil(_objComponent)) + return false; + else + return true; +} + +#ifdef SALOME_KERNEL +//! Load the component +void SalomeComponent::load() +{ + if(_container) + { + SalomeContainer *containerC=(SalomeContainer *)_container; + containerC->lock();//To be sure + if(!_container->isAlreadyStarted()) + { + try + { + _container->start(); + } + catch(Exception& e) + { + containerC->unLock(); + throw e; + } + } + containerC->unLock(); + containerC->lock();//To be sure + const char* componentName=_name.c_str(); + //char *val2=CORBA::string_dup(""); + // does not work with python components + // does not make a strict load but a find or load component + // _objComponent=containerC->_trueCont->load_impl(componentName,val2); + bool isLoadable = containerC->_trueCont->load_component_Library(componentName); + if (isLoadable) + _objComponent=containerC->_trueCont->create_component_instance(componentName, 0); + + if(CORBA::is_nil(_objComponent)) + { + containerC->unLock(); + throw Exception("SalomeComponent::load : Error while trying to create a new component."); + } + containerC->unLock(); + return; + } + //throw Exception("SalomeComponent::load : no container specified !!! To be implemented in executor to allocate default a Container in case of presenceOfDefaultContainer."); + //This component has no specified container : use default container policy + SALOME_NamingService ns(getSALOMERuntime()->getOrb()); + SALOME_LifeCycleCORBA LCC(&ns); + Engines::MachineParameters params; + LCC.preSet(params); + params.hostname="localhost"; + params.container_name ="FactoryServer"; + _objComponent=LCC.LoadComponent(params,_name.c_str()); +} +#else +void SalomeComponent::load() +{ + throw Exception("YACS has been built without SALOME support"); +} +#endif + +//! Create a ServiceNode with this component instance and no input or output port +/*! + * \param name : node name + * \return a new SalomeNode node + */ +ServiceNode* SalomeComponent::createNode(const std::string& name) +{ + SalomeNode* node=new SalomeNode(name); + node->setComponent(this); + return node; +} + +//! Clone the component instance +ComponentInstance* SalomeComponent::clone() const +{ + if(_isAttachedOnCloning) + { + incrRef(); + return (ComponentInstance*) (this); + } + else + return new SalomeComponent(*this); +} + +std::string SalomeComponent::getFileRepr() const +{ + ostringstream stream; + stream << "" << getName() << ""; + return stream.str(); +} diff --git a/src/runtime/SalomeComponent.hxx b/src/runtime/SalomeComponent.hxx new file mode 100644 index 000000000..a276e2124 --- /dev/null +++ b/src/runtime/SalomeComponent.hxx @@ -0,0 +1,40 @@ +#ifndef _SALOMECOMPONENT_HXX_ +#define _SALOMECOMPONENT_HXX_ + +#include "ComponentInstance.hxx" +#include + +namespace YACS +{ + namespace ENGINE + { + class ServiceNode; + +/*! \brief Class for Salome component instance + * + * \ingroup Nodes + * + */ + class SalomeComponent : public ComponentInstance + { + public: + SalomeComponent(const std::string& name); + SalomeComponent(const SalomeComponent& other); + virtual ~SalomeComponent(); + virtual void load(); + virtual void unload(); + virtual bool isLoaded(); + virtual ServiceNode* createNode(const std::string& name); + virtual ComponentInstance* clone() const; + virtual std::string getFileRepr() const; + virtual CORBA::Object_ptr getCompoPtr(){return CORBA::Object::_duplicate(_objComponent);} + public: + static const char KIND[]; + virtual std::string getKind() const; + protected: + CORBA::Object_var _objComponent; + }; + } +} + +#endif diff --git a/src/runtime/SalomeContainer.cxx b/src/runtime/SalomeContainer.cxx new file mode 100644 index 000000000..f7963d341 --- /dev/null +++ b/src/runtime/SalomeContainer.cxx @@ -0,0 +1,129 @@ +//#define REFCNT +#ifdef REFCNT +#define private public +#define protected public +#include +#include +#endif + +#include "RuntimeSALOME.hxx" +#include "SalomeContainer.hxx" +#include "SalomeComponent.hxx" + +#include "SALOME_NamingService.hxx" +#include "SALOME_LifeCycleCORBA.hxx" +#include "SALOME_ContainerManager.hxx" + +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +SalomeContainer::SalomeContainer():_trueCont(Engines::Container::_nil()) +{ +} + +SalomeContainer::SalomeContainer(const SalomeContainer& other):Container(other),_trueCont(Engines::Container::_nil()) +{ +} + +SalomeContainer::~SalomeContainer() +{ +} + +void SalomeContainer::lock() +{ + _mutex.lock(); +} + +void SalomeContainer::unLock() +{ + _mutex.unlock(); +} + +bool SalomeContainer::isAlreadyStarted() const +{ + if(CORBA::is_nil(_trueCont)) + return false; + else + return true; +} + +void SalomeContainer::start() throw (Exception) +{ + CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb(); + SALOME_NamingService ns(orb); + CORBA::Object_var obj=ns.Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS); + Engines::ContainerManager_var contManager=Engines::ContainerManager::_narrow(obj); + SALOME_LifeCycleCORBA LCC(&ns); + Engines::MachineParameters params; + LCC.preSet(params); + params.hostname=CORBA::string_dup(""); + std::ostringstream stream; + stream << (void *)(this); + params.container_name=CORBA::string_dup(stream.str().c_str()); + try + { + std::string policy=getProperty("policy"); + if(policy=="best") + _trueCont=contManager->StartContainer(params,Engines::P_BEST); + else if(policy=="first") + _trueCont=contManager->StartContainer(params,Engines::P_FIRST); + else + _trueCont=contManager->StartContainer(params,Engines::P_CYCL); + } + catch(CORBA::COMM_FAILURE&) + { + throw Exception("SalomeContainer::start : Unable to launch container in Salome : CORBA Comm failure detected"); + } + catch(CORBA::Exception&) + { + throw Exception("SalomeContainer::start : Unable to launch container in Salome : Unexpected CORBA failure detected"); + } + if(CORBA::is_nil(_trueCont)) + throw Exception("SalomeContainer::start : Unable to launch container in Salome"); +#ifdef REFCNT + DEBTRACE(_trueCont->_PR_getobj()->pd_refCount ); +#endif +} + +Container *SalomeContainer::clone() const +{ + if(_isAttachedOnCloning) + { + incrRef(); + return (Container*) (this); + } + else + return new SalomeContainer(*this); +} + +std::string SalomeContainer::getPlacementId() const +{ + if(isAlreadyStarted()) + { + const char *what="/"; + char *corbaStr=_trueCont->name(); + string ret(corbaStr); + CORBA::string_free(corbaStr); + //Salome FOREVER ... + std::string::size_type i=ret.find_first_of(what,0); + i=ret.find_first_of(what, i==std::string::npos ? i:i+1); + if(i!=std::string::npos) + return ret.substr(i+1); + return ret; + } + else + return "Not placed yet !!!"; +} + +void SalomeContainer::checkCapabilityToDealWith(const ComponentInstance *inst) const throw (Exception) +{ + if(inst->getKind()!=SalomeComponent::KIND) + throw Exception("SalomeContainer::checkCapabilityToDealWith : SalomeContainer is not able to deal with this type of ComponentInstance."); +} + diff --git a/src/runtime/SalomeContainer.hxx b/src/runtime/SalomeContainer.hxx new file mode 100644 index 000000000..275243016 --- /dev/null +++ b/src/runtime/SalomeContainer.hxx @@ -0,0 +1,40 @@ +#ifndef __SALOMECONTAINER_HXX__ +#define __SALOMECONTAINER_HXX__ + +#include "Container.hxx" +#include "Mutex.hxx" +#include +#include CORBA_CLIENT_HEADER(SALOME_Component) + +namespace YACS +{ + namespace ENGINE + { + class SalomeComponent; + + class SalomeContainer : public Container + { + friend class SalomeComponent; + public: + SalomeContainer(); + SalomeContainer(const SalomeContainer& other); + //! For thread safety for concurrent load operation on same Container. + void lock(); + //! For thread safety for concurrent load operation on same Container. + void unLock(); + bool isAlreadyStarted() const; + void start() throw (Exception); + Container *clone() const; + std::string getPlacementId() const; + void checkCapabilityToDealWith(const ComponentInstance *inst) const throw (Exception); + protected: + virtual ~SalomeContainer(); + protected: + //! thread safety in Salome ??? + YACS::BASES::Mutex _mutex; + Engines::Container_var _trueCont; + }; + } +} + +#endif diff --git a/src/runtime/SalomeProc.cxx b/src/runtime/SalomeProc.cxx new file mode 100644 index 000000000..8427cfbde --- /dev/null +++ b/src/runtime/SalomeProc.cxx @@ -0,0 +1,26 @@ +#include "SalomeProc.hxx" +#include "Runtime.hxx" +#include + +using namespace YACS::ENGINE; + +TypeCode * SalomeProc::createInterfaceTc(const std::string& id, const std::string& name, + std::list ltc) +{ + std::string myName; + if(id == "") myName = "IDL:" + name + ":1.0"; + else myName = id; + return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc); +} +TypeCode * SalomeProc::createStructTc(const std::string& id, const std::string& name) +{ + std::string myName; + if(id == "") myName = "IDL:" + name + ":1.0"; + else myName = id; + return TypeCode::structTc(myName.c_str(),name.c_str()); +} + +SalomeProc::~SalomeProc() +{ +} + diff --git a/src/runtime/SalomeProc.hxx b/src/runtime/SalomeProc.hxx new file mode 100644 index 000000000..f37853e14 --- /dev/null +++ b/src/runtime/SalomeProc.hxx @@ -0,0 +1,27 @@ +#ifndef _SALOMEPROC_HXX_ +#define _SALOMEPROC_HXX_ + +#include "Proc.hxx" +#include +#include +#include + +namespace YACS +{ + namespace ENGINE + { + class TypeCode; + + class SalomeProc: public Proc + { + public: + SalomeProc(const std::string& name):Proc(name){}; + virtual ~SalomeProc(); + virtual TypeCode * createInterfaceTc(const std::string& id, const std::string& name, + std::list ltc); + virtual TypeCode * createStructTc(const std::string& id, const std::string& name); + }; + } +} + +#endif diff --git a/src/runtime/SalomePythonComponent.cxx b/src/runtime/SalomePythonComponent.cxx new file mode 100644 index 000000000..7e9922bdb --- /dev/null +++ b/src/runtime/SalomePythonComponent.cxx @@ -0,0 +1,88 @@ +#include "SalomePythonComponent.hxx" +#include "SalomeComponent.hxx" +#include "SalomePythonNode.hxx" +#include "Exception.hxx" +#include "Container.hxx" + +#include + +using namespace YACS::ENGINE; + +const char SalomePythonComponent::KIND[]="SalomePy"; + +unsigned SalomePythonComponent::_cntForReprS = 0; + +SalomePythonComponent::SalomePythonComponent(const std::string &name):ComponentInstance(name),_cntForRepr(_cntForReprS++) +{ +} + +SalomePythonComponent::SalomePythonComponent(const SalomePythonComponent& other):ComponentInstance(other),_cntForRepr(_cntForReprS++) +{ +} + +SalomePythonComponent::~SalomePythonComponent() +{ +} + +void SalomePythonComponent::load() +{ + if(_container) + { + _container->start(); + return; + } + //This component has no specified container : use default container policy + //given by getStringValueToExportInInterp() + //throw Exception("SalomePythonComponent::load : no container specified !!! To be implemented in executor to allocate default a Container in case of presenceOfDefaultContainer."); +} + +void SalomePythonComponent::unload() +{ +} + +bool SalomePythonComponent::isLoaded() +{ + if(!_container) + return false; + else + return _container->isAlreadyStarted(); +} + +std::string SalomePythonComponent::getKind() const +{ + //This is not a bug !!!! SalomeComponent NOT SalomePythonComponent. This is for Container assignation. + return SalomeComponent::KIND; +} + +ComponentInstance* SalomePythonComponent::clone() const +{ + if(_isAttachedOnCloning) + { + incrRef(); + return (ComponentInstance*) (this); + } + else + return new SalomePythonComponent(*this); +} + +ServiceNode *SalomePythonComponent::createNode(const std::string &name) +{ + ServiceNode* node=new SalomePythonNode(name); + node->setComponent(this); + return node; +} + +std::string SalomePythonComponent::getFileRepr() const +{ + std::ostringstream stream; + stream << "" << "SalomePythonComponent #" << _cntForRepr << ""; + return stream.str(); +} + +std::string SalomePythonComponent::getStringValueToExportInInterp() const +{ + if(!_container) + return "localhost/FactoryServer"; + else + return _container->getPlacementId(); +} diff --git a/src/runtime/SalomePythonComponent.hxx b/src/runtime/SalomePythonComponent.hxx new file mode 100644 index 000000000..49ba8f622 --- /dev/null +++ b/src/runtime/SalomePythonComponent.hxx @@ -0,0 +1,34 @@ +#ifndef __SALOMEPYTHONCOMPONENT_HXX__ +#define __SALOMEPYTHONCOMPONENT_HXX__ + +#include "ComponentInstance.hxx" + +namespace YACS +{ + namespace ENGINE + { + class SalomePythonComponent : public ComponentInstance + { + public: + SalomePythonComponent(const std::string &name); + SalomePythonComponent(const SalomePythonComponent& other); + std::string getPlacementId() const; + virtual ~SalomePythonComponent(); + virtual void load(); + virtual void unload(); + virtual bool isLoaded(); + virtual std::string getKind() const; + virtual ComponentInstance* clone() const; + virtual std::string getFileRepr() const; + virtual ServiceNode *createNode(const std::string &name); + //! The specific method that justified SalomePythonComponent class. + std::string getStringValueToExportInInterp() const; + public: + unsigned _cntForRepr; + static unsigned _cntForReprS; + static const char KIND[]; + }; + } +} + +#endif diff --git a/src/runtime/SalomePythonNode.cxx b/src/runtime/SalomePythonNode.cxx new file mode 100644 index 000000000..4466fc71f --- /dev/null +++ b/src/runtime/SalomePythonNode.cxx @@ -0,0 +1,213 @@ +#include "RuntimeSALOME.hxx" +#include "SalomePythonComponent.hxx" +#include "SalomePythonNode.hxx" +#include "PythonNode.hxx" +#include "PythonPorts.hxx" +#include "CORBANode.hxx" + +#include +#include + +using namespace YACS::ENGINE; +using namespace std; + +const char SalomePythonNode::PLACEMENT_VAR_NAME_IN_INTERP[]="__container__from__YACS__"; + +SalomePythonNode::SalomePythonNode(const SalomePythonNode& other, ComposedNode *father):ServiceInlineNode(other,father),_pyfunc(0),_context(0) +{ + //Not a bug : just because port point of view this is like PythonNode. + _implementation = PythonNode::IMPL_NAME; + PyGILState_STATE gstate = PyGILState_Ensure(); + _context=PyDict_New(); + if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) + { + stringstream msg; + msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__; + PyGILState_Release(gstate); + throw Exception(msg.str()); + } + PyGILState_Release(gstate); +} + +SalomePythonNode::SalomePythonNode(const std::string& name): ServiceInlineNode(name),_pyfunc(0) +{ + + //Not a bug : just because port point of view this is like PythonNode. + _implementation = PythonNode::IMPL_NAME; + cerr << "SalomePythonNode::SalomePythonNode " << name << endl; + PyGILState_STATE gstate = PyGILState_Ensure(); + _context=PyDict_New(); + if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) + { + stringstream msg; + msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__; + PyGILState_Release(gstate); + throw Exception(msg.str()); + } + PyGILState_Release(gstate); +} + +void SalomePythonNode::load() +{ + ServiceInlineNode::load(); + cerr << "---------------SalomePythonNode::load function---------------" << endl; + list::iterator iter; + string value2Export=((SalomePythonComponent*)_component)->getStringValueToExportInInterp(); + PyObject* ob=PyString_FromString(value2Export.c_str()); + PyDict_SetItemString(_context,PLACEMENT_VAR_NAME_IN_INTERP,ob); + for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++) + { + OutputPyPort *p=(OutputPyPort *)*iter; + cerr << "port name: " << p->getName() << endl; + cerr << "port kind: " << p->edGetType()->kind() << endl; + } + cerr << _script << endl; + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject *res=PyRun_String(_script.c_str(),Py_file_input,_context,_context); + if(res == NULL) + { + PyErr_Print(); + PyGILState_Release(gstate); + throw Exception("Error during execution"); + return; + } + Py_DECREF(res); + _pyfunc=PyDict_GetItemString(_context,_method.c_str()); + if(_pyfunc == NULL) + { + PyErr_Print(); + PyGILState_Release(gstate); + throw Exception("Error during execution"); + } + cerr << "---------------End SalomePythonNode::load function---------------" << endl; + PyGILState_Release(gstate); +} + +void SalomePythonNode::execute() +{ + cerr << "++++++++++++++ SalomePythonNode::execute: " << getName() << " ++++++++++++++++++++" << endl; + int pos=0; + PyObject* ob; + if(!_pyfunc)throw Exception("SalomePythonNode badly loaded"); + PyGILState_STATE gstate = PyGILState_Ensure(); + + cerr << "---------------SalomePythonNode::inputs---------------" << endl; + PyObject* args = PyTuple_New(getNumberOfInputPorts()) ; + list::iterator iter2; + for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++) + { + InputPyPort *p=(InputPyPort *)*iter2; + cerr << "port name: " << p->getName() << endl; + cerr << "port kind: " << p->edGetType()->kind() << endl; + ob=p->getPyObj(); + PyObject_Print(ob,stderr,Py_PRINT_RAW); + cerr << endl; + cerr << "ob refcnt: " << ob->ob_refcnt << endl; + Py_INCREF(ob); + PyTuple_SetItem(args,pos,ob); + cerr << "ob refcnt: " << ob->ob_refcnt << endl; + pos++; + } + cerr << "---------------End SalomePythonNode::inputs---------------" << endl; + + cerr << "----------------SalomePythonNode::calculation---------------" << endl; + PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW); + cerr << endl; + PyObject_Print(args,stderr,Py_PRINT_RAW); + cerr << endl; + PyObject* result = PyObject_CallObject( _pyfunc , args ) ; + Py_DECREF(args); + if(result == NULL) + { + PyErr_Print(); + PyGILState_Release(gstate); + throw Exception("Error during execution"); + } + cerr << "----------------End SalomePythonNode::calculation---------------" << endl; + + cerr << "-----------------SalomePythonNode::outputs-----------------" << endl; + int nres=1; + if(result == Py_None) + nres=0; + else if(PyTuple_Check(result)) + nres=PyTuple_Size(result); + + if(getNumberOfOutputPorts() != nres) + { + Py_DECREF(result); + PyGILState_Release(gstate); + throw Exception("Number of output arguments : Mismatch between definition and execution"); + } + + pos=0; + PyObject_Print(result,stderr,Py_PRINT_RAW); + cerr << endl; + list::iterator iter; + try + { + for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++) + { + OutputPyPort *p=(OutputPyPort *)*iter; + cerr << "port name: " << p->getName() << endl; + cerr << "port kind: " << p->edGetType()->kind() << endl; + cerr << "port pos : " << pos << endl; + if(PyTuple_Check(result))ob=PyTuple_GetItem(result,pos) ; + else ob=result; + cerr << "ob refcnt: " << ob->ob_refcnt << endl; + PyObject_Print(ob,stderr,Py_PRINT_RAW); + cerr << endl; + p->put(ob); + pos++; + } + } + catch(ConversionException) + { + Py_DECREF(result); + PyGILState_Release(gstate); + throw; + } + cerr << "-----------------End SalomePythonNode::outputs-----------------" << endl; + + Py_DECREF(result); + PyGILState_Release(gstate); + cerr << "++++++++++++++ End SalomePythonNode::execute: " << getName() << " ++++++++++++++++++++" << endl; +} + +std::string SalomePythonNode::getKind() const +{ + //This not a bug !!! Returns SalomeNode::KIND to be managed by SalomeContainer. + return SalomeNode::KIND; +} + +Node *SalomePythonNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new SalomePythonNode(*this,father); +} + +ServiceNode *SalomePythonNode::createNode(const std::string &name) +{ + ServiceNode* node=new SalomePythonNode(name); + node->setComponent(_component); + return node; +} + +//! Create a new node of same type with a given name +SalomePythonNode* SalomePythonNode::cloneNode(const std::string& name) +{ + SalomePythonNode* n=new SalomePythonNode(name); + n->setScript(_script); + n->setMethod(_method); + list::iterator iter; + for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++) + { + InputPyPort *p=(InputPyPort *)*iter; + n->edAddInputPort(p->getName(),p->edGetType()); + } + list::iterator iter2; + for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++) + { + OutputPyPort *p=(OutputPyPort *)*iter2; + n->edAddOutputPort(p->getName(),p->edGetType()); + } + return n; +} diff --git a/src/runtime/SalomePythonNode.hxx b/src/runtime/SalomePythonNode.hxx new file mode 100644 index 000000000..211a101d5 --- /dev/null +++ b/src/runtime/SalomePythonNode.hxx @@ -0,0 +1,37 @@ +#ifndef _SALOMEPYTHONNODE_HXX_ +#define _SALOMEPYTHONNODE_HXX_ + +#include "ServiceInlineNode.hxx" +#include + +namespace YACS +{ + namespace ENGINE + { + /*! + * This class is in charge to deal with python willing to interact with YACS placed container. + * Typical use is for nodes building GEOM and MESH. The great number of calls needed by this type of application, + * implies a human impossibility to make the corresponding graph. + */ + class SalomePythonNode : public ServiceInlineNode + { + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; + public: + SalomePythonNode(const SalomePythonNode& other, ComposedNode *father); + SalomePythonNode(const std::string& name); + virtual void execute(); + virtual void load(); + std::string getKind() const; + ServiceNode *createNode(const std::string &name); + SalomePythonNode* cloneNode(const std::string& name); + protected: + PyObject* _context; + PyObject* _pyfunc; + public: + static const char PLACEMENT_VAR_NAME_IN_INTERP[]; + }; + } +} + +#endif diff --git a/src/runtime/Test/Makefile.am b/src/runtime/Test/Makefile.am index 0a29ddbe8..51e84e94c 100644 --- a/src/runtime/Test/Makefile.am +++ b/src/runtime/Test/Makefile.am @@ -1,13 +1,13 @@ - include $(top_srcdir)/adm/unix/make_begin.am check_SCRIPTS = runtimeTest.sh -check_PROGRAMS = TestRuntime echoSrv +check_PROGRAMS = TestRuntime echoSrv echo_clt +lib_LTLIBRARIES = libTestComponentLocal.la IDL_FILES = echo.idl IDL_SOURCES = echoSK.cc -BUILT_SOURCES = $(IDL_SOURCES) echo_idl.py +BUILT_SOURCES = $(IDL_SOURCES) echo_idl.py xmlrun.sh TESTS = runtimeTest.sh TESTS_ENVIRONMENT=$(SHELL) -x @@ -26,27 +26,55 @@ TestRuntime_LDADD = \ TestRuntime_LDFLAGS = \ - @CPPUNIT_LIBS@ -pthread -ldl -lxml2 + @CPPUNIT_LIBS@ -pthread -ldl -lxml2 TestRuntime_CXXFLAGS = \ - $(CPPUNIT_INCLUDES) \ + -DUSE_CPPUNIT \ + $(CPPUNIT_INCLUDES) \ $(PYTHON_CPPFLAGS) \ $(OMNIORB_INCLUDES) \ - $(OMNIORB_CCXFLAGS) \ + $(OMNIORB_CXXFLAGS) \ + -I.. \ -I$(srcdir)/.. \ -I$(srcdir)/../../bases \ -I$(srcdir)/../../bases/Test \ -I$(srcdir)/../../engine \ - -I/usr/include/libxml2 + -I$(srcdir)/../../engine/Test \ + -I/usr/include/libxml2 \ + -DLOCATION="\"@prefix@\"" -DYACS_PTHREAD +xmlrun.sh:${srcdir}/xmlrun_orig.sh + cp $(srcdir)/xmlrun_orig.sh xmlrun.sh echoSrv_SOURCES = echoSrv.cxx $(IDL_SOURCES) echoSrv_CXXFLAGS = \ + -I$(srcdir)/../../bases \ $(OMNIORB_INCLUDES) \ $(OMNIORB_CXXFLAGS) echoSrv_LDFLAGS = \ $(OMNIORB_LIBS) +echo_clt_SOURCES = echo_clt.cxx $(IDL_SOURCES) + +echo_clt_CXXFLAGS = \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CXXFLAGS) + +echo_clt_LDFLAGS = \ + $(OMNIORB_LIBS) + +libTestComponentLocal_la_SOURCES = TestComponent.cxx + +libTestComponentLocal_la_CXXFLAGS = \ + -I.. \ + -I$(srcdir)/.. \ + -I$(srcdir)/../../bases \ + -I$(srcdir)/../../bases/Test \ + -I$(srcdir)/../../engine \ + -I$(srcdir)/../../engine/Test + +libTestComponentLocal_la_LDFLAGS = -module + include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/runtime/Test/TestComponent.cxx b/src/runtime/Test/TestComponent.cxx new file mode 100644 index 000000000..832d20eb3 --- /dev/null +++ b/src/runtime/Test/TestComponent.cxx @@ -0,0 +1,81 @@ + +#include "Any.hxx" +#include +#include +#include +#include "TestComponent.hxx" + + +extern "C" void * __init() +{ + TestComponent * obj = new TestComponent(); + obj->info.code = 0; + obj->info.message = ""; + return obj; +} + +extern "C" void __terminate(void **pObj) +{ + TestComponent * obj = * (TestComponent **) pObj; + delete obj; + *pObj = NULL; +} + +extern "C" void __ping() +{ + std::cerr << "ping TestComponent" << std::endl; +} + +extern "C" void __run(void *vObj, const char *service, int nIn, int nOut, + YACS::ENGINE::Any **In, YACS::ENGINE::Any **Out, returnInfo * r) +{ + TestComponent * obj = (TestComponent *) vObj; + + if (obj == NULL) { + r->code = -1; + r->message = "TestComponent has not been initialized"; + return; + } + + obj->info.message = ""; + obj->info.code = 0; + + if (std::strncmp(service, "f", 1) == 0) + { + double _arg0 = In[0]->getDoubleValue(); + double _res = obj->f(_arg0); + Out[0] = YACS::ENGINE::AtomAny::New(_res); + } + else + { + obj->info.code = 1; + obj->info.message = "service "; + obj->info.message += service; + obj->info.message += " doesn't exist in TestComponent"; + Out[0] = NULL; + } + *r = obj->info; +} + +double TestComponent::f(double x) +{ + double y; + + if (x >= 0.0) + { + y = std::sqrt(x); + } + else { + y = 0.0; + info.message = "TestComponent::f : argument must be positive or null"; + info.code = 2; + } + return y; +} + +double TestComponent::g(int n, double x) +{ + double y; + y = std::pow(x, n); + return y; +} diff --git a/src/runtime/Test/TestComponent.hxx b/src/runtime/Test/TestComponent.hxx new file mode 100644 index 000000000..1dd3a1a77 --- /dev/null +++ b/src/runtime/Test/TestComponent.hxx @@ -0,0 +1,28 @@ +#ifndef TESTCOMPONENT_HXX_ +#define TESTCOMPONENT_HXX_ + + +#include "Any.hxx" +#include + +struct returnInfo { + int code; + std::string message; +}; + +class TestComponent { + +public : + + double f(double c); + double g(int n, double x); + returnInfo info; +}; + +extern "C" void * __init(); +extern "C" void __terminate(void **pObj); +extern "C" void __ping(); +extern "C" void __run(void *vObj, const char *service, int nIn, int nOut, + YACS::ENGINE::Any **In, YACS::ENGINE::Any **Out, returnInfo *r); + +#endif /*TESTCOMPONENT_HXX_*/ diff --git a/src/runtime/Test/TestRuntime.cxx b/src/runtime/Test/TestRuntime.cxx index c3de92282..9e85942c0 100644 --- a/src/runtime/Test/TestRuntime.cxx +++ b/src/runtime/Test/TestRuntime.cxx @@ -1,4 +1,6 @@ +#define UNIT_TEST_HEADER " --- TEST src/runtime" + #include "runtimeTest.hxx" using namespace YACS; diff --git a/src/runtime/Test/TestStandAlone.cxx b/src/runtime/Test/TestStandAlone.cxx new file mode 100644 index 000000000..ae5089545 --- /dev/null +++ b/src/runtime/Test/TestStandAlone.cxx @@ -0,0 +1,38 @@ +#ifdef USE_CPPUNIT +#undef USE_CPPUNIT +#endif + +#include "runtimeTest.hxx" + +int main() +{ + YACS::RuntimeTest T; + T.setUp(); + T.initRuntimeTypeCode(); + T.createPythonNodes(); + T.createCORBANodes(); + T.createBloc(); + T.createRecursiveBlocs(); + T.createDataLinks(); + T.createPythonNodesWithScript(); + T.createCORBANodesWithMethod(); + T.createXMLNodes(); + T.createBloc2(); + T.createDataLinksPythonPython(); + /* + T.createDataLinksPythonCORBA(); + T.createDataLinksCORBACORBA(); + T.createDataLinksCORBAPython(); + T.createDataLinksXML(); + T.manualInitInputPort(); + T.manualExecuteNoThread(); + T.manualGetOutputs(); + T.createCppNodes(); + T.convertPorts(); + T.executeCppNode(); + T.createGraphWithCppNodes(); + T.classTeardown(); +*/ + return 0; +} + diff --git a/src/runtime/Test/echo.idl b/src/runtime/Test/echo.idl index dacf1c44c..ca9276c10 100644 --- a/src/runtime/Test/echo.idl +++ b/src/runtime/Test/echo.idl @@ -55,6 +55,9 @@ module eo{ 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 echoObj2(in Obj i,out Obj j) ; + void echoD(in D i,out D j) ; + void echoC(in C i,out C 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); diff --git a/src/runtime/Test/echoSrv.cxx b/src/runtime/Test/echoSrv.cxx index f7fdda4fb..c343ebb54 100644 --- a/src/runtime/Test/echoSrv.cxx +++ b/src/runtime/Test/echoSrv.cxx @@ -5,7 +5,10 @@ #include using namespace std; -static CORBA::Boolean bindObjectToName(CORBA::ORB_ptr, CORBA::Object_ptr); +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +static CORBA::Boolean bindObjectToName(CORBA::ORB_ptr, CORBA::Object_ptr,const char*); static ostream& operator<<(ostream& os, const CORBA::Exception& e) { @@ -43,6 +46,7 @@ class D_i : public POA_eo::D, public PortableServer::RefCountServantBase public: inline D_i() {} virtual ~D_i() {} + CORBA::Long echoLong(CORBA::Long i); CORBA::Long echoLong2(CORBA::Long i); }; @@ -56,7 +60,7 @@ public: }; class Echo_i : public POA_eo::Echo, - public PortableServer::RefCountServantBase + public PortableServer::RefCountServantBase { public: inline Echo_i() {} @@ -69,6 +73,9 @@ public: 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 echoObj2(eo::Obj_ptr , eo::Obj_out); + void echoD(eo::D_ptr , eo::D_out); + void echoC(eo::C_ptr , eo::C_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); @@ -93,48 +100,48 @@ PortableServer::POA_ptr Echo_i::_default_POA() char* Echo_i::echoString(const char* mesg) { - cout << "Echo_i::echoString " << mesg << endl; + DEBTRACE("Echo_i::echoString " << mesg); return CORBA::string_dup(mesg); } void Echo_i::echoDouble(CORBA::Double i,CORBA::Double& j ) { - cout << "Echo_i::echoDouble " << i << endl; + DEBTRACE("Echo_i::echoDouble " << i); j=i+1; } void Echo_i::echoIntVec(const eo::IntVec& in, eo::IntVec_out out) { - cout << "Echo_i::echoIntVec " << in.length() << endl; + DEBTRACE("Echo_i::echoIntVec " << in.length()); for(int i=0;i_PD_repoId << endl; + DEBTRACE(in[i]->_PD_repoId); }; out=new eo::ObjectVec(in); } void Echo_i::echoObjectVecVec(const eo::ObjectVecVec& in, eo::ObjectVecVec_out out) { - cout << "Echo_i::echoObjectVecVec " << in.length() << endl; + DEBTRACE("Echo_i::echoObjectVecVec " << in.length()); for(int i=0;i< in.length(); i++){ for(int j=0;j< in[i].length(); j++){ - cout << in[i][j]->_PD_repoId << endl; + DEBTRACE(in[i][j]->_PD_repoId); }; }; out=new eo::ObjectVecVec(in); @@ -142,19 +149,19 @@ void Echo_i::echoObjectVecVec(const eo::ObjectVecVec& in, eo::ObjectVecVec_out o void Echo_i::echoDoubleVec(const eo::DoubleVec& in,eo::DoubleVec_out out ) { - cout << "Echo_i::echoDoubleVec " << in.length() << endl; + DEBTRACE("Echo_i::echoDoubleVec " << in.length()); for(int i=0;iechoLong(10); + oo=eo::C::_duplicate(o); +} + +void Echo_i::echoD(eo::D_ptr o,eo::D_out oo){ + DEBTRACE("Echo_i::echoD "); + o->echoLong2(10); + //oo=eo::D::_duplicate(o); + D_i* myD = new D_i(); + oo=myD->_this(); + myD->_remove_ref(); +} + +void Echo_i::echoObj2(eo::Obj_ptr o,eo::Obj_out oo){ + DEBTRACE("Echo_i::echoObj2 "); + o->echoLong(10); + oo=eo::Obj::_duplicate(o); +} + eo::Obj_ptr Echo_i::echoObj(CORBA::Long i ,eo::Obj_ptr o,CORBA::Long j,eo::Obj_out oo){ - cout << "Echo_i::echoObj " << i << "," << j << endl; + DEBTRACE("Echo_i::echoObj " << i << "," << j ); oo=eo::Obj::_duplicate(o); return eo::Obj::_duplicate(o); } void Echo_i::createObj(CORBA::Long i ,eo::Obj_out oo){ - cout << "Echo_i::createObj " << i << endl; + DEBTRACE("Echo_i::createObj " << i); Obj_i* myobj = new Obj_i(); CORBA::Object_var myref = myobj->_this(); oo = eo::Obj::_narrow(myref); @@ -189,7 +217,7 @@ void Echo_i::createObj(CORBA::Long i ,eo::Obj_out oo){ } void Echo_i::createC(eo::C_out oo){ - cout << "Echo_i::createC " << endl; + DEBTRACE("Echo_i::createC "); C_i* myobj = new C_i(); CORBA::Object_var myref = myobj->_this(); oo = eo::C::_narrow(myref); @@ -198,7 +226,7 @@ void Echo_i::createC(eo::C_out oo){ 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; + DEBTRACE("Echo_i::echoAll " << d << "," << l << "," << m); dd=d; ll=l; s=CORBA::string_dup(m); @@ -207,33 +235,38 @@ void Echo_i::echoAll(CORBA::Double d,CORBA::Long l,const char * m,eo::Obj_ptr o, //Implementation Obj CORBA::Long Obj_i::echoLong(CORBA::Long i ){ - cout << "Obj_i::echoLong " << i << endl; + DEBTRACE("Obj_i::echoLong " << i ); CORBA::Long j=i+1; return j; } //Implementation C CORBA::Long C_i::echoLong(CORBA::Long i ){ - cout << "C_i::echoLong " << i << endl; + DEBTRACE("C_i::echoLong " << i); CORBA::Long j=i+5; return j; } //Implementation D CORBA::Long D_i::echoLong2(CORBA::Long i ){ - cout << "D_i::echoLong " << i << endl; + DEBTRACE("D_i::echoLong " << i); CORBA::Long j=i+10; return j; } +CORBA::Long D_i::echoLong(CORBA::Long i ){ + DEBTRACE("D_i::echoLong " << i); + CORBA::Long j=i+1; + return j; +} //Implementation E CORBA::Long E_i::echoLong2(CORBA::Long i ){ - cout << "E_i::echoLong " << i << endl; + DEBTRACE("E_i::echoLong " << i); CORBA::Long j=i+20; return j; } CORBA::Long E_i::echoLong(CORBA::Long i ){ - cout << "E_i::echoLong " << i << endl; + DEBTRACE("E_i::echoLong " << i); CORBA::Long j=i+15; return j; } @@ -268,33 +301,53 @@ int main(int argc, char** argv) // stringified IOR. obj = myecho->_this(); CORBA::String_var sior(orb->object_to_string(obj)); - cerr << "'" << (char*)sior << "'" << endl; + DEBTRACE("'" << (char*)sior << "'"); myechoref = eo::Echo::_narrow(obj); - if( !bindObjectToName(orb, myechoref) ) - return 1; + if( !bindObjectToName(orb, myechoref,"Echo") ) 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(); + + //create object C and register it in naming service + C_i* myC = new C_i(); + obj=myC->_this(); + eo::C_var myCref=eo::C::_narrow(obj); + myC->_remove_ref(); + if( !bindObjectToName(orb, myCref,"C") ) return 1; + + //create object D and register it in naming service + D_i* myD = new D_i(); + obj=myD->_this(); + eo::D_var myDref=eo::D::_narrow(obj); + myD->_remove_ref(); + if( !bindObjectToName(orb, myDref,"D") ) return 1; + + //create object Obj and register it in naming service + Obj_i* myObj = new Obj_i(); + obj=myObj->_this(); + eo::Obj_var myObjref=eo::Obj::_narrow(obj); + myObj->_remove_ref(); + if( !bindObjectToName(orb, myObjref,"Obj") ) return 1; } orb->run(); } catch(CORBA::SystemException&) { - cerr << "Caught CORBA::SystemException." << endl; + DEBTRACE("Caught CORBA::SystemException."); } catch(CORBA::Exception& ex) { - cerr << "Caught CORBA::Exception." << ex << endl; + DEBTRACE("Caught CORBA::Exception." << ex); } catch(omniORB::fatalException& fe) { - cerr << "Caught omniORB::fatalException:" << endl; - cerr << " file: " << fe.file() << endl; - cerr << " line: " << fe.line() << endl; - cerr << " mesg: " << fe.errmsg() << endl; + DEBTRACE("Caught omniORB::fatalException:"); + DEBTRACE(" file: " << fe.file()); + DEBTRACE(" line: " << fe.line()); + DEBTRACE(" mesg: " << fe.errmsg()); } catch(...) { - cerr << "Caught unknown exception." << endl; + DEBTRACE("Caught unknown exception." ); } return 0; @@ -304,7 +357,7 @@ int main(int argc, char** argv) ////////////////////////////////////////////////////////////////////// static CORBA::Boolean -bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref) +bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref,const char *name) { CosNaming::NamingContext_var rootContext; @@ -316,13 +369,13 @@ bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref) // Narrow the reference returned. rootContext = CosNaming::NamingContext::_narrow(obj); if( CORBA::is_nil(rootContext) ) { - cerr << "Failed to narrow the root naming context." << endl; + DEBTRACE("Failed to narrow the root naming context."); return 0; } } catch(CORBA::ORB::InvalidName& ex) { // This should not happen! - cerr << "Service required is invalid [does not exist]." << endl; + DEBTRACE("Service required is invalid [does not exist]." ); return 0; } @@ -350,7 +403,7 @@ bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref) obj = rootContext->resolve(contextName); testContext = CosNaming::NamingContext::_narrow(obj); if( CORBA::is_nil(testContext) ) { - cerr << "Failed to narrow naming context." << endl; + DEBTRACE("Failed to narrow naming context."); return 0; } } @@ -358,7 +411,7 @@ bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref) // Bind objref with name Echo to the testContext: CosNaming::Name objectName; objectName.length(1); - objectName[0].id = (const char*) "Echo"; // string copied + objectName[0].id = name; // string copied objectName[0].kind = (const char*) "Object"; // string copied try { @@ -379,13 +432,12 @@ bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref) // it should just bind]. } catch(CORBA::COMM_FAILURE& ex) { - cerr << "Caught system exception COMM_FAILURE -- unable to contact the " - << "naming service." << endl; + DEBTRACE("Caught system exception COMM_FAILURE -- unable to contact the " + << "naming service."); return 0; } catch(CORBA::SystemException&) { - cerr << "Caught a CORBA::SystemException while using the naming service." - << endl; + DEBTRACE("Caught a CORBA::SystemException while using the naming service."); return 0; } diff --git a/src/runtime/Test/echo_clt.cxx b/src/runtime/Test/echo_clt.cxx new file mode 100644 index 000000000..cdc5cfb1c --- /dev/null +++ b/src/runtime/Test/echo_clt.cxx @@ -0,0 +1,75 @@ +#include +#include + +int main(int argc, char** argv) +{ + try { + CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); + CORBA::Object_var obj = orb->string_to_object("corbaname:rir:#test.my_context/Echo.Object"); + eo::Echo_var echoref = eo::Echo::_narrow(obj); + if( CORBA::is_nil(echoref) ) { + std::cerr << "Can't narrow reference to type Echo (or it was nil)." << std::endl; + return 1; + } + + CORBA::String_var src = (const char*) "Hello!"; + CORBA::String_var dest = echoref->echoString(src); + std::cerr << "I said, \"" << (char*)src << "\"." << std::endl + << "The Echo object replied, \"" << (char*)dest <<"\"." << std::endl; + + CORBA::Object_var ob = orb->string_to_object("corbaname:rir:#test.my_context/D.Object"); + eo::D_var Dref = eo::D::_narrow(ob); + if( CORBA::is_nil(Dref) ) { + std::cerr << "Can't narrow reference to type D (or it was nil)." << std::endl; + return 1; + } + Dref->echoLong2(10); + + eo::D_var dout; + echoref->echoD(Dref,dout); + std::cerr << dout->echoLong2(10) << std::endl; + + eo::D_var ddout; + echoref->echoD(dout,ddout); + std::cerr << dout->echoLong2(10) << std::endl; + + CORBA::Object_var oob = orb->string_to_object("corbaname:rir:#test.my_context/Obj.Object"); + eo::Obj_var Objref = eo::Obj::_narrow(oob); + Objref->echoLong(10); + eo::Obj_var Objout; + echoref->echoObj2(Objref,Objout); + std::cerr << Objout->echoLong(10) << std::endl; + + CORBA::Object_var cob = orb->string_to_object("corbaname:rir:#test.my_context/C.Object"); + eo::C_var Cref = eo::C::_narrow(cob); + eo::C_var Cout; + echoref->echoC(Cref,Cout); + + echoref->echoObj2(Cref,Objout); + //echoref->echoC(Cref,Objout); compilation impossible + //echoref->echoObj2(Cref,Cout); compilation impossible + //echoref->echoC(Objref,Cout); compilation impossible + + orb->destroy(); + } + catch(CORBA::COMM_FAILURE& ex) { + std::cerr << "Caught system exception COMM_FAILURE -- unable to contact the " + << "object." << std::endl; + } + catch(CORBA::SystemException&) { + std::cerr << "Caught a CORBA::SystemException." << std::endl; + } + catch(CORBA::Exception&) { + std::cerr << "Caught CORBA::Exception." << std::endl; + } + catch(omniORB::fatalException& fe) { + std::cerr << "Caught omniORB::fatalException:" << std::endl; + std::cerr << " file: " << fe.file() << std::endl; + std::cerr << " line: " << fe.line() << std::endl; + std::cerr << " mesg: " << fe.errmsg() << std::endl; + } + catch(...) { + std::cerr << "Caught unknown exception." << std::endl; + } + return 0; +} diff --git a/src/runtime/Test/runtimeTest.cxx b/src/runtime/Test/runtimeTest.cxx index b780fd169..46844d343 100644 --- a/src/runtime/Test/runtimeTest.cxx +++ b/src/runtime/Test/runtimeTest.cxx @@ -1,175 +1,209 @@ // --- include from engine first, to avoid redifinition warning _POSIX_C_SOURCE +#include "TypeConversions.hxx" #include "Bloc.hxx" #include "ElementaryNode.hxx" #include "Loop.hxx" +#include "ForLoop.hxx" #include "Switch.hxx" -#include "RuntimeSALOME.hxx" #include "CppNode.hxx" #include "PythonNode.hxx" -#include "CORBANode.hxx" +#include "InlineNode.hxx" +#include "ServiceNode.hxx" #include "XMLNode.hxx" -#include "TypeConversions.hxx" -#include "CORBACORBAConv.hxx" -#include "PythonCORBAConv.hxx" -#include "CORBAPythonConv.hxx" -#include "CORBAXMLConv.hxx" +#include "PythonPorts.hxx" +#include "XMLPorts.hxx" +#include "CORBAPorts.hxx" +#include "CppPorts.hxx" +#include "CppComponent.hxx" +#include "Executor.hxx" #include "runtimeTest.hxx" -#include - #include #include #include #include #include #include +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" 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< RuntimeTest::_ltc; +TypeCode *RuntimeTest::_tc_C; +TypeCode *RuntimeTest::_tc_seqC; + +map RuntimeTest::_nodeMap; +map RuntimeTest::_blocMap; +int RuntimeTest::_inode = 0; +int RuntimeTest::_ibloc = 0; +Runtime *RuntimeTest::_myRuntime = 0; +bool RuntimeTest::endTests = false; void RuntimeTest::setUp() { + if (_ltc.size() == 0) + { + _ltc.push_back((TypeCodeObjref *)_tc_obj); + _tc_C = TypeCode::interfaceTc("eo:C","C",_ltc); + _tc_seqC = TypeCode::sequenceTc("eo:seqC","seqC",_tc_C); + } } + +#define cRef(x) cerr << "_tc" << #x << " : " << _tc ## x->getRefCnt() << endl + void RuntimeTest::tearDown() { } -void RuntimeTest::test1() + +void RuntimeTest::initRuntimeTypeCode() { // --- init runtime - + std::cerr << std::endl; RuntimeSALOME::setRuntime(); - - Runtime *myRuntime = getRuntime(); + _myRuntime = getRuntime(); // --- init typecodes - TypeCode *tc_double = new TypeCode(Double); - TypeCode *tc_int = new TypeCode(Int); - TypeCode *tc_string = new TypeCode(String); - TypeCode *tc = TypeCode::interface_tc("id","name"); - TypeCode *tc_obj = TypeCode::interface_tc("eo:Obj","Obj"); - DEBTRACE( " " << tc->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; + DEBTRACE( " " << _tc->id() << " " << _tc->name() ); + DEBTRACE("int is a int: "); CPPUNIT_ASSERT( _tc_int->isA(_tc_int)); + DEBTRACE("seqdble is not a seqlong: "); CPPUNIT_ASSERT(!_tc_seqdble->isA(_tc_seqlong)); + DEBTRACE("seqdble is a seqdble: "); CPPUNIT_ASSERT( _tc_seqdble->isA(_tc_seqdble)); + DEBTRACE("seqlong is not a seqdble: "); CPPUNIT_ASSERT(!_tc_seqlong->isA(_tc_seqdble)); + DEBTRACE("C is a Obj: "); CPPUNIT_ASSERT( _tc_C->isA(_tc_obj)); + DEBTRACE("Obj is not a C: " ); CPPUNIT_ASSERT(!_tc_obj->isA(_tc_C)); + DEBTRACE("seqC is a seqObj: "); CPPUNIT_ASSERT( _tc_seqC->isA(_tc_seqobj)); + DEBTRACE( "seqObj is not a seqC: "); CPPUNIT_ASSERT(!_tc_seqobj->isA(_tc_seqC)); +} +void RuntimeTest::createPythonNodes() +{ // --- Nodes 0 a 4 : Python for (int i=0; i<5; i++) { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createScriptNode("",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); + CPPUNIT_ASSERT_EQUAL(node->getImplementation(),string("Python")); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfInputPorts(),11); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfOutputPorts(),11); + CPPUNIT_ASSERT_EQUAL(node->getInPortName(i10),string("iC10")); + CPPUNIT_ASSERT_EQUAL(node->getOutPortName(o10),string("oC10")); + CPPUNIT_ASSERT_EQUAL(node->getInputPort("iC10"),i10); + CPPUNIT_ASSERT_EQUAL(node->getOutputPort("oC10"),o10); } +} + +void RuntimeTest::createCORBANodes() +{ // --- Nodes 5 a 9 : CORBA for (int i=5; i<10; i++) { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",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); + CPPUNIT_ASSERT_EQUAL(node->getImplementation(),string("CORBA")); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfInputPorts(),11); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfOutputPorts(),11); + CPPUNIT_ASSERT_EQUAL(node->getInPortName(i10),string("iC10")); + CPPUNIT_ASSERT_EQUAL(node->getOutPortName(o10),string("oC10")); + CPPUNIT_ASSERT_EQUAL(node->getInputPort("iC10"),i10); + CPPUNIT_ASSERT_EQUAL(node->getOutputPort("oC10"),o10); } +} - DEBTRACE(" --- create bloc, add two nodes, check constituants" ); - map blocMap; - int ibloc = 0; +void RuntimeTest::createBloc() +{ + DEBTRACE(" --- create bloc, add two nodes, check constituants" ); // --- Bloc_0 with Node_0 and Node_1 { ostringstream ss; - ss << "Bloc_" << ibloc++; + 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"]); + _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); @@ -179,218 +213,260 @@ void RuntimeTest::test1() // --- Bloc_1 with Node_2 { ostringstream ss; - ss << "Bloc_" << ibloc++; + ss << "Bloc_" << _ibloc++; string s = ss.str(); Bloc* bloc = new Bloc(s); - nodeMap[s] = bloc; - blocMap[s] = bloc; - bloc->edAddChild(nodeMap["Node_2"]); + _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"])); + 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); + CPPUNIT_ASSERT_THROW(_blocMap["Bloc_1"]->edAddChild(_nodeMap["Node_1"]), + YACS::Exception); +} +void RuntimeTest::createRecursiveBlocs() +{ DEBTRACE(" --- recursive blocs, check constituants" ); // --- Bloc_2 with Bloc_1 and Bloc_2 { ostringstream ss; - ss << "Bloc_" << ibloc++; + 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 + _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(); + 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(" elem name = " << (*it)->getName()); } } +} +void RuntimeTest::createDataLinks() +{ 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); + 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"]->edAddLink(_nodeMap["Node_0"]->getOutputPort("oi2"), + _nodeMap["Node_1"]->getInputPort("ii2")); + CPPUNIT_ASSERT(_blocMap["Bloc_0"]->getNumberOfInputPorts() == 22); - blocMap["Bloc_0"]->edRemoveLink(nodeMap["Node_0"]->getOutputPort("oi2"), - nodeMap["Node_1"]->getInputPort("ii2")); - CPPUNIT_ASSERT(blocMap["Bloc_0"]->getNumberOfInputPorts() == 22); + _blocMap["Bloc_0"]->edRemoveLink(_nodeMap["Node_0"]->getOutputPort("oi2"), + _nodeMap["Node_1"]->getInputPort("ii2")); + CPPUNIT_ASSERT(_blocMap["Bloc_0"]->getNumberOfInputPorts() == 22); +} +void RuntimeTest::createPythonNodesWithScript() +{ DEBTRACE(" --- create python nodes with scripts" ); // --- Node 10 : Python { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createScriptNode("",s); + _nodeMap[s] = node; + ((InlineNode*) node)->setScript("a=a+1\n"); + InputPort *i1 = node->edAddInputPort("a", _tc_double); + OutputPort *o1 = node->edAddOutputPort("a", _tc_double); + CPPUNIT_ASSERT_EQUAL(node->getImplementation(),string("Python")); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfInputPorts(),1); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfOutputPorts(),1); } // --- Node 11 : Python { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createScriptNode("",s); + _nodeMap[s] = node; + ((InlineNode*) node)->setScript("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++; + 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); + ElementaryNode* node = _myRuntime->createScriptNode("",s); + _nodeMap[s] = node; + ((InlineNode*) node)->setScript("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++; + 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); + ElementaryNode* node = _myRuntime->createScriptNode("",s); + _nodeMap[s] = node; + ((InlineNode*) node)->setScript("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); + CPPUNIT_ASSERT_EQUAL(((InputPyPort *)i1)->getPyObj(), Py_None); + CPPUNIT_ASSERT_EQUAL(((InputPyPort *)i2)->getPyObj(), Py_None); + CPPUNIT_ASSERT_EQUAL(((InputPyPort *)i3)->getPyObj(), Py_None); + CPPUNIT_ASSERT_EQUAL(((InputPyPort *)i4)->getPyObj(), Py_None); + CPPUNIT_ASSERT_EQUAL(((OutputPyPort *)o1)->get(), Py_None); + CPPUNIT_ASSERT_EQUAL(((OutputPyPort *)o2)->get(), Py_None); + CPPUNIT_ASSERT_EQUAL(((OutputPyPort *)o3)->get(), Py_None); + CPPUNIT_ASSERT_EQUAL(((OutputPyPort *)o4)->get(), Py_None); + CPPUNIT_ASSERT_EQUAL(((OutputPyPort *)o5)->get(), Py_None); + CPPUNIT_ASSERT_EQUAL(((OutputPyPort *)o6)->get(), Py_None); + CPPUNIT_ASSERT_EQUAL(((OutputPyPort *)o7)->get(), Py_None); } // --- Node 14 : Python { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createScriptNode("",s); + _nodeMap[s] = node; + ((InlineNode*) node)->setScript("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); + CPPUNIT_ASSERT_EQUAL(((InputPyPort *)i1)->getPyObj(), Py_None); + CPPUNIT_ASSERT_EQUAL(((InputPyPort *)i2)->getPyObj(), Py_None); + CPPUNIT_ASSERT_EQUAL(((InputPyPort *)i3)->getPyObj(), Py_None); + CPPUNIT_ASSERT_EQUAL(((InputPyPort *)i4)->getPyObj(), Py_None); + CPPUNIT_ASSERT_EQUAL(((InputPyPort *)i5)->getPyObj(), Py_None); + CPPUNIT_ASSERT_EQUAL(((InputPyPort *)i6)->getPyObj(), Py_None); + CPPUNIT_ASSERT_EQUAL(((OutputPyPort *)o1)->get(), Py_None); + CPPUNIT_ASSERT_EQUAL(((OutputPyPort *)o2)->get(), Py_None); } // --- Node 15 : Python { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createScriptNode("",s); + _nodeMap[s] = node; + ((InlineNode*) node)->setScript("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); + CPPUNIT_ASSERT_EQUAL(node->getImplementation(),string("Python")); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfInputPorts(),4); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfOutputPorts(),1); } +} +void RuntimeTest::createCORBANodesWithMethod() +{ DEBTRACE(" --- create CORBA nodes" ); // --- Node 16 : CORBA { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("echoDouble"); + InputPort *i1 = node->edAddInputPort("a", _tc_double); + OutputPort *o1 = node->edAddOutputPort("c", _tc_double); + CPPUNIT_ASSERT_EQUAL(node->getImplementation(),string("CORBA")); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfInputPorts(),1); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfOutputPorts(),1); + CPPUNIT_ASSERT_EQUAL(((InputCorbaPort *)i1)->getAny()->type()->kind(),CORBA::tk_null); + CPPUNIT_ASSERT_EQUAL(((OutputCorbaPort *)o1)->getAny()->type()->kind(),CORBA::tk_null); } // --- Node 17 - 18 : CORBA @@ -398,28 +474,30 @@ void RuntimeTest::test1() for (int i =0; i <2; i++) { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("echoDouble"); + InputPort *i1 = node->edAddInputPort("b", _tc_double); + OutputPort *o1 = node->edAddOutputPort("c", _tc_double); } // --- Node 19 : CORBA { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("createObj"); + InputPort *i1 = node->edAddInputPort("long", _tc_int); + OutputPort *o1 = node->edAddOutputPort("obj", _tc_obj); + CPPUNIT_ASSERT_EQUAL(((InputCorbaPort *)i1)->getAny()->type()->kind(),CORBA::tk_null); + CPPUNIT_ASSERT_EQUAL(((OutputCorbaPort *)o1)->getAny()->type()->kind(),CORBA::tk_null); } // --- Node 20, 21, 22 : CORBA @@ -427,20 +505,24 @@ void RuntimeTest::test1() for (int i =0; i <3; i++) { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("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); + CPPUNIT_ASSERT_EQUAL(((InputCorbaPort *)i3)->getAny()->type()->kind(),CORBA::tk_null); + CPPUNIT_ASSERT_EQUAL(((InputCorbaPort *)i4)->getAny()->type()->kind(),CORBA::tk_null); + CPPUNIT_ASSERT_EQUAL(((OutputCorbaPort *)o3)->getAny()->type()->kind(),CORBA::tk_null); + CPPUNIT_ASSERT_EQUAL(((OutputCorbaPort *)o4)->getAny()->type()->kind(),CORBA::tk_null); } // --- Node 23 a 26 : CORBA @@ -448,524 +530,1074 @@ void RuntimeTest::test1() for (int i =0; i <4; i++) { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("echoDoubleVec"); + InputPort *i1 = node->edAddInputPort("dblevec", _tc_seqdble); + OutputPort *o1 = node->edAddOutputPort("dblevec", _tc_seqdble); + CPPUNIT_ASSERT_EQUAL(((InputCorbaPort *)i1)->getAny()->type()->kind(),CORBA::tk_null); + CPPUNIT_ASSERT_EQUAL(((OutputCorbaPort *)o1)->getAny()->type()->kind(),CORBA::tk_null); } // --- Node 27 : CORBA { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("echoStrVec"); + InputPort *i1 = node->edAddInputPort("strvec", _tc_seqstr); + OutputPort *o1 = node->edAddOutputPort("strvec", _tc_seqstr); + CPPUNIT_ASSERT_EQUAL(((InputCorbaPort *)i1)->getAny()->type()->kind(),CORBA::tk_null); + CPPUNIT_ASSERT_EQUAL(((OutputCorbaPort *)o1)->getAny()->type()->kind(),CORBA::tk_null); } // --- Node 28 : CORBA { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("echoObjectVec"); + InputPort *i1 = node->edAddInputPort("objvec", _tc_seqobj); + OutputPort *o1 = node->edAddOutputPort("objvec", _tc_seqobj); + CPPUNIT_ASSERT_EQUAL(((InputCorbaPort *)i1)->getAny()->type()->kind(),CORBA::tk_null); + CPPUNIT_ASSERT_EQUAL(((OutputCorbaPort *)o1)->getAny()->type()->kind(),CORBA::tk_null); } // --- Node 29 : CORBA { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("echoDoubleVecVec"); + InputPort *i1 = node->edAddInputPort("dblevecvec", _tc_seqseqdble); + OutputPort *o1 = node->edAddOutputPort("dblevecvec", _tc_seqseqdble); + CPPUNIT_ASSERT_EQUAL(((InputCorbaPort *)i1)->getAny()->type()->kind(),CORBA::tk_null); + CPPUNIT_ASSERT_EQUAL(((OutputCorbaPort *)o1)->getAny()->type()->kind(),CORBA::tk_null); } // --- Node 30 : CORBA { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("echoObjectVecVec"); + InputPort *i1 = node->edAddInputPort("objvecvec", _tc_seqseqobj); + OutputPort *o1 = node->edAddOutputPort("objvecvec", _tc_seqseqobj); + CPPUNIT_ASSERT_EQUAL(((InputCorbaPort *)i1)->getAny()->type()->kind(),CORBA::tk_null); + CPPUNIT_ASSERT_EQUAL(((OutputCorbaPort *)o1)->getAny()->type()->kind(),CORBA::tk_null); } // --- Node 31 : CORBA { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("echoIntVec"); + InputPort *i1 = node->edAddInputPort("lngvec", _tc_seqlong); + OutputPort *o1 = node->edAddOutputPort("lngvec", _tc_seqlong); + CPPUNIT_ASSERT_EQUAL(((InputCorbaPort *)i1)->getAny()->type()->kind(),CORBA::tk_null); + CPPUNIT_ASSERT_EQUAL(((OutputCorbaPort *)o1)->getAny()->type()->kind(),CORBA::tk_null); } // --- Node 32 : CORBA { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("createC"); + OutputPort *o1 = node->edAddOutputPort("objc", _tc_C); + CPPUNIT_ASSERT_EQUAL(((OutputCorbaPort *)o1)->getAny()->type()->kind(),CORBA::tk_null); } // --- Node 33 : CORBA { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("echoDouble"); + InputPort *i1 = node->edAddInputPort("dble", _tc_double); + OutputPort *o1 = node->edAddOutputPort("dble", _tc_double); } // --- Node 34 : CORBA { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("echoDoubleVec"); + InputPort *i1 = node->edAddInputPort("dblevec", _tc_seqdble); + OutputPort *o1 = node->edAddOutputPort("dblevec", _tc_seqdble); } // --- Node 35 : CORBA { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("corbaname:rir:#test.my_context/Echo.Object"); + ((ServiceNode *) node)->setMethod("echoDoubleVecVec"); + InputPort *i1 = node->edAddInputPort("dblevecvec", _tc_seqseqdble); + OutputPort *o1 = node->edAddOutputPort("dblevecvec", _tc_seqseqdble); } +} + +void RuntimeTest::createXMLNodes() +{ DEBTRACE(" --- create XML nodes" ); // --- Node 36 : XML { ostringstream ss; - ss << "Node_" << inode++; + 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); + ElementaryNode* node = _myRuntime->createRefNode("xmlsh",s); + _nodeMap[s] = node; + ((ServiceNode *) node)->setRef("./xmlrun.sh"); + ((ServiceNode *) node)->setMethod("echo"); + 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); + CPPUNIT_ASSERT_EQUAL(node->getImplementation(),string("XML")); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfInputPorts(),3); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfOutputPorts(),3); } +} + +void RuntimeTest::createBloc2() +{ DEBTRACE(" --- create Bloc with all nodes" ); // --- Bloc_3 with Node_10 and following { ostringstream ss; - ss << "Bloc_" << ibloc++; + 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]); + ostringstream ssn; + ssn << "Node_" << i; + string sn = ssn.str(); + cerr << sn << endl; + bloc->edAddChild(_nodeMap[sn]); } + { + set setelem = bloc->getRecursiveConstituents(); + CPPUNIT_ASSERT(setelem.size() == _inode - 10); + } } + set unitialized = _blocMap["Bloc_3"]->edGetSetOfUnitializedInputPort(); + DEBTRACE(unitialized.size()); + CPPUNIT_ASSERT(! _blocMap["Bloc_3"]->edAreAllInputPortInitialized() ); +} + +void RuntimeTest::createDataLinksPythonPython() +{ 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_11"]->getInputPort("b")); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_10"]->getOutputPort("a"), - nodeMap["Node_12"]->getInputPort("dble")); + _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 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 C (derived from Obj) -> Python obj Obj : accepted + _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); + // --- Python Obj -> Python C (derived from Obj) : forbidden + 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("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); +} - CPPUNIT_ASSERT_THROW(blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("seqdble"), - nodeMap["Node_12"]->getInputPort("dble")), - YACS::ENGINE::ConversionException); +void RuntimeTest::createDataLinksPythonCORBA() +{ DEBTRACE(" --- create data links, python to CORBA" ); - // double->double - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("c"), - nodeMap["Node_16"]->getInputPort("a")); + // --- 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")); + // --- 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")); + // --- str->str + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_11"]->getOutputPort("s"), + _nodeMap["Node_20"]->getInputPort("str")); + cerr << "##### 3" << endl; - // 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_23"]->getInputPort("dblevec")); - // seq -> seq - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_11"]->getOutputPort("lngvec"), - nodeMap["Node_31"]->getInputPort("lngvec")); + // --- 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_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_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("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_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_11"]->getOutputPort("dblevecvec"), + _nodeMap["Node_29"]->getInputPort("dblevecvec")); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_13"]->getOutputPort("seqseqobj"), - nodeMap["Node_30"]->getInputPort("objvecvec")); + _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_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("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("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("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_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_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_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); + CPPUNIT_ASSERT_THROW(_blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_13"]->getOutputPort("seqstr"), + _nodeMap["Node_24"]->getInputPort("dblevec")), + YACS::ENGINE::ConversionException); +} + +void RuntimeTest::createDataLinksCORBACORBA() +{ DEBTRACE(" --- create data links, CORBA to CORBA" ); // double->double - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_16"]->getOutputPort("c"), - nodeMap["Node_17"]->getInputPort("b")); + _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_16"]->getOutputPort("c"), + _nodeMap["Node_18"]->getInputPort("b")); + + CPPUNIT_ASSERT_THROW(_blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_19"]->getOutputPort("obj"), + _nodeMap["Node_21"]->getInputPort("double")), + YACS::ENGINE::ConversionException); + + CPPUNIT_ASSERT_THROW(_blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_23"]->getOutputPort("dblevec"), + _nodeMap["Node_31"]->getInputPort("lngvec")), + YACS::ENGINE::ConversionException); + + CPPUNIT_ASSERT_THROW(_blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_20"]->getOutputPort("str"), + _nodeMap["Node_27"]->getInputPort("strvec")), + YACS::ENGINE::ConversionException); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_19"]->getOutputPort("obj"), - nodeMap["Node_20"]->getInputPort("obj")); + _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_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("double")); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_20"]->getOutputPort("long"), - nodeMap["Node_21"]->getInputPort("long")); + _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("str"), + _nodeMap["Node_21"]->getInputPort("str")); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_20"]->getOutputPort("obj"), - nodeMap["Node_21"]->getInputPort("obj")); + _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")); + _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")); + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_31"]->getOutputPort("lngvec"), + _nodeMap["Node_25"]->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")); +} +void RuntimeTest::createDataLinksCORBAPython() +{ DEBTRACE(" --- create data links, CORBA to Python" ); + CPPUNIT_ASSERT_THROW(_blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_20"]->getOutputPort("double"), + _nodeMap["Node_13"]->getInputPort("lng")), + YACS::ENGINE::ConversionException); - // Corba C -> Python C (dérivé de Obj):OK - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_32"]->getOutputPort("objc"), - nodeMap["Node_14"]->getInputPort("objc")); + CPPUNIT_ASSERT_THROW(_blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_27"]->getOutputPort("strvec"), + _nodeMap["Node_13"]->getInputPort("s")), + YACS::ENGINE::ConversionException); - 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")); + // Corba C -> Python C (derived from Obj):OK + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_32"]->getOutputPort("objc"), + _nodeMap["Node_14"]->getInputPort("objc")); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_21"]->getOutputPort("str"), - nodeMap["Node_13"]->getInputPort("s")); + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_21"]->getOutputPort("double"), + _nodeMap["Node_13"]->getInputPort("dble")); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_21"]->getOutputPort("obj"), - nodeMap["Node_13"]->getInputPort("ob")); + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_21"]->getOutputPort("long"), + _nodeMap["Node_13"]->getInputPort("lng")); - // Corba sequence -> Python sequence - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_23"]->getOutputPort("dblevec"), - nodeMap["Node_14"]->getInputPort("li")); + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_21"]->getOutputPort("str"), + _nodeMap["Node_13"]->getInputPort("s")); - // Corba sequence> -> Python sequence> - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_29"]->getOutputPort("dblevecvec"), - nodeMap["Node_14"]->getInputPort("lili")); + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_21"]->getOutputPort("obj"), + _nodeMap["Node_13"]->getInputPort("ob")); - // 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_23"]->getOutputPort("dblevec"), + _nodeMap["Node_14"]->getInputPort("li")); - // 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_29"]->getOutputPort("dblevecvec"), + _nodeMap["Node_14"]->getInputPort("lili")); - // Corba sequence -> Python sequence - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_30"]->getOutputPort("objvecvec"), - nodeMap["Node_14"]->getInputPort("llobj")); + // --- Corba sequence -> Python sequence + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_28"]->getOutputPort("objvec"), + _nodeMap["Node_14"]->getInputPort("lobj")); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_31"]->getOutputPort("lngvec"), - nodeMap["Node_15"]->getInputPort("lngvec")); + // --- Corba sequence -> Python sequence + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_27"]->getOutputPort("strvec"), + _nodeMap["Node_14"]->getInputPort("lstr")); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_31"]->getOutputPort("lngvec"), - nodeMap["Node_15"]->getInputPort("dblevec")); + // --- Corba sequence -> Python sequence + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_30"]->getOutputPort("objvecvec"), + _nodeMap["Node_14"]->getInputPort("llobj")); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_20"]->getOutputPort("long"), - nodeMap["Node_22"]->getInputPort("double")); + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_31"]->getOutputPort("lngvec"), + _nodeMap["Node_15"]->getInputPort("lngvec")); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_20"]->getOutputPort("long"), - nodeMap["Node_22"]->getInputPort("long")); + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_31"]->getOutputPort("lngvec"), + _nodeMap["Node_15"]->getInputPort("dblevec")); +} - 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")); +void RuntimeTest::createDataLinksXML() +{ + DEBTRACE(" --- create data links, xml nodes" ); + + CPPUNIT_ASSERT_THROW(_blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_16"]->getOutputPort("c"), + _nodeMap["Node_36"]->getInputPort("dblevec")), + YACS::ENGINE::ConversionException); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_26"]->getOutputPort("dblevec"), - nodeMap["Node_36"]->getInputPort("dblevec")); + CPPUNIT_ASSERT_THROW(_blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_26"]->getOutputPort("dblevec"), + _nodeMap["Node_36"]->getInputPort("dble")), + YACS::ENGINE::ConversionException); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_29"]->getOutputPort("dblevecvec"), - nodeMap["Node_36"]->getInputPort("dblevecvec")); + CPPUNIT_ASSERT_THROW(_blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_36"]->getOutputPort("dblevec"), + _nodeMap["Node_33"]->getInputPort("dble")), + YACS::ENGINE::ConversionException); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_36"]->getOutputPort("dble"), - nodeMap["Node_33"]->getInputPort("dble")); + CPPUNIT_ASSERT_THROW(_blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_36"]->getOutputPort("dble"), + _nodeMap["Node_34"]->getInputPort("dblevec")), + YACS::ENGINE::ConversionException); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_36"]->getOutputPort("dblevec"), - nodeMap["Node_34"]->getInputPort("dblevec")); + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_16"]->getOutputPort("c"), + _nodeMap["Node_36"]->getInputPort("dble")); - blocMap["Bloc_3"]->edAddLink(nodeMap["Node_36"]->getOutputPort("dblevecvec"), - nodeMap["Node_35"]->getInputPort("dblevecvec")); + _blocMap["Bloc_3"]->edAddLink(_nodeMap["Node_26"]->getOutputPort("dblevec"), + _nodeMap["Node_36"]->getInputPort("dblevec")); - DEBTRACE(" --- initialization" ); + _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")); +} - PyObject *pyDouble = PyFloat_FromDouble(10.51); - nodeMap["Node_10"]->getInputPort("a")->put(pyDouble); - CORBA::Any a; - a <<= (CORBA::Double) 3.14; +void RuntimeTest::manualInitInputPort() +{ + DEBTRACE(" --- InputPort initialization" ); - CORBA::Any anyLong; - anyLong <<= (CORBA::Long) 1; + { + CPPUNIT_ASSERT(! _blocMap["Bloc_3"]->edAreAllInputPortInitialized() ); + set unitialized = _blocMap["Bloc_3"]->edGetSetOfUnitializedInputPort(); + DEBTRACE(unitialized.size()); + for (set::const_iterator iter = unitialized.begin(); iter != unitialized.end(); iter++) + { + DEBTRACE(_blocMap["Bloc_3"]->getInPortName(*iter)); + } + } + _nodeMap["Node_10"]->getInputPort("a")->edInit(10.51); - CORBA::Any anyLong2; - anyLong2 <<= (CORBA::Long) 1; - nodeMap["Node_20"]->getInputPort("long")->put(&anyLong2); +// CORBA::Any anyLong; +// anyLong <<= (CORBA::Long) 1; + DEBTRACE("---"); + _nodeMap["Node_20"]->getInputPort("long")->edInit(1); + DEBTRACE("---"); + // --- manual set of a linked input port: no use under normal conditions + // (value will be replaced by output value before activation and read) + CORBA::Any aString; aString <<= (const char *)"texte"; - nodeMap["Node_20"]->getInputPort("str")->put(&aString); + _nodeMap["Node_20"]->getInputPort("str")->put(&aString); +// _nodeMap["Node_20"]->getInputPort("str")->edInit("texte"); + DEBTRACE("---"); + + { + set unitialized = _blocMap["Bloc_3"]->edGetSetOfUnitializedInputPort(); + DEBTRACE(unitialized.size()); + CPPUNIT_ASSERT( _blocMap["Bloc_3"]->edAreAllInputPortInitialized() ); + } + { + double d=10.51; + int l; + PyObject *pyob; + CORBA::Any *any; + Any * a; + DEBTRACE("Python input port double"); + InputPort* inport=_nodeMap["Node_10"]->getInputPort("a"); + + DEBTRACE("Initialize port with C++ double value"); + a = AtomAny::New(d); + inport->edInit("Cpp",a); + a->decrRef(); + pyob=((InputPyPort*)inport)->getPyObj(); + DEBTRACE(pyob->ob_refcnt); + CPPUNIT_ASSERT(PyFloat_AS_DOUBLE(pyob) == d); + + DEBTRACE("Initialize port with XML double value"); + inport->edInit("XML","10.51"); + pyob=((InputPyPort*)inport)->getPyObj(); + DEBTRACE(pyob->ob_refcnt); + CPPUNIT_ASSERT(PyFloat_AS_DOUBLE(pyob) == d); + + DEBTRACE("Initialize port with XML int value"); + inport->edInit("XML","10"); + pyob=((InputPyPort*)inport)->getPyObj(); + DEBTRACE(pyob->ob_refcnt); + CPPUNIT_ASSERT(PyFloat_AS_DOUBLE(pyob) == 10.); + + DEBTRACE("Initialize port with Python double value"); + inport->edInit("Python",PyFloat_FromDouble(d)); + pyob=((InputPyPort*)inport)->getPyObj(); + DEBTRACE(pyob->ob_refcnt); + CPPUNIT_ASSERT(PyFloat_AS_DOUBLE(pyob) == d); + + DEBTRACE("Python input port seq"); + inport=_nodeMap["Node_14"]->getInputPort("li"); + DEBTRACE("Initialize port with XML seq value"); + inport->edInit("XML","\ + 1.5\ + 2.4\ + "); + pyob=((InputPyPort*)inport)->getPyObj(); + DEBTRACE(pyob->ob_refcnt); + + DEBTRACE("Initialize port with XML seq value"); + inport->edInit("XML","\ + 15\ + 24\ + "); + pyob=((InputPyPort*)inport)->getPyObj(); + DEBTRACE(pyob->ob_refcnt); + + DEBTRACE("CORBA input port int"); + inport=_nodeMap["Node_20"]->getInputPort("long"); + DEBTRACE("Initialize port with XML int value"); + inport->edInit("XML","10"); + any=((InputCorbaPort*)inport)->getAny(); + long LL; + *any >>= LL; + l = LL; + DEBTRACE("l = " << l); + CPPUNIT_ASSERT(l == 10); + + DEBTRACE("CORBA input port double"); + inport=_nodeMap["Node_17"]->getInputPort("b"); + DEBTRACE("Initialize port with XML double value"); + inport->edInit("XML","10.51"); + any=((InputCorbaPort*)inport)->getAny(); + *any >>= d; + CPPUNIT_ASSERT_DOUBLES_EQUAL(10.51,d, 1e-12); + + DEBTRACE("CORBA input port seq"); + inport=_nodeMap["Node_24"]->getInputPort("dblevec"); + DEBTRACE("Initialize port with XML seq value"); + inport->edInit("XML","\ + 1.5\ + 2.4\ + "); + } +} + +void RuntimeTest::manualExecuteNoThread() +{ DEBTRACE(" --- execution Python Node_10" ); - ((ElementaryNode*)nodeMap["Node_10"])->execute(); + ((ElementaryNode*)_nodeMap["Node_10"])->load(); + ((ElementaryNode*)_nodeMap["Node_10"])->execute(); + // CPPUNIT_ASSERT_DOUBLES_EQUAL(10.51, (ElementaryNode*)_nodeMap["Node_10"]) DEBTRACE(" --- execution Python Node_11" ); - ((ElementaryNode*)nodeMap["Node_11"])->execute(); + ((ElementaryNode*)_nodeMap["Node_11"])->load(); + ((ElementaryNode*)_nodeMap["Node_11"])->execute(); DEBTRACE(" --- execution Python Node_12" ); - ((ElementaryNode*)nodeMap["Node_12"])->execute(); + ((ElementaryNode*)_nodeMap["Node_12"])->load(); + ((ElementaryNode*)_nodeMap["Node_12"])->execute(); DEBTRACE(" --- execution CORBA Node_16" ); - ((ElementaryNode*)nodeMap["Node_16"])->execute(); + ((ElementaryNode*)_nodeMap["Node_16"])->load(); + ((ElementaryNode*)_nodeMap["Node_16"])->execute(); DEBTRACE(" --- execution CORBA Node_17" ); - ((ElementaryNode*)nodeMap["Node_17"])->execute(); + ((ElementaryNode*)_nodeMap["Node_17"])->load(); + ((ElementaryNode*)_nodeMap["Node_17"])->execute(); DEBTRACE(" --- execution CORBA Node_18" ); - ((ElementaryNode*)nodeMap["Node_18"])->execute(); + ((ElementaryNode*)_nodeMap["Node_18"])->load(); + ((ElementaryNode*)_nodeMap["Node_18"])->execute(); DEBTRACE(" --- execution CORBA Node_19" ); - ((ElementaryNode*)nodeMap["Node_19"])->execute(); + ((ElementaryNode*)_nodeMap["Node_19"])->load(); + ((ElementaryNode*)_nodeMap["Node_19"])->execute(); DEBTRACE(" --- execution CORBA Node_20" ); - ((ElementaryNode*)nodeMap["Node_20"])->execute(); + ((ElementaryNode*)_nodeMap["Node_20"])->load(); + ((ElementaryNode*)_nodeMap["Node_20"])->execute(); DEBTRACE(" --- execution CORBA Node_21" ); - ((ElementaryNode*)nodeMap["Node_21"])->execute(); + ((ElementaryNode*)_nodeMap["Node_21"])->load(); + ((ElementaryNode*)_nodeMap["Node_21"])->execute(); DEBTRACE(" --- execution CORBA Node_29" ); - ((ElementaryNode*)nodeMap["Node_29"])->execute(); + ((ElementaryNode*)_nodeMap["Node_29"])->load(); + ((ElementaryNode*)_nodeMap["Node_29"])->execute(); DEBTRACE(" --- execution Python Node_13" ); - ((ElementaryNode*)nodeMap["Node_13"])->execute(); + ((ElementaryNode*)_nodeMap["Node_13"])->load(); + ((ElementaryNode*)_nodeMap["Node_13"])->execute(); DEBTRACE(" --- execution CORBA Node_22" ); - ((ElementaryNode*)nodeMap["Node_22"])->execute(); + ((ElementaryNode*)_nodeMap["Node_22"])->load(); + ((ElementaryNode*)_nodeMap["Node_22"])->execute(); DEBTRACE(" --- execution CORBA Node_23" ); - ((ElementaryNode*)nodeMap["Node_23"])->execute(); + ((ElementaryNode*)_nodeMap["Node_23"])->load(); + ((ElementaryNode*)_nodeMap["Node_23"])->execute(); DEBTRACE(" --- execution CORBA Node_24" ); - ((ElementaryNode*)nodeMap["Node_24"])->execute(); + ((ElementaryNode*)_nodeMap["Node_24"])->load(); + ((ElementaryNode*)_nodeMap["Node_24"])->execute(); DEBTRACE(" --- execution CORBA Node_27" ); - ((ElementaryNode*)nodeMap["Node_27"])->execute(); + ((ElementaryNode*)_nodeMap["Node_27"])->load(); + ((ElementaryNode*)_nodeMap["Node_27"])->execute(); DEBTRACE(" --- execution CORBA Node_28" ); - ((ElementaryNode*)nodeMap["Node_28"])->execute(); + ((ElementaryNode*)_nodeMap["Node_28"])->load(); + ((ElementaryNode*)_nodeMap["Node_28"])->execute(); DEBTRACE(" --- execution CORBA Node_30" ); - ((ElementaryNode*)nodeMap["Node_30"])->execute(); + ((ElementaryNode*)_nodeMap["Node_30"])->load(); + ((ElementaryNode*)_nodeMap["Node_30"])->execute(); DEBTRACE(" --- execution CORBA Node_32" ); - ((ElementaryNode*)nodeMap["Node_32"])->execute(); + ((ElementaryNode*)_nodeMap["Node_32"])->load(); + ((ElementaryNode*)_nodeMap["Node_32"])->execute(); DEBTRACE(" --- execution CORBA Node_26" ); - ((ElementaryNode*)nodeMap["Node_26"])->execute(); + ((ElementaryNode*)_nodeMap["Node_26"])->load(); + ((ElementaryNode*)_nodeMap["Node_26"])->execute(); DEBTRACE(" --- execution CORBA Node_31" ); - ((ElementaryNode*)nodeMap["Node_31"])->execute(); + ((ElementaryNode*)_nodeMap["Node_31"])->load(); + ((ElementaryNode*)_nodeMap["Node_31"])->execute(); DEBTRACE(" --- execution Python Node_14" ); - ((ElementaryNode*)nodeMap["Node_14"])->execute(); + ((ElementaryNode*)_nodeMap["Node_14"])->load(); + ((ElementaryNode*)_nodeMap["Node_14"])->execute(); DEBTRACE(" --- execution Python Node_15" ); - ((ElementaryNode*)nodeMap["Node_15"])->execute(); + ((ElementaryNode*)_nodeMap["Node_15"])->load(); + ((ElementaryNode*)_nodeMap["Node_15"])->execute(); DEBTRACE(" --- execution XML Node_36" ); - ((ElementaryNode*)nodeMap["Node_36"])->execute(); + ((ElementaryNode*)_nodeMap["Node_36"])->load(); + ((ElementaryNode*)_nodeMap["Node_36"])->execute(); DEBTRACE(" --- execution CORBA Node_33" ); - ((ElementaryNode*)nodeMap["Node_33"])->execute(); + ((ElementaryNode*)_nodeMap["Node_33"])->load(); + ((ElementaryNode*)_nodeMap["Node_33"])->execute(); DEBTRACE(" --- execution CORBA Node_34" ); - ((ElementaryNode*)nodeMap["Node_34"])->execute(); + ((ElementaryNode*)_nodeMap["Node_34"])->load(); + ((ElementaryNode*)_nodeMap["Node_34"])->execute(); DEBTRACE(" --- execution CORBA Node_35" ); - ((ElementaryNode*)nodeMap["Node_35"])->execute(); + ((ElementaryNode*)_nodeMap["Node_35"])->load(); + ((ElementaryNode*)_nodeMap["Node_35"])->execute(); DEBTRACE(" --- end of execution" ); +} + +void RuntimeTest::manualGetOutputs() +{ CORBA::Double l; CORBA::Any* x; - PyObject *ob=((OutputPyPort*)nodeMap["Node_11"]->getOutputPort("c"))->get(); + 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()); + // DEBTRACE("a: " << &a); + // DEBTRACE("a.value(): " << a.value()); - x= ((InputCorbaPort*)nodeMap["Node_16"]->getInputPort("a"))->getAny(); + 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; + *((InputCorbaPort*)_nodeMap["Node_17"]->getInputPort("b"))->getAny() >>= l; DEBTRACE("CORBA Node_17 input b double: " << l); - *((InputCorbaPort*)nodeMap["Node_18"]->getInputPort("b"))->getAny() >>= 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; + *((OutputCorbaPort*)_nodeMap["Node_16"]->getOutputPort("c"))->getAny() >>= l; DEBTRACE("CORBA Node_16 output c double: " << l); - *((OutputCorbaPort*)nodeMap["Node_17"]->getOutputPort("c"))->getAny() >>= 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; + *((OutputCorbaPort*)_nodeMap["Node_18"]->getOutputPort("c"))->getAny() >>= l; DEBTRACE("CORBA Node_18 output c double: " << l); DEBTRACE(" --- fini" ); } + +void RuntimeTest::createCppNodes() +{ + + string s = "Node_Cpp"; + ElementaryNode* node = _myRuntime->createCompoNode("Cpp",s); + _nodeMap[s] = node; + InputPort *i1 = node->edAddInputPort("id1", _tc_double); + InputPort *i2 = node->edAddInputPort("ii2", _tc_int); + + OutputPort *o3 = node->edAddOutputPort("os3", _tc_string); + + CPPUNIT_ASSERT_EQUAL(node->getImplementation(),string("Cpp")); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfInputPorts(),2); + CPPUNIT_ASSERT_EQUAL(node->getNumberOfOutputPorts(),1); + CPPUNIT_ASSERT_EQUAL(node->getInPortName(i1),string("id1")); + CPPUNIT_ASSERT_EQUAL(node->getOutPortName(o3),string("os3")); + + CPPUNIT_ASSERT_EQUAL(node->getInputPort("id1"),i1); + CPPUNIT_ASSERT_EQUAL(node->getOutputPort("os3"),o3); + + delete node; +} + +void RuntimeTest::convertPorts() +{ + const char *type[] = { "Cpp", "CORBA", "Python", "XML" }; + int itype, jtype, ntypes = sizeof(type)/sizeof(const char *); + + string s0 = "Node_"; + CORBA::Any cAny; + PyObject * pAny; + Any * vAny; + std::string sAny; + + for (itype=0; itypecreateRefNode(type[itype],s); + break; + case 2: + node = _myRuntime->createScriptNode(type[itype], s); + break; + case 3: + node = _myRuntime->createRefNode("xmlsh",s); + break; + default: + node = _myRuntime->createCompoNode(type[itype], s); + break; + } + InputPort *inport = node->edAddInputPort("id1", _tc_double); + CPPUNIT_ASSERT(NULL != node); + for (jtype=0; jtype < ntypes; jtype++) + { + double d0= itype * 10 + jtype, d1; + InputPort* pwrap=_myRuntime->adapt(inport, type[jtype], _tc_double); + + const void *v; + switch (jtype) + { + case 0: + case 4: + v = vAny = AtomAny::New(d0); + break; + case 1: + v = &cAny; + cAny <<= (CORBA::Double) d0; + break; + case 2: + v = pAny = PyFloat_FromDouble(d0); + break; + case 3: + { + ostringstream os; + os << "" << d0 << ""; + sAny = os.str(); + v = sAny.c_str(); + } + break; + default: + v = NULL; + break; + } + + if ((itype == 2) && (jtype == 2)) + { + std::cerr << "s = " << s << endl; + } + + DEBTRACE("Put a " << type[jtype] << " double (" << d0 << ") in " << s); + pwrap->put(v); + cerr << endl; + + switch (itype) + { + case 0: + case 4: + { + Any * a=((InputCppPort*)inport)->getCppObj(); + CPPUNIT_ASSERT(a->getType()->isA(_tc_double)); + d1 = a->getDoubleValue(); + } + break; + case 1: + { + CORBA::Any * a = ((InputCorbaPort*)inport)->getAny(); + CPPUNIT_ASSERT(a->type()->equal(CORBA::_tc_double)); + CORBA::Double d; + *a >>= d; + d1 = d; + } + break; + case 2: + { + PyObject *a = ((InputPyPort*)inport)->getPyObj(); + CPPUNIT_ASSERT(PyFloat_Check(a)); + d1 = PyFloat_AsDouble(a); + } + break; + case 3: + { + const char *a = ((InputXmlPort*)inport)->getXml(); + const char *a1, *a2, *a3, *a_end; + a_end = a + strlen(a) - 1; + while (isspace(*a_end)) a_end--; + a1 = a; + a2 = a + strlen(""); + a3 = a_end - strlen("") + 1; + CPPUNIT_ASSERT(!strncmp(a1, "", strlen(""))); + CPPUNIT_ASSERT(!strncmp(a3, "", strlen(""))); + char *err; + d1 = strtod(a2, &err); + CPPUNIT_ASSERT(err == a3); + } + break; + } + + CPPUNIT_ASSERT_DOUBLES_EQUAL(d0, d1, 1e-12); + + switch (jtype) + { + case 0: + case 4: + vAny->decrRef(); + break; + case 2: + Py_DECREF(pAny); + break; + default: + break; + } + if (pwrap != inport) delete pwrap; + } + delete node; + } +} + +void myTestRun(int nIn, int nOut, Any **In, Any **Out) throw (YACS::Exception) +{ + double x, y; + cerr << "myTestRun nIn = " << nIn << endl; + cerr << "myTestRun nOut = " << nOut << endl; + + x = In[0]->getDoubleValue(); + + if (x >= 0.0) + { + y = sqrt(x); + Out[0] = AtomAny::New(y); + } + else + { + throw YACS::Exception("myTestRun : input must be a positive or null real"); + } +} + + +void RuntimeTest::executeCppNode() +{ + cerr << endl << endl; + + Any *u, *v, *w; + double du, dv, dw; + + DEBTRACE("execute a CppNode with an internal C++ implementation") + ServiceNode * node = _myRuntime->createCompoNode("Cpp", "test"); + ((CppNode *) node)->setFunc(myTestRun); + + InputPort *in = node->edAddInputPort("in", _tc_double); + OutputPort *out = node->edAddOutputPort("out", _tc_double); + node->load(); + + dv = 4.5; + v = AtomAny::New(dv); + in->edInit("Cpp",v); + + node->execute(); + + w = ((OutputCppPort *) out)->get(); + dw = w->getDoubleValue(); + + cerr << "sqrt(" << dv << ") = " << dw << endl; + CPPUNIT_ASSERT_DOUBLES_EQUAL(dw, sqrt(dv), 1e-12); + + u = AtomAny::New((double) -3.5); + in->edInit("Cpp",u); + CPPUNIT_ASSERT_THROW(node->execute(), YACS::Exception); + + u->decrRef(); + v->decrRef(); + w->decrRef(); + + delete node; + + DEBTRACE("execute a CppNode with an external C++ implementation (in a dynamic library)"); + + setenv("TESTCOMPONENT_ROOT_DIR", LOCATION, 1); + node = _myRuntime->createCompoNode("Cpp", "test"); + CppComponent * C = new CppComponent("TestComponent"); + node->setComponent(C); + node->setMethod("f"); + + in = node->edAddInputPort("in", _tc_double); + out = node->edAddOutputPort("out", _tc_double); + node->load(); + + dv = 4.5; + v = AtomAny::New(dv); + in->edInit("Cpp",v); + + node->execute(); + + w = ((OutputCppPort *) out)->get(); + dw = w->getDoubleValue(); + + cerr << "sqrt(" << dv << ") = " << dw << endl; + CPPUNIT_ASSERT_DOUBLES_EQUAL(dw, sqrt(dv), 1e-12); + + u = AtomAny::New((double) -3.5); + in->edInit("Cpp",u); + CPPUNIT_ASSERT_THROW(node->execute(), YACS::Exception); + + u->decrRef(); + v->decrRef(); + w->decrRef(); + + delete node; + +} + +void RuntimeTest::createGraphWithCppNodes() +{ + setenv("TESTCOMPONENT_ROOT_DIR", LOCATION, 1); + ElementaryNode * n1, * n2; + InputPort *in1, *in2; + OutputPort *out1, *out2; + + n1 = _myRuntime->createCompoNode(CppNode::KIND, "test1"); + n2 = _myRuntime->createScriptNode(PythonNode::KIND, "test2"); + + CppComponent *C = new CppComponent("TestComponent"); + ((CppNode *) n1)->setComponent(C); + ((CppNode *) n1)->setMethod("f"); + in1 = n1->edAddInputPort("i", _tc_double); + out1 = n1->edAddOutputPort("o", _tc_double); + + ((InlineNode*) n2)->setScript("a=a+1\n"); + in2 = n2->edAddInputPort("a", _tc_double); + out2 = n2->edAddOutputPort("a", _tc_double); + + Bloc * loopBody = _myRuntime->createBloc("LoopBody"); + loopBody->edAddChild(n1); + loopBody->edAddChild(n2); + loopBody->edAddLink(out1, in2); + loopBody->edAddLink(out2, in1); + + ForLoop *loop=_myRuntime->createForLoop("Loop"); + loop->edSetNode(loopBody); + InputPort *iNbTimes=loop->edGetNbOfTimesInputPort(); + iNbTimes->edInit(5); + + Bloc * graph = _myRuntime->createBloc("graph"); + graph->edAddChild(loop); + + DEBTRACE("n1->getInputPort(\"in\") = " << n1->getInputPort("i")->getName()) + + in1->edInit(4.5); + in2->edInit(0.0); + + Executor exe; + exe.RunW(graph); + + DEBTRACE(out2->dump()); + + delete graph; +} + +void RuntimeTest::classTeardown() +{ + if (endTests) return; + + endTests = true; + _tc_seqC->decrRef(); + _tc_C->decrRef(); + list::iterator i; + for (i=_ltc.begin(); i != _ltc.end(); i++) + (*i)->decrRef(); + + _tc_seqseqobj->decrRef(); + _tc_seqobj->decrRef(); + + + _tc->decrRef(); + _tc_seqseqdble->decrRef(); + _tc_seqdble->decrRef(); + _tc_seqstr->decrRef(); + _tc_seqlong->decrRef(); + _tc_string->decrRef(); + + delete _myRuntime; +} diff --git a/src/runtime/Test/runtimeTest.hxx b/src/runtime/Test/runtimeTest.hxx index 5caaa39ad..db369dc51 100644 --- a/src/runtime/Test/runtimeTest.hxx +++ b/src/runtime/Test/runtimeTest.hxx @@ -2,24 +2,111 @@ #ifndef _RUNTIMETEST_HXX_ #define _RUNTIMETEST_HXX_ +#include "RuntimeSALOME.hxx" +#include "TypeCode.hxx" + +#ifdef USE_CPPUNIT #include +#else +#define CPPUNIT_TEST_SUITE(x) +#define CPPUNIT_TEST(x) +#define CPPUNIT_TEST_SUITE_END(x) +#define CPPUNIT_ASSERT(x) std::cerr << #x << " : " << (x) << std::endl +#define CPPUNIT_ASSERT_EQUAL(x,y) std::cerr << "Test " << #x << " == " << #y << " : " << ((x) == (y)) << std::endl; +#define CPPUNIT_ASSERT_DOUBLES_EQUAL(x,y,z) +#define CPPUNIT_ASSERT_THROW(x,y) \ + try { x; } \ + catch (y &e) { cerr << e.what() << endl; } +#endif + +#include +#include namespace YACS { - class RuntimeTest: public CppUnit::TestFixture + class RuntimeTest +#ifdef USE_CPPUNIT + : public CppUnit::TestFixture +#endif { CPPUNIT_TEST_SUITE( RuntimeTest ); - CPPUNIT_TEST(test1 ); + CPPUNIT_TEST(initRuntimeTypeCode ); + CPPUNIT_TEST(createPythonNodes ); + CPPUNIT_TEST(createCORBANodes ); + CPPUNIT_TEST(createBloc ); + CPPUNIT_TEST(createRecursiveBlocs ); + CPPUNIT_TEST(createDataLinks ); + CPPUNIT_TEST(createPythonNodesWithScript ); + CPPUNIT_TEST(createCORBANodesWithMethod ); + CPPUNIT_TEST(createXMLNodes ); + CPPUNIT_TEST(createBloc2 ); + CPPUNIT_TEST(createDataLinksPythonPython ); + CPPUNIT_TEST(createDataLinksPythonCORBA ); + CPPUNIT_TEST(createDataLinksCORBACORBA ); + CPPUNIT_TEST(createDataLinksCORBAPython ); + CPPUNIT_TEST(createDataLinksXML ); + CPPUNIT_TEST(manualInitInputPort ); + CPPUNIT_TEST(manualExecuteNoThread ); + CPPUNIT_TEST(manualGetOutputs ); + CPPUNIT_TEST(createCppNodes ); + CPPUNIT_TEST(convertPorts ); + CPPUNIT_TEST(executeCppNode ); + CPPUNIT_TEST(createGraphWithCppNodes ); CPPUNIT_TEST_SUITE_END(); - + public: void setUp(); void tearDown(); - void test1(); - + void initRuntimeTypeCode(); + void createPythonNodes(); + void createCORBANodes(); + void createBloc(); + void createRecursiveBlocs(); + void createDataLinks(); + void createPythonNodesWithScript(); + void createCORBANodesWithMethod(); + void createXMLNodes(); + void createBloc2(); + void createDataLinksPythonPython(); + void createDataLinksPythonCORBA(); + void createDataLinksCORBACORBA(); + void createDataLinksCORBAPython(); + void createDataLinksXML(); + void manualInitInputPort(); + void manualExecuteNoThread(); + void manualGetOutputs(); + void createCppNodes(); + void executeCppNode(); + void createGraphWithCppNodes(); + void convertPorts(); + + void classTeardown(); + protected: + static std::map _nodeMap; + static std::map _blocMap; + static std::list _ltc; + static int _inode; + static int _ibloc; + static YACS::ENGINE::Runtime *_myRuntime; + + static YACS::ENGINE::TypeCode *_tc_double; + static YACS::ENGINE::TypeCode *_tc_int; + static YACS::ENGINE::TypeCode *_tc_string; + static YACS::ENGINE::TypeCode *_tc; + static YACS::ENGINE::TypeCode *_tc_obj; + static YACS::ENGINE::TypeCode *_tc_seqdble; + static YACS::ENGINE::TypeCode *_tc_seqstr; + static YACS::ENGINE::TypeCode *_tc_seqlong; + static YACS::ENGINE::TypeCode *_tc_seqobj; + static YACS::ENGINE::TypeCode *_tc_seqseqdble; + static YACS::ENGINE::TypeCode *_tc_seqseqobj; + static YACS::ENGINE::TypeCode *_tc_C; + static YACS::ENGINE::TypeCode *_tc_seqC; + + static bool endTests; private: diff --git a/src/runtime/Test/runtimeTest.sh b/src/runtime/Test/runtimeTest.sh index cbb79edf9..ce2bf720c 100644 --- a/src/runtime/Test/runtimeTest.sh +++ b/src/runtime/Test/runtimeTest.sh @@ -1,3 +1,4 @@ +#!/bin/sh BASEREP=`pwd` OMNIORB_CONFIG=${BASEREP}/omniorb.cfg @@ -27,5 +28,8 @@ pidecho=$! echo $pidecho ./TestRuntime +ret=$? kill -9 $pidecho $pidomni +cat /tmp/${USER}/UnitTestsResult +exit $ret diff --git a/src/runtime/Test/standaloneTest.sh b/src/runtime/Test/standaloneTest.sh new file mode 100755 index 000000000..991900269 --- /dev/null +++ b/src/runtime/Test/standaloneTest.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +killall -9 omniNames echoSrv + +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} + +mkdir -p /tmp/${USER} +\rm -f /tmp/${USER}/UnitTestsResult + +echo $$ + +omniNames -start 2910 & +pidomni=$! +echo $pidomni + +./echoSrv & +pidecho=$! +echo $pidecho + +export PYTHONPATH=${BASEREP}:${PYTHONPATH} +./.libs/TestStandAlone +ret=$? +# +# kill -9 $pidecho $pidomni +cat /tmp/${USER}/UnitTestsResult +exit $ret diff --git a/src/runtime/Test/xmlrun_orig.sh b/src/runtime/Test/xmlrun_orig.sh new file mode 100755 index 000000000..3121519cb --- /dev/null +++ b/src/runtime/Test/xmlrun_orig.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env python + +import xmlrpclib,sys + +data=""" + + echo + + hello, world + 3.5 + coucou + + +""" +def echo(args): + print args + return args + +f=open("input") +data=f.read() +f.close() +print data + +class Objref: + """Wrapper for objrefs """ + def __init__(self,data=None): + self.data=data + def __str__(self): + return self.data or "" + def __cmp__(self, other): + if isinstance(other, Binary): + other = other.data + return cmp(self.data, other) + + def decode(self, data): + self.data = data + + def encode(self, out): + out.write("") + out.write(self.data or "") + out.write("\n") + +xmlrpclib.WRAPPERS=xmlrpclib.WRAPPERS+(Objref,) + +def end_objref(self,data): + self.append(Objref(data)) + self._value=0 + +xmlrpclib.Unmarshaller.end_objref=end_objref +xmlrpclib.Unmarshaller.dispatch["objref"]=end_objref + +params, method = xmlrpclib.loads(data) + +try: + call=eval(method) + response=call(params) + response = (response,) +except: + # report exception back to server + response = xmlrpclib.dumps( xmlrpclib.Fault(1, "%s:%s" % sys.exc_info()[:2])) +else: + response = xmlrpclib.dumps( response, methodresponse=1) + +print response +f=open("output",'w') +f.write(response) +f.close() diff --git a/src/runtime/TypeConversions.cxx b/src/runtime/TypeConversions.cxx index 58f3903b5..c51ca9ae2 100644 --- a/src/runtime/TypeConversions.cxx +++ b/src/runtime/TypeConversions.cxx @@ -1,1053 +1,1881 @@ +//#define REFCNT +#ifdef REFCNT +#define private public +#define protected public +#include +#include +#endif + #include "TypeConversions.hxx" -#include "Exception.hxx" +#include "ConversionException.hxx" #include "RuntimeSALOME.hxx" +#include "TypeCode.hxx" +#include "Cstr2d.hxx" #include #include +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + using namespace std; namespace YACS { namespace ENGINE { - /* - * Fonctions qui retournent un TypeCode CORBA equivalent a un TypeCode Superviseur + * Functions to return a CORBA TypeCode equivalent to a YACS TypeCode */ - CORBA::TypeCode_ptr getCorbaTCNull(TypeCode *t) + typedef CORBA::TypeCode_ptr (*getCorbaTCFn)(const TypeCode *); + + CORBA::TypeCode_ptr getCorbaTCNull(const TypeCode *t) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind(); + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + + CORBA::TypeCode_ptr getCorbaTCDouble(const TypeCode *t) { - stringstream msg; - msg << "Conversion not implemented: kind= " << t->kind() << " : " << __FILE__ << ":" << __LINE__; - throw YACS::Exception(msg.str()); + return CORBA::TypeCode::_duplicate(CORBA::_tc_double); + } + + CORBA::TypeCode_ptr getCorbaTCInt(const TypeCode *t) + { + return CORBA::TypeCode::_duplicate(CORBA::_tc_long); } - CORBA::TypeCode_ptr getCorbaTCDouble(TypeCode *t) + CORBA::TypeCode_ptr getCorbaTCString(const TypeCode *t) { - return CORBA::_tc_double; + return CORBA::TypeCode::_duplicate(CORBA::_tc_string); } - CORBA::TypeCode_ptr getCorbaTCInt(TypeCode *t) + CORBA::TypeCode_ptr getCorbaTCBool(const TypeCode *t) { - return CORBA::_tc_long; + return CORBA::TypeCode::_duplicate(CORBA::_tc_boolean); } - CORBA::TypeCode_ptr getCorbaTCString(TypeCode *t) + CORBA::TypeCode_ptr getCorbaTCObjref(const TypeCode *t) { - return CORBA::_tc_string; + DEBTRACE( t->name() << " " << t->shortName()); + CORBA::TypeCode_ptr tc= getSALOMERuntime()->getOrb()->create_interface_tc(t->id(),t->shortName()); +#ifdef REFCNT + DEBTRACE("refcount CORBA tc Objref: " << ((omni::TypeCode_base*)tc)->pd_ref_count); +#endif + return tc; } - CORBA::TypeCode_ptr getCorbaTCObjref(TypeCode *t) + CORBA::TypeCode_ptr getCorbaTCSequence(const TypeCode *t) { - return CORBA::_tc_Object; + CORBA::TypeCode_var content_type=getCorbaTC(t->contentType()); + CORBA::TypeCode_ptr tc= getSALOMERuntime()->getOrb()->create_sequence_tc(0,content_type); +#ifdef REFCNT + DEBTRACE("refcount CORBA content_type: " << ((omni::TypeCode_base*)content_type.in())->pd_ref_count); + DEBTRACE("refcount CORBA tc: " << ((omni::TypeCode_base*)tc)->pd_ref_count); +#endif + return tc; } - CORBA::TypeCode_ptr getCorbaTCSequence(TypeCode *t) + CORBA::TypeCode_ptr getCorbaTCStruct(const TypeCode *t) { - return getSALOMERuntime()->getOrb()->create_sequence_tc(0,getCorbaTC(t->content_type())); + CORBA::StructMemberSeq mseq; + YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t; + int nMember=tst->memberCount(); + mseq.length(nMember); + for(int i=0;imemberName(i); + TypeCode* tm=tst->memberType(i); + mseq[i].name=CORBA::string_dup(name); + mseq[i].type=getCorbaTC(tm); + } + CORBA::TypeCode_ptr tc= getSALOMERuntime()->getOrb()->create_struct_tc(t->id(),t->shortName(),mseq); +#ifdef REFCNT + DEBTRACE("refcount CORBA tc: " << ((omni::TypeCode_base*)tc)->pd_ref_count); +#endif + return tc; } getCorbaTCFn getCorbaTCFns[]= { - getCorbaTCNull, - getCorbaTCDouble, - getCorbaTCInt, - getCorbaTCString, - getCorbaTCNull, - getCorbaTCObjref, - getCorbaTCSequence, - getCorbaTCNull, + getCorbaTCNull, + getCorbaTCDouble, + getCorbaTCInt, + getCorbaTCString, + getCorbaTCBool, + getCorbaTCObjref, + getCorbaTCSequence, + getCorbaTCNull, + getCorbaTCStruct, }; - CORBA::TypeCode_ptr getCorbaTC(TypeCode *t) + CORBA::TypeCode_ptr getCorbaTC(const TypeCode *t) { int tk=t->kind(); return getCorbaTCFns[tk](t); } /* - * Fin des Fonctions qui retournent un TypeCode CORBA equivalent a un TypeCode Superviseur + * End of Functions to return a CORBA TypeCode equivalent to a YACS TypeCode */ /* - * Fonctions de conversion d'un PyObject * quelconque en CORBA::Any * - * du type donné par le TypeCode passé en argument + * Section that defines functions to check adaptation from one implementation to another + * isAdaptable is template function that checks if TypeCode t1 from implementation IMPLIN + * can be converted to TypeCode t2 from implementation IMPLOUT + * IMPLIN is the implementation of an output port + * IMPLOUT is the implementation of an input port + * If the check is True, the input port can be adapted to the output port */ - //Le TypeCode passé en argument est celui du port qui recoit la donnée : InputCorbaPort + template inline int isAdaptable(const TypeCode *t1,const TypeCode* t2); - //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[] = + template + struct isAdaptableDouble { - convertCorbaPyObjectNull, - convertCorbaPyObjectDouble, - convertCorbaPyObjectInt, - convertCorbaPyObjectString, - convertCorbaPyObjectNull, - convertCorbaPyObjectObjref, - convertCorbaPyObjectSequence, + static inline int apply(const TypeCode *t1,const TypeCode* t2) + { + if(t1->kind() == Double)return 1; + if(t1->kind() == Int)return 1; + return 0; + } + }; + template + struct isAdaptableInt + { + static inline int apply(const TypeCode *t1,const TypeCode* t2) + { + if(t1->kind() == Int)return 1; + return 0; + } + }; + template + struct isAdaptableString + { + static inline int apply(const TypeCode *t1,const TypeCode* t2) + { + if(t1->kind() == String)return 1; + return 0; + } + }; + template + struct isAdaptableBool + { + static inline int apply(const TypeCode *t1,const TypeCode* t2) + { + if(t1->kind() == Bool)return 1; + if(t1->kind() == Int)return 1; + return 0; + } + }; + template + struct isAdaptableObjref + { + static inline int apply(const TypeCode *t1,const TypeCode* t2) + { + if(t1->kind() == Objref) + { + //The inport type must be more general than outport type + if( t1->isA(t2->id()) ) + return 1; + } + return 0; + } + }; + template + struct isAdaptableSequence + { + static inline int apply(const TypeCode *t1,const TypeCode* t2) + { + if(t1->kind() == Sequence) + { + if(isAdaptable(t1->contentType(),t2->contentType())) + { + return 1; + } + } + return 0; + } + }; + template + struct isAdaptableArray + { + static inline int apply(const TypeCode *t1,const TypeCode* t2) + { + return 0; + } + }; + template + struct isAdaptableStruct + { + static inline int apply(const TypeCode *t1,const TypeCode* t2) + { + if(t1->kind() == Struct) + { + if( t1->isA(t2->id()) ) + return 1; + } + return 0; + } }; - - 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) + * Function to check adaptation from implementation 1 (IMPLIN,t1) to implementation 2 (IMPLOUT,t2) + * t1 is the IMPLIN output port type + * t2 is the IMPLOUT input port type */ - //t1 est le type du port output Python - //t2 est le type du port input Corba + template + inline int isAdaptable(const TypeCode *t1,const TypeCode* t2) + { + switch(t2->kind()) + { + case Double: + return isAdaptableDouble::apply(t1,t2); + case Int: + return isAdaptableInt::apply(t1,t2); + case String: + return isAdaptableString::apply(t1,t2); + case Bool: + return isAdaptableBool::apply(t1,t2); + case Objref: + return isAdaptableObjref::apply(t1,t2); + case Sequence: + return isAdaptableSequence::apply(t1,t2); + case Array: + return isAdaptableArray::apply(t1,t2); + case Struct: + return isAdaptableStruct::apply(t1,t2); + default: + break; + } + return 0; + } - int isAdaptableCorbaPyObjectNull(TypeCode *t1,TypeCode* t2) + //xxx to Python adaptations + int isAdaptableCorbaPyObject(const TypeCode *t1,const TypeCode *t2) { - return 0; + return isAdaptable(t1,t2); } - - int isAdaptableCorbaPyObjectDouble(TypeCode *t1,TypeCode* t2) + int isAdaptableNeutralPyObject(const TypeCode * t1, const TypeCode * t2) { - if (t1->kind() == Double) return 1; - if (t1->kind() == Int) return 1; - return 0; + return isAdaptable(t1,t2); } - - int isAdaptableCorbaPyObjectInt(TypeCode *t1,TypeCode* t2) + int isAdaptablePyObjectPyObject(const TypeCode *t1,const TypeCode *t2) { - if (t1->kind() == Int) return 1; - return 0; + return isAdaptable(t1,t2); } - int isAdaptableCorbaPyObjectString(TypeCode *t1,TypeCode* t2) + //xxx to Neutral adaptations + int isAdaptableCorbaNeutral(const TypeCode *t1,const 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; + return isAdaptable(t1,t2); } - - isAdaptableCorbaPyObjectFn isAdaptableCorbaPyObjectFns[]= - { - isAdaptableCorbaPyObjectNull, - isAdaptableCorbaPyObjectDouble, - isAdaptableCorbaPyObjectInt, - isAdaptableCorbaPyObjectString, - isAdaptableCorbaPyObjectNull, - isAdaptableCorbaPyObjectObjref, - isAdaptableCorbaPyObjectSequence, - }; - - int isAdaptableCorbaPyObject(TypeCode *t1,TypeCode *t2) + int isAdaptablePyObjectNeutral(const TypeCode *t1,const TypeCode *t2) { - int tk=t2->kind(); - return isAdaptableCorbaPyObjectFns[tk](t1,t2); + return isAdaptable(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) + int isAdaptableXmlNeutral(const TypeCode *t1,const TypeCode *t2) { - return 0; + return isAdaptable(t1,t2); } - - int isAdaptableXmlCorbaDouble(TypeCode *t1,TypeCode* t2) + int isAdaptableNeutralNeutral(const TypeCode *t1, const TypeCode *t2) { - if(t1->kind() == Double)return 1; - if(t1->kind() == Int)return 1; - return 0; + return isAdaptableNeutralCorba(t1, t2); } - int isAdaptableXmlCorbaInt(TypeCode *t1,TypeCode* t2) + //xxx to XML adaptations + int isAdaptableNeutralXml(const TypeCode * t1, const TypeCode * t2) { - if(t1->kind() == Int)return 1; - return 0; + return isAdaptable(t1,t2); } - int isAdaptableXmlCorbaString(TypeCode *t1,TypeCode* t2) + //xxx to Corba adaptations + int isAdaptableNeutralCorba(const TypeCode *t1,const TypeCode *t2) { - if(t1->kind() == String)return 1; - return 0; + return isAdaptable(t1,t2); } - - 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 isAdaptableXmlCorba(const TypeCode *t1,const TypeCode *t2) + { + return isAdaptable(t1,t2); } - - int isAdaptableXmlCorbaSequence(TypeCode *t1,TypeCode* t2) - { - if(t1->kind() == Sequence) - { - if(isAdaptableXmlCorba(t1->content_type(),t2->content_type())) - { - return 1; - } - } - return 0; + int isAdaptableCorbaCorba(const TypeCode *t1,const TypeCode *t2) + { + return isAdaptable(t1,t2); } - - isAdaptableXmlCorbaFn isAdaptableXmlCorbaFns[]= - { - isAdaptableXmlCorbaNull, - isAdaptableXmlCorbaDouble, - isAdaptableXmlCorbaInt, - isAdaptableXmlCorbaString, - isAdaptableXmlCorbaNull, - isAdaptableXmlCorbaObjref, - isAdaptableXmlCorbaSequence, - }; - - int isAdaptableXmlCorba(TypeCode *t1,TypeCode *t2) + int isAdaptablePyObjectCorba(const TypeCode *t1,const TypeCode *t2) { - int tk=t2->kind(); - return isAdaptableXmlCorbaFns[tk](t1,t2); + return isAdaptable(t1,t2); } - /* - * Fin des fonctions d'adaptation pour conversion CORBA::Any * (t1) -> Xml::char * (t2) + //! Basic template convertor from type TIN to Yacs type + /*! + * This convertor does nothing : throws exception + * It must be partially specialize for a specific type (TIN) */ + template + struct convertToYacsDouble + { + static inline double convert(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsInt + { + static inline long convert(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsString + { + static inline std::string convert(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsBool + { + static inline bool convert(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsObjref + { + static inline std::string convert(const TypeCode *t,TIN o,TIN2 aux) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsSequence + { + static inline void convert(const TypeCode *t,TIN o,TIN2 aux,std::vector& v) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsArray + { + static inline void convert(const TypeCode *t,TIN o,TIN2 aux,std::vector& v) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsStruct + { + static inline void convert(const TypeCode *t,TIN o,TIN2 aux,std::map& v) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; - /* - * Fonctions de test d'adaptation pour conversion CORBA::Any * (t1) -> CORBA::Any * (t2) + //! Basic convertor from Yacs type to full TOUT type + /*! + * */ - //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) + template + struct convertFromYacsDouble + { + static inline TOUT convert(const TypeCode *t,double o) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertFromYacsInt + { + static inline TOUT convert(const TypeCode *t,long o) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertFromYacsString + { + static inline TOUT convert(const TypeCode *t,std::string o) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertFromYacsBool + { + static inline TOUT convert(const TypeCode *t,bool o) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertFromYacsObjref + { + static inline TOUT convert(const TypeCode *t,std::string o) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertFromYacsSequence + { + static inline TOUT convert(const TypeCode *t,std::vector& v) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertFromYacsArray + { + static inline TOUT convert(const TypeCode *t,std::vector& v) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertFromYacsStruct + { + static inline TOUT convert(const TypeCode *t,std::map& v) + { + stringstream msg; + msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + inline TOUT convertDouble(const TypeCode *t,TIN o,TIN2 aux) { - if(t1->kind() == Double)return 1; - if(t1->kind() == Int)return 1; - return 0; + double d=convertToYacsDouble::convert(t,o,aux); + DEBTRACE( d ); + TOUT r=convertFromYacsDouble::convert(t,d); + return r; } - - int isAdaptableCorbaCorbaInt(TypeCode *t1,TypeCode* t2) + template + inline TOUT convertInt(const TypeCode *t,TIN o,TIN2 aux) { - if(t1->kind() == Int)return 1; - return 0; + long d=convertToYacsInt::convert(t,o,aux); + DEBTRACE( d ); + TOUT r=convertFromYacsInt::convert(t,d); + return r; } - - int isAdaptableCorbaCorbaString(TypeCode *t1,TypeCode* t2) + template + inline TOUT convertString(const TypeCode *t,TIN o,TIN2 aux) { - if(t1->kind() == String)return 1; - return 0; + std::string d=convertToYacsString::convert(t,o,aux); + DEBTRACE( d ); + TOUT r=convertFromYacsString::convert(t,d); + return r; } - - int isAdaptableCorbaCorbaObjref(TypeCode *t1,TypeCode* t2) + template + inline TOUT convertBool(const TypeCode *t,TIN o,TIN2 aux) { - 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; + double d=convertToYacsBool::convert(t,o,aux); + DEBTRACE( d ); + TOUT r=convertFromYacsBool::convert(t,d); + return r; } - - isAdaptableCorbaCorbaFn isAdaptableCorbaCorbaFns[]= - { - isAdaptableCorbaCorbaNull, - isAdaptableCorbaCorbaDouble, - isAdaptableCorbaCorbaInt, - isAdaptableCorbaCorbaString, - isAdaptableCorbaCorbaNull, - isAdaptableCorbaCorbaObjref, - isAdaptableCorbaCorbaSequence, - }; - - int isAdaptableCorbaCorba(TypeCode *t1,TypeCode *t2) + template + inline TOUT convertObjref(const TypeCode *t,TIN o,TIN2 aux) { - int tk=t2->kind(); - return isAdaptableCorbaCorbaFns[tk](t1,t2); + std::string d=convertToYacsObjref::convert(t,o,aux); + DEBTRACE( d ); + TOUT r=convertFromYacsObjref::convert(t,d); + return r; } - /* - * 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) + template + inline TOUT convertSequence(const TypeCode *t,TIN o,TIN2 aux) { - return 0; + std::vector v; + convertToYacsSequence::convert(t,o,aux,v); + TOUT r=convertFromYacsSequence::convert(t,v); + return r; } - - int isAdaptablePyObjectPyObjectDouble(TypeCode *t1,TypeCode* t2) + template + inline TOUT convertArray(const TypeCode *t,TIN o,TIN2 aux) { - if(t1->kind() == Double)return 1; - if(t1->kind() == Int)return 1; - return 0; + std::vector v; + convertToYacsArray::convert(t,o,aux,v); + TOUT r=convertFromYacsArray::convert(t,v); + return r; } - - int isAdaptablePyObjectPyObjectInt(TypeCode *t1,TypeCode* t2) + template + inline TOUT convertStruct(const TypeCode *t,TIN o,TIN2 aux) { - if(t1->kind() == Int)return 1; - return 0; + std::map v; + convertToYacsStruct::convert(t,o,aux,v); + TOUT r=convertFromYacsStruct::convert(t,v); + return r; } - 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[]= + template + inline TOUT YacsConvertor(const TypeCode *t,TIN o,TIN2 aux) { - isAdaptablePyObjectPyObjectNull, - isAdaptablePyObjectPyObjectDouble, - isAdaptablePyObjectPyObjectInt, - isAdaptablePyObjectPyObjectString, - isAdaptablePyObjectPyObjectNull, - isAdaptablePyObjectPyObjectObjref, - isAdaptablePyObjectPyObjectSequence, - }; - - int isAdaptablePyObjectPyObject(TypeCode *t1,TypeCode *t2) - { - int tk=t2->kind(); - return isAdaptablePyObjectPyObjectFns[tk](t1,t2); - } + int tk=t->kind(); + switch(t->kind()) + { + case Double: + return convertDouble(t,o,aux); + case Int: + return convertInt(t,o,aux); + case String: + return convertString(t,o,aux); + case Bool: + return convertBool(t,o,aux); + case Objref: + return convertObjref(t,o,aux); + case Sequence: + return convertSequence(t,o,aux); + case Array: + return convertArray(t,o,aux); + case Struct: + return convertStruct(t,o,aux); + default: + break; + } + stringstream msg; + msg << "Conversion not implemented: kind= " << tk << " Implementation: " << IMPLOUT; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } - /* - * Fin des fonctions d'adaptation pour conversion PyObject * -> PyObject * + //! ToYacs Convertor for PYTHONImpl + /*! + * This convertor converts Python object to YACS types + * Partial specialization for Python implementation with type PyObject* (PYTHONImpl) */ + template + struct convertToYacsDouble + { + static inline double convert(const TypeCode *t,PyObject* o,void*) + { + double x; + if (PyFloat_Check(o)) + x=PyFloat_AS_DOUBLE(o); + else if (PyInt_Check(o)) + x=PyInt_AS_LONG(o); + else if(PyLong_Check(o)) + x=PyLong_AsLong(o); + else + { + stringstream msg; + msg << "Not a python double. kind=" << t->kind() ; + msg << " ( " << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); + } + return x; + } + }; + template + struct convertToYacsInt + { + static inline long convert(const TypeCode *t,PyObject* o,void*) + { + long l; + if (PyInt_Check(o)) + l=PyInt_AS_LONG(o); + else if(PyLong_Check(o)) + l=PyLong_AsLong(o); + else + { + stringstream msg; + msg << "Not a python integer. kind=" << t->kind() ; + msg << " ( " << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); + } + return l; + } + }; + template + struct convertToYacsString + { + static inline std::string convert(const TypeCode *t,PyObject* o,void*) + { + if (PyString_Check(o)) + return PyString_AS_STRING(o); + else + { + stringstream msg; + msg << "Not a python string. kind=" << t->kind() ; + msg << " ( " << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); + } + } + }; + template + struct convertToYacsBool + { + static inline bool convert(const TypeCode *t,PyObject* o,void*) + { + bool l; + if (PyBool_Check(o)) + l=(o==Py_True); + else if (PyInt_Check(o)) + l=(PyInt_AS_LONG(o)!=0); + else if(PyLong_Check(o)) + l=(PyLong_AsLong(o)!=0); + else + { + stringstream msg; + msg << "Problem in Python to xml conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + return l; + } + }; + template + struct convertToYacsObjref + { + static inline std::string convert(const TypeCode *t,PyObject* o,void*) + { + if (PyString_Check(o)) + { + // the objref is used by Python as a string (prefix:value) keep it as a string + return PyString_AS_STRING(o); + } + PyObject *pystring=PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),"object_to_string","O",o); + std::string mystr=PyString_AsString(pystring); + Py_DECREF(pystring); + return mystr; + } + }; + template + struct convertToYacsSequence + { + static inline void convert(const TypeCode *t,PyObject* o,void*,std::vector& v) + { + int length=PySequence_Size(o); + DEBTRACE("length: " << length ); + v.resize(length); + for(int i=0;iob_refcnt ); + TOUT ro=YacsConvertor(t->contentType(),item,0); + v[i]=ro; + Py_DECREF(item); + } + } + }; + template + struct convertToYacsStruct + { + static inline void convert(const TypeCode *t,PyObject* o,void*,std::map& m) + { + DEBTRACE( "o refcnt: " << o->ob_refcnt ); + PyObject *key, *value; + YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t; + int nMember=tst->memberCount(); + DEBTRACE("nMember="<memberName(i); + DEBTRACE("Member name="<memberType(i); + value=PyDict_GetItemString(o, name.c_str()); + if(value==NULL) + { + //member name not present + //TODO delete all allocated objects in m +#ifdef _DEVDEBUG_ + PyObject_Print(o,stderr,Py_PRINT_RAW); + std::cerr << std::endl; +#endif + stringstream msg; + msg << "Problem in conversion: member " << name << " not present " << endl; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); + } + DEBTRACE( "value refcnt: " << value->ob_refcnt ); + TOUT ro=YacsConvertor(tm,value,0); + m[name]=ro; + } + } + }; + /* End of ToYacs Convertor for PYTHONImpl */ - /* - * Fonctions de test d'adaptation pour conversion CORBA::Any * (t1) -> PyObject * (t2) + //! FromYacs Convertor for PYTHONImpl + /*! + * Convert YACS intermediate types to PyObject* types (PYTHONImpl) */ - //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) + template <> + struct convertFromYacsDouble + { + static inline PyObject* convert(const TypeCode *t,double o) + { + PyObject *pyob=PyFloat_FromDouble(o); + return pyob; + } + }; + template <> + struct convertFromYacsInt + { + static inline PyObject* convert(const TypeCode *t,long o) + { + PyObject *pyob=PyLong_FromLong(o); + return pyob; + } + }; + template <> + struct convertFromYacsString { - if(t1->kind() == String)return 1; - return 0; - } - - int isAdaptablePyObjectCorbaObjref(TypeCode *t1,TypeCode* t2) + static inline PyObject* convert(const TypeCode *t,std::string& o) + { + return PyString_FromString(o.c_str()); + } + }; + template <> + struct convertFromYacsBool { - 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, + static inline PyObject* convert(const TypeCode *t,bool o) + { + return PyBool_FromLong ((long)o); + } + }; + template <> + struct convertFromYacsObjref + { + static inline PyObject* convert(const TypeCode *t,std::string& o) + { + std::string::size_type pos=o.find_first_of(":"); + std::string prefix=o.substr(0,pos); + DEBTRACE(prefix); + if(prefix == "file") + { + //It's an objref file. Convert it specially + return PyString_FromString(o.c_str()); + } + /* another way + PyObject* ob= PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),"string_to_object","s",o.c_str()); + DEBTRACE( "Objref python refcnt: " << ob->ob_refcnt ); + return ob; + */ + + //Objref CORBA. prefix=IOR,corbaname,corbaloc + CORBA::Object_var obref; + try + { + obref = getSALOMERuntime()->getOrb()->string_to_object(o.c_str()); +#ifdef REFCNT + DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount); +#endif + } + catch(CORBA::Exception& ex) + { + DEBTRACE( "Can't get reference to object." ); + throw ConversionException("Can't get reference to object"); + } + + if( CORBA::is_nil(obref) ) + { + DEBTRACE( "Can't get reference to object (or it was nil)." ); + throw ConversionException("Can't get reference to object"); + } + + if(!obref->_is_a(t->id())) + { + stringstream msg; + msg << "Problem in conversion: an objref " << t->id() << " is expected " << endl; + msg << "An objref of type " << obref->_PD_repoId << " is given " << endl; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); + } + //hold_lock is true: caller is supposed to hold the GIL. + //omniorb will not take the GIL +#ifdef REFCNT + DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount); +#endif + PyObject* ob= getSALOMERuntime()->getApi()->cxxObjRefToPyObjRef(obref, 1); +#ifdef REFCNT + DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount); +#endif + return ob; + } }; - int isAdaptablePyObjectCorba(TypeCode *t1,TypeCode *t2) - { - int tk=t2->kind(); - return isAdaptablePyObjectCorbaFns[tk](t1,t2); - } + template <> + struct convertFromYacsSequence + { + static inline PyObject* convert(const TypeCode *t,std::vector& v) + { + std::vector::const_iterator iter; + PyObject *pyob = PyList_New(v.size()); + int i=0; + for(iter=v.begin();iter!=v.end();iter++) + { + PyObject* item=*iter; + DEBTRACE( "item refcnt: " << item->ob_refcnt ); + PyList_SetItem(pyob,i,item); + DEBTRACE( "item refcnt: " << item->ob_refcnt ); + i++; + } + return pyob; + } + }; + template <> + struct convertFromYacsStruct + { + static inline PyObject* convert(const TypeCode *t,std::map& m) + { + PyObject *pyob = PyDict_New(); + std::map::const_iterator pt; + for(pt=m.begin();pt!=m.end();pt++) + { + std::string name=(*pt).first; + PyObject* item=(*pt).second; + DEBTRACE( "item refcnt: " << item->ob_refcnt ); + PyDict_SetItemString(pyob,name.c_str(),item); + Py_DECREF(item); + DEBTRACE( "item refcnt: " << item->ob_refcnt ); + } + DEBTRACE( "pyob refcnt: " << pyob->ob_refcnt ); + return pyob; + } + }; + /* End of FromYacs Convertor for PYTHONImpl */ - /* - * Fin des fonctions d'adaptation pour conversion CORBA::Any * -> PyObject * + //! ToYacs Convertor for XMLImpl + /*! + * Partial specialization for XML implementation (XMLImpl) + * This convertor converts xml object to YACS types */ + template + struct convertToYacsDouble + { + static inline double convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) + { + double d; + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"double"))) + { + //wait a double, got a double + xmlChar * s = NULL; + s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + DEBTRACE( "convertToYacsDouble " << (const char *)s ); + d=Cstr2d((const char *)s); + xmlFree(s); + return d; + } + else if ((!xmlStrcmp(cur->name, (const xmlChar *)"int"))) + { + //wait a double, got an int + xmlChar * s = NULL; + s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + DEBTRACE( "convertToYacsDouble " << (const char *)s ); + d=Cstr2d((const char *)s); + xmlFree(s); + return d; + } + cur = cur->next; + } + stringstream msg; + msg << "Problem in Xml to TOUT conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsInt + { + static inline long convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) + { + long d; + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"int"))) + { + //wait a double, got an int + xmlChar * s = NULL; + s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + DEBTRACE( "convertToYacsInt " << (const char *)s ); + d=atol((const char *)s); + xmlFree(s); + return d; + } + cur = cur->next; + } + stringstream msg; + msg << "Problem in Xml to TOUT conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsString + { + static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) + { + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"string"))) + { + //wait a string, got a string + xmlChar * s = NULL; + s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + if(s==0)return ""; + DEBTRACE( "convertToYacsString " << (const char *)s ); + std::string mystr=std::string((const char *)s); + xmlFree(s); + return mystr; + } + cur = cur->next; + } + stringstream msg; + msg << "Problem in Xml to TOUT conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsBool + { + static inline bool convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) + { + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"boolean"))) + { + //wait a boolean, got a boolean + xmlChar * s = NULL; + s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + DEBTRACE( "convertToYacsBool " << (const char *)s ); + bool ob=atoi((const char*)s)!=0; + xmlFree(s); + return ob; + } + cur = cur->next; + } + stringstream msg; + msg << "Problem in Xml to TOUT conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsObjref + { + static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) + { + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"objref"))) + { + //we wait a objref, we have got a objref + xmlChar * s = NULL; + s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + DEBTRACE( "convertToYacsObjref " << (const char *)s ); + std::string mystr((const char *)s); + xmlFree(s); + return mystr; + } + cur = cur->next; + } + stringstream msg; + msg << "Problem in conversion: a objref is expected " ; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsSequence + { + static inline void convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,std::vector& v) + { + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"array"))) + { + DEBTRACE( "parse sequence " ); + xmlNodePtr cur1=cur->xmlChildrenNode; + while (cur1 != NULL) + { + if ((!xmlStrcmp(cur1->name, (const xmlChar *)"data"))) + { + DEBTRACE( "parse data " ); + xmlNodePtr cur2=cur1->xmlChildrenNode; + while (cur2 != NULL) + { + //collect all values + if ((!xmlStrcmp(cur2->name, (const xmlChar *)"value"))) + { + TOUT ro=YacsConvertor(t->contentType(),doc,cur2); + v.push_back(ro); + } + cur2 = cur2->next; + } // end while value + break; + } + cur1 = cur1->next; + } // end while data + break; + } + cur = cur->next; + } // end while array + } + }; + template + struct convertToYacsStruct + { + static inline void convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,std::map& m) + { + YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t; + int nMember=tst->memberCount(); + DEBTRACE("nMember="< mtc; + for(int i=0;imemberName(i)]=tst->memberType(i); + } + + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"struct"))) + { + DEBTRACE( "parse struct " ); + xmlNodePtr cur1=cur->xmlChildrenNode; + while (cur1 != NULL) + { + if ((!xmlStrcmp(cur1->name, (const xmlChar *)"member"))) + { + DEBTRACE( "parse member " ); + xmlNodePtr cur2=cur1->xmlChildrenNode; + while (cur2 != NULL) + { + //member name + if ((!xmlStrcmp(cur2->name, (const xmlChar *)"name"))) + { + xmlChar * s = NULL; + s = xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1); + std::string name= (char *)s; + cur2 = cur2->next; + while (cur2 != NULL) + { + if ((!xmlStrcmp(cur2->name, (const xmlChar *)"value"))) + { + TOUT ro=YacsConvertor(mtc[name],doc,cur2); + m[name]=ro; + break; + } + cur2 = cur2->next; + } + xmlFree(s); + break; + } + cur2 = cur2->next; + } // end while member/value + } + cur1 = cur1->next; + } // end while member + break; + } + cur = cur->next; + } // end while struct + } + }; + /* End of ToYacs Convertor for XMLImpl */ - /* - * Fonctions de conversion CORBA::Any * -> PyObject * + //! FromYacs Convertor for XMLImpl + /*! + * Convert YACS intermediate types to std::string types (XMLImpl) */ - //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) + template <> + struct convertFromYacsDouble + { + static inline std::string convert(const TypeCode *t,double o) + { + stringstream msg ; + msg << "" << o << "\n"; + return msg.str(); + } + }; + template <> + struct convertFromYacsInt + { + static inline std::string convert(const TypeCode *t,long o) + { + stringstream msg ; + msg << "" << o << "\n"; + return msg.str(); + } + }; + template <> + struct convertFromYacsString + { + static inline std::string convert(const TypeCode *t,std::string& o) + { + std::string msg=""; + return msg+o+"\n"; + } + }; + template <> + struct convertFromYacsBool + { + static inline std::string convert(const TypeCode *t,bool o) + { + stringstream msg ; + msg << "" << o << "\n"; + return msg.str(); + } + }; + template <> + struct convertFromYacsObjref { - stringstream msg; - msg << "Conversion not implemented: kind= " << t->kind() ; - msg << " : " << __FILE__ << ":" << __LINE__; - throw YACS::Exception(msg.str()); - } + static inline std::string convert(const TypeCode *t,std::string& o) + { + return "" + o + "\n"; + } + }; - //kind=1 - //Convertit un CORBA::Any "equivalent double" en Python double + template <> + struct convertFromYacsSequence + { + static inline std::string convert(const TypeCode *t,std::vector& v) + { + std::vector::const_iterator iter; + stringstream xmlob; + xmlob << "\n"; + for(iter=v.begin();iter!=v.end();iter++) + { + xmlob << *iter; + } + xmlob << "\n"; + DEBTRACE("Sequence= " << xmlob); + return xmlob.str(); + } + }; + template <> + struct convertFromYacsStruct + { + static inline std::string convert(const TypeCode *t,std::map& m) + { + std::string result="\n"; + std::map::const_iterator pt; + for(pt=m.begin();pt!=m.end();pt++) + { + std::string name=(*pt).first; + std::string item=(*pt).second; + result=result+"\n"; + result=result+""+name+"\n"; + result=result+item; + result=result+"\n"; + } + result=result+"\n"; + return result; + } + }; - 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()); - } + /* End of FromYacs Convertor for XMLImpl */ - PyObject *convertPyObjectCorbaInt(TypeCode *t,CORBA::Any *ob) + //! ToYacs Convertor for NEUTRALImpl + /*! + * This convertor converts Neutral objects to intermediate YACS types + * Template : Partial specialization for Neutral implementation with types YACS::ENGINE::Any* + */ + template + struct convertToYacsDouble + { + static inline double convert(const TypeCode *t,YACS::ENGINE::Any* o,void*) + { + if(o->getType()->kind()==Double) + return o->getDoubleValue(); + else if(o->getType()->kind()==Int) + return o->getIntValue(); + + stringstream msg; + msg << "Problem in conversion: a double or int is expected " ; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsInt { - CORBA::Long l; - *ob >>= l; - return PyInt_FromLong(l); - } - - PyObject *convertPyObjectCorbaString(TypeCode *t,CORBA::Any *ob) + static inline long convert(const TypeCode *t,YACS::ENGINE::Any* o,void*) + { + return o->getIntValue(); + } + }; + template + struct convertToYacsString { - 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) + static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*) + { + return o->getStringValue(); + } + }; + template + struct convertToYacsBool + { + static inline bool convert(const TypeCode *t,YACS::ENGINE::Any* o,void*) + { + if(o->getType()->kind()==Bool) + return o->getBoolValue(); + else if(o->getType()->kind()==Int) + return o->getIntValue() != 0; + stringstream msg; + msg << "Problem in conversion: a bool or int is expected " ; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + } + }; + template + struct convertToYacsObjref { - int tk=t->kind(); - return convertPyObjectCorbaFns[tk](t,ob); - } - - /* - * Fin des fonctions de conversion CORBA::Any * -> PyObject * - */ + static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*) + { + return o->getStringValue(); + } + }; + template + struct convertToYacsSequence + { + static inline void convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,std::vector& v) + { + SequenceAny* sdata= (SequenceAny*)o; + int length=sdata->size(); + v.resize(length); + for(int i=0;i(t->contentType(),(*sdata)[i],0); + v[i]=ro; + } + } + }; + /* End of ToYacs Convertor for NEUTRALImpl */ - /* - * Fonctions de conversion CORBA::Any * -> Xml char * + //! FromYacs Convertor for NEUTRALImpl + /*! + * Convert YACS intermediate types to YACS::ENGINE::Any* types (NEUTRALImpl) */ - //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) + template <> + struct convertFromYacsDouble + { + static inline YACS::ENGINE::Any* convert(const TypeCode *t,double o) + { + YACS::ENGINE::Any *ob=YACS::ENGINE::AtomAny::New(o); + return ob; + } + }; + template <> + struct convertFromYacsInt { - 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) + static inline YACS::ENGINE::Any* convert(const TypeCode *t,long o) + { + return YACS::ENGINE::AtomAny::New((int)o); + } + }; + template <> + struct convertFromYacsString { - CORBA::Long l; - *ob >>= l; - stringstream msg ; - msg << "" << l << "\n"; - return (char *)msg.str().c_str(); - } - - char *convertXmlCorbaString(TypeCode *t,CORBA::Any *ob) + static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::string& o) + { + return YACS::ENGINE::AtomAny::New(o); + } + }; + template <> + struct convertFromYacsBool { - char *s; - *ob >>=s; - stringstream msg ; - msg << "" << s << "\n"; - return (char *)msg.str().c_str(); - } - - char *convertXmlCorbaObjref(TypeCode *t,CORBA::Any *ob) + static inline YACS::ENGINE::Any* convert(const TypeCode *t,bool o) + { + return YACS::ENGINE::AtomAny::New(o); + } + }; + template <> + struct convertFromYacsObjref { - 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, - }; + static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::string& o) + { + return YACS::ENGINE::AtomAny::New(o); + } + }; - char *convertXmlCorba(TypeCode *t,CORBA::Any *ob) - { - int tk=t->kind(); - return convertXmlCorbaFns[tk](t,ob); - } + template <> + struct convertFromYacsSequence + { + static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::vector& v) + { + std::vector::const_iterator iter; + //Objref are managed as string within YACS::ENGINE::Any objs + SequenceAny* any; + any=SequenceAny::New(t->contentType()); + for(iter=v.begin();iter!=v.end();iter++) + { + any->pushBack(*iter); + (*iter)->decrRef(); + } + DEBTRACE( "refcnt: " << any->getRefCnt() ); + return any; + } + }; + /* End of FromYacs Convertor for NEUTRALImpl */ - /* - * Fin des fonctions de conversion CORBA::Any * -> Xml char * + //! ToYacs Convertor for CORBAImpl + /*! + * This convertor converts Corba objects to intermediate YACS types + * Template : Partial specialization for CORBA implementation with types CORBA::Any* */ + template + struct convertToYacsDouble + { + static inline double convert(const TypeCode *t,CORBA::Any* o,void*) + { + CORBA::TypeCode_var tc = o->type(); + if (tc->equivalent(CORBA::_tc_double)) + { + CORBA::Double d; + *o >>= d; + return d; + } + if (tc->equivalent(CORBA::_tc_long)) + { + CORBA::Long d; + *o >>= d; + return d; + } + stringstream msg; + msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsInt + { + static inline long convert(const TypeCode *t,CORBA::Any* o,void*) + { + CORBA::Long d; + *o >>= d; + return d; + } + }; + template + struct convertToYacsString + { + static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*) + { + const char *s; + *o >>=s; + return s; + } + }; + template + struct convertToYacsBool + { + static inline bool convert(const TypeCode *t,CORBA::Any* o,void*) + { + CORBA::Boolean b; + if(*o >>= CORBA::Any::to_boolean(b)) + return b; + stringstream msg; + msg << "Problem in Corba to TOUT conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsObjref + { + static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*) + { + CORBA::Object_var ObjRef ; + *o >>= (CORBA::Any::to_object ) ObjRef ; + CORBA::String_var objref = getSALOMERuntime()->getOrb()->object_to_string(ObjRef); + return (char *)objref; + } + }; + template + struct convertToYacsSequence + { + static inline void convert(const TypeCode *t,CORBA::Any* o,void*,std::vector& v) + { + CORBA::TypeCode_var tc=o->type(); + if (tc->kind() != CORBA::tk_sequence) + { + stringstream msg; + msg << "Not a sequence corba type " << tc->kind(); + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + DynamicAny::DynAny_ptr dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any(*o); + DynamicAny::DynSequence_ptr ds=DynamicAny::DynSequence::_narrow(dynany); + CORBA::release(dynany); + DynamicAny::AnySeq_var as=ds->get_elements(); + int len=as->length(); + v.resize(len); + for(int i=0;ipd_ref_count); +#endif + TOUT ro=YacsConvertor(t->contentType(),&as[i],0); + v[i]=ro; + } + ds->destroy(); + CORBA::release(ds); + for(int i=0;ipd_ref_count); +#endif + } + } + }; + template + struct convertToYacsStruct + { + static inline void convert(const TypeCode *t,CORBA::Any* o,void*,std::map& m) + { + CORBA::TypeCode_var tc=o->type(); + DEBTRACE(tc->kind()); + if (tc->kind() != CORBA::tk_struct) + { + stringstream msg; + msg << "Not a struct corba type " << tc->kind(); + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t; + DynamicAny::DynAny_ptr dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any(*o); + DynamicAny::DynStruct_ptr ds=DynamicAny::DynStruct::_narrow(dynany); + CORBA::release(dynany); + DynamicAny::NameValuePairSeq_var as=ds->get_members(); + int len=as->length(); + for(int i=0;ipd_ref_count); +#endif + TOUT ro=YacsConvertor(tst->memberType(i),&value,0); + m[name]=ro; + } + ds->destroy(); + CORBA::release(ds); + } + }; + /* End of ToYacs Convertor for CORBAImpl */ - /* - * Fonctions de conversion CORBA::Any * -> CORBA::Any * + //! FromYacs Convertor for CORBAImpl + /*! + * Convert YACS intermediate types to CORBA::Any* types (CORBAImpl) */ - //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()); + template <> + struct convertFromYacsDouble + { + static inline CORBA::Any* convert(const TypeCode *t,double o) + { + CORBA::Any *any = new CORBA::Any(); + *any <<= o; + return any; + } + }; + template <> + struct convertFromYacsInt + { + static inline CORBA::Any* convert(const TypeCode *t,long o) + { + CORBA::Any *any = new CORBA::Any(); + *any <<= o; + return any; + } + }; + template <> + struct convertFromYacsString + { + static inline CORBA::Any* convert(const TypeCode *t,std::string& o) + { + CORBA::Any *any = new CORBA::Any(); + *any <<= o.c_str(); + return any; + } + }; + template <> + struct convertFromYacsBool + { + static inline CORBA::Any* convert(const TypeCode *t,bool o) + { + CORBA::Any *any = new CORBA::Any(); + *any <<= CORBA::Any::from_boolean(o); + return any; + } + }; + template <> + struct convertFromYacsObjref + { + static inline CORBA::Any* convert(const TypeCode *t,std::string& o) + { + /* + std::string::size_type pos=o.find_first_of(":"); + std::string prefix=o.substr(0,pos); + DEBTRACE(prefix); + if(prefix == "file") + { + //It's an objref file. Convert it specially + } + */ + CORBA::Object_var obref = + getSALOMERuntime()->getOrb()->string_to_object(o.c_str()); +#ifdef REFCNT + DEBTRACE("ObjRef refCount: " << obref->_PR_getobj()->pd_refCount); +#endif + CORBA::Any *any = new CORBA::Any(); + *any <<= obref; +#ifdef REFCNT + DEBTRACE("ObjRef refCount: " << obref->_PR_getobj()->pd_refCount); +#endif + return any; + } }; - //kind=1 - //Convertit un CORBA::Any "equivalent double" en Python double + template <> + struct convertFromYacsSequence + { + static inline CORBA::Any* convert(const TypeCode *t,std::vector& v) + { + CORBA::Any *any; + CORBA::TypeCode_ptr seqTC; + + //the equivalent CORBA TypeCode + seqTC=getCorbaTC(t); +#ifdef REFCNT + DEBTRACE("refcount CORBA seqTC: " << ((omni::TypeCode_base*)seqTC)->pd_ref_count); +#endif + DynamicAny::DynAny_ptr dynany = + getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(seqTC); + CORBA::release(seqTC); + DynamicAny::DynSequence_ptr ds = + DynamicAny::DynSequence::_narrow(dynany); + CORBA::release(dynany); + + std::vector::const_iterator iter; + DynamicAny::AnySeq as ; + as.length(v.size()); + int i=0; + for(iter=v.begin();iter!=v.end();iter++) + { + //Can we avoid making a copy ? + CORBA::Any* a=*iter; + as[i]=*a; + i++; + //delete intermediate any + delete a; + } + try + { + ds->set_elements(as); + } + catch(DynamicAny::DynAny::TypeMismatch& ex) + { + throw YACS::ENGINE::ConversionException("type mismatch"); + } + catch(DynamicAny::DynAny::InvalidValue& ex) + { + throw YACS::ENGINE::ConversionException("invalid value"); + } + any=ds->to_any(); + ds->destroy(); + CORBA::release(ds); +#ifdef REFCNT + DEBTRACE("refcount CORBA seqTC: " << ((omni::TypeCode_base*)seqTC)->pd_ref_count); +#endif + return any; + } + }; + template <> + struct convertFromYacsStruct + { + static inline CORBA::Any* convert(const TypeCode *t,std::map& m) + { + CORBA::Any *any; + CORBA::TypeCode_ptr structTC; + + //the equivalent CORBA TypeCode + structTC=getCorbaTC(t); +#ifdef REFCNT + DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); + DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); +#endif + YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t; + int nMember=tst->memberCount(); + DEBTRACE("nMember="<getDynFactory()->create_dyn_any_from_type_code(structTC); +#ifdef REFCNT + DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); + DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); +#endif + CORBA::release(structTC); +#ifdef REFCNT + DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); + DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); +#endif + DynamicAny::DynStruct_ptr ds=DynamicAny::DynStruct::_narrow(da); + CORBA::release(da); +#ifdef REFCNT + DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); + DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); +#endif + DynamicAny::NameValuePairSeq members; + members.length(nMember); + for(int i=0;imemberName(i); + DEBTRACE("Member name="<memberType(i); + //do not test member presence : test has been done in ToYacs convertor + CORBA::Any* a=m[name]; + members[i].id=CORBA::string_dup(name); + members[i].value=*a; + //delete intermediate any + delete a; + } +#ifdef REFCNT + DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); + DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); +#endif + ds->set_members(members); +#ifdef REFCNT + DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); + DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); +#endif + any=ds->to_any(); +#ifdef REFCNT + DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); + DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); +#endif + ds->destroy(); + CORBA::release(ds); +#ifdef REFCNT + DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count); + DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count); +#endif + return any; + } + }; + /* End of FromYacs Convertor for CORBAImpl */ - CORBA::Any *convertCorbaCorbaDouble(TypeCode *t,CORBA::Any *ob) + /* Some shortcuts for CORBA to CORBA conversion */ + template <> + inline CORBA::Any* convertDouble(const TypeCode *t,CORBA::Any* o,void* aux) { - CORBA::TypeCode_var tc = ob->type(); - if (tc->equivalent(CORBA::_tc_double)) - { - return ob; - } + CORBA::TypeCode_var tc = o->type(); + if (tc->equivalent(CORBA::_tc_double)) + { + return o; + } if (tc->equivalent(CORBA::_tc_long)) - { - CORBA::Long d; - *ob >>= d; - CORBA::Any *any = new CORBA::Any(); - *any <<= (CORBA::Double)d; - return any; - } + { + CORBA::Long d; + *o >>= d; + CORBA::Any *any = new CORBA::Any(); + *any <<= (CORBA::Double)d; + return any; + } stringstream msg; - msg << "Internal error " ; + msg << "Not a double or long corba type " << tc->kind(); msg << " : " << __FILE__ << ":" << __LINE__; - throw YACS::Exception(msg.str()); + throw YACS::ENGINE::ConversionException(msg.str()); } - - CORBA::Any *convertCorbaCorbaInt(TypeCode *t,CORBA::Any *ob) + template <> + inline CORBA::Any* convertInt(const TypeCode *t,CORBA::Any* o,void* aux) { - return ob; + return o; } - - CORBA::Any *convertCorbaCorbaString(TypeCode *t,CORBA::Any *ob) + template <> + inline CORBA::Any* convertString(const TypeCode *t,CORBA::Any* o,void* aux) { - return ob; + return o; } - - CORBA::Any *convertCorbaCorbaObjref(TypeCode *t,CORBA::Any *ob) + template <> + inline CORBA::Any* convertBool(const TypeCode *t,CORBA::Any* o,void* aux) { - return ob; + return o; } - - 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; + template <> + inline CORBA::Any* convertObjref(const TypeCode *t,CORBA::Any* o,void* aux) + { + return o; } - - - convertCorbaCorbaFn convertCorbaCorbaFns[]= - { - convertCorbaCorbaNull, - convertCorbaCorbaDouble, - convertCorbaCorbaInt, - convertCorbaCorbaString, - convertCorbaCorbaNull, - convertCorbaCorbaObjref, - convertCorbaCorbaSequence, - }; - - CORBA::Any *convertCorbaCorba(TypeCode *t,CORBA::Any *ob) + template <> + inline CORBA::Any* convertStruct(const TypeCode *t,CORBA::Any* o,void* aux) { - int tk=t->kind(); - return convertCorbaCorbaFns[tk](t,ob); + return o; } + /* End of shortcuts for CORBA to CORBA conversion */ - /* - * Fin des fonctions de conversion CORBA::Any * -> PyObject * - */ - - /* - * Fonctions de conversion Xml char * -> CORBA::Any * + //! ToYacs Convertor for CPPImpl + /*! + * This convertor converts Python object to YACS types + * Partial specialization for Python implementation with type PyObject* (PYTHONImpl) */ + template + struct convertToYacsDouble + { + static inline double convert(const TypeCode *t,void* o,const TypeCode* intype) + { + if(intype->kind()==YACS::ENGINE::Double) + { + return *(double*)o; + } + else if(intype->kind()==YACS::ENGINE::Int) + { + return *(long*)o; + } + stringstream msg; + msg << "Problem in Cpp to TOUT conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + template + struct convertToYacsInt + { + static inline long convert(const TypeCode *t,void* o,const TypeCode* intype) + { + if(intype->kind()==YACS::ENGINE::Int) + { + return *(long*)o; + } + stringstream msg; + msg << "Problem in Cpp to TOUT conversion: kind= " << t->kind() ; + msg << " : " << __FILE__ << ":" << __LINE__; + throw YACS::ENGINE::ConversionException(msg.str()); + } + }; + /* End of ToYacs Convertor for CPPImpl */ - //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 + //Python conversions + std::string convertPyObjectXml(const TypeCode *t,PyObject *data) { - dsout->set_elements(as); + return YacsConvertor(t,data,0); } - catch(DynamicAny::DynAny::TypeMismatch& ex) + YACS::ENGINE::Any* convertPyObjectNeutral(const TypeCode *t,PyObject *data) { - throw YACS::Exception("type mismatch"); + return YacsConvertor(t,data,0); } - catch(DynamicAny::DynAny::InvalidValue& ex) + CORBA::Any* convertPyObjectCorba(const TypeCode *t,PyObject *data) { - throw YACS::Exception("invalid value"); + return YacsConvertor(t,data,0); } - CORBA::Any *any=dsout->to_any(); - return any; - } - convertCorbaXmlFn convertCorbaXmlFns[]= + //XML conversions + PyObject* convertXmlPyObject(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) { - 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 * - */ + return YacsConvertor(t,doc,cur); + } + YACS::ENGINE::Any* convertXmlNeutral(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) + { + return YacsConvertor(t,doc,cur); + } + CORBA::Any* convertXmlCorba(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur) + { + return YacsConvertor(t,doc,cur); + } + //NEUTRAL conversions + PyObject* convertNeutralPyObject(const TypeCode *t,YACS::ENGINE::Any* data) + { + return YacsConvertor(t,data,0); + } + std::string convertNeutralXml(const TypeCode *t,YACS::ENGINE::Any* data) + { + return YacsConvertor(t,data,0); + } + CORBA::Any* convertNeutralCorba(const TypeCode *t,YACS::ENGINE::Any* data) + { + return YacsConvertor(t,data,0); + } + YACS::ENGINE::Any *convertNeutralNeutral(const TypeCode *t, YACS::ENGINE::Any* data) + { + data->incrRef(); + return data; + } + //CORBA conversions + PyObject* convertCorbaPyObject(const TypeCode *t,CORBA::Any* data) + { + return YacsConvertor(t,data,0); + } + std::string convertCorbaXml(const TypeCode *t,CORBA::Any* data) + { + return YacsConvertor(t,data,0); + } + YACS::ENGINE::Any* convertCorbaNeutral(const TypeCode *t,CORBA::Any* data) + { + return YacsConvertor(t,data,0); + } + CORBA::Any *convertCorbaCorba(const TypeCode *t,CORBA::Any *data) + { + return YacsConvertor(t,data,0); + } } } diff --git a/src/runtime/TypeConversions.hxx b/src/runtime/TypeConversions.hxx index a26496594..e04f1b9e8 100644 --- a/src/runtime/TypeConversions.hxx +++ b/src/runtime/TypeConversions.hxx @@ -5,47 +5,59 @@ #include #include #include - -#include "TypeCode.hxx" +#include "Any.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 enum + { + CORBAImpl = 1, + PYTHONImpl = 2, + NEUTRALImpl = 3, + XMLImpl = 4, + CPPImpl = 5, + } ImplType; - typedef int (*isAdaptableCorbaPyObjectFn)(TypeCode *,TypeCode* ); - int isAdaptableCorbaPyObject(TypeCode* t1,TypeCode* t2); + class TypeCode; - typedef int (*isAdaptableXmlCorbaFn)(TypeCode *,TypeCode* ); - int isAdaptableXmlCorba(TypeCode *t1,TypeCode *t2); + CORBA::TypeCode_ptr getCorbaTC(const TypeCode *t); - typedef int (*isAdaptableCorbaCorbaFn)(TypeCode *,TypeCode* ); - int isAdaptableCorbaCorba(TypeCode* t1,TypeCode* t2); + int isAdaptableCorbaPyObject(const TypeCode * t1, const TypeCode * t2); + int isAdaptableCorbaNeutral(const TypeCode * t1, const TypeCode * t2); + int isAdaptableCorbaCorba(const TypeCode * t1, const TypeCode * t2); - typedef int (*isAdaptablePyObjectPyObjectFn)(TypeCode *,TypeCode* ); - int isAdaptablePyObjectPyObject(TypeCode* t1,TypeCode* t2); + int isAdaptableNeutralCorba(const TypeCode * t1, const TypeCode * t2); + int isAdaptableNeutralNeutral(const TypeCode * t1, const TypeCode * t2); + int isAdaptableNeutralXml(const TypeCode * t1, const TypeCode * t2); + int isAdaptableNeutralPyObject(const TypeCode * t1, const TypeCode * t2); - typedef int (*isAdaptablePyObjectCorbaFn)(TypeCode *,TypeCode* ); - int isAdaptablePyObjectCorba(TypeCode* t1,TypeCode* t2); + int isAdaptablePyObjectPyObject(const TypeCode * t1, const TypeCode * t2); + int isAdaptablePyObjectCorba(const TypeCode * t1, const TypeCode * t2); + int isAdaptablePyObjectNeutral(const TypeCode * t1, const TypeCode * t2); - typedef PyObject* (*convertPyObjectCorbaFn)(TypeCode *,CORBA::Any* ); - PyObject *convertPyObjectCorba(TypeCode* t,CORBA::Any* ob); + int isAdaptableXmlNeutral(const TypeCode *t1,const TypeCode *t2); + int isAdaptableXmlCorba(const TypeCode *t1, const TypeCode *t2); - typedef char* (*convertXmlCorbaFn)(TypeCode *,CORBA::Any* ); - char *convertXmlCorba(TypeCode* t,CORBA::Any* ob); + PyObject *convertCorbaPyObject(const TypeCode * t,CORBA::Any* ob); + CORBA::Any *convertCorbaCorba(const TypeCode * t,CORBA::Any* ob); + YACS::ENGINE::Any *convertCorbaNeutral(const TypeCode *t,CORBA::Any* ob); + std::string convertCorbaXml(const TypeCode * t,CORBA::Any* ob); - typedef CORBA::Any* (*convertCorbaCorbaFn)(TypeCode *,CORBA::Any* ); - CORBA::Any *convertCorbaCorba(TypeCode* t,CORBA::Any* ob); + CORBA::Any *convertPyObjectCorba(const TypeCode *t,PyObject *ob); + std::string convertPyObjectXml(const TypeCode * t,PyObject* ob); + YACS::ENGINE::Any *convertPyObjectNeutral(const TypeCode *t,PyObject* ob); - typedef CORBA::Any* (*convertCorbaXmlFn)(TypeCode *,xmlDocPtr doc,xmlNodePtr cur); - CORBA::Any *convertCorbaXml(TypeCode* t,xmlDocPtr doc,xmlNodePtr cur ); + PyObject *convertXmlPyObject(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur ); + CORBA::Any *convertXmlCorba(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur ); + YACS::ENGINE::Any *convertXmlNeutral(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur ); + PyObject *convertNeutralPyObject(const TypeCode * t,YACS::ENGINE::Any* ob); + std::string convertNeutralXml(const TypeCode * t,YACS::ENGINE::Any* ob); + CORBA::Any *convertNeutralCorba(const TypeCode *t,YACS::ENGINE::Any *ob); + YACS::ENGINE::Any *convertNeutralNeutral(const TypeCode *t, YACS::ENGINE::Any* ob); } } diff --git a/src/runtime/XMLCORBAConv.cxx b/src/runtime/XMLCORBAConv.cxx index 41116c793..608d8d66e 100644 --- a/src/runtime/XMLCORBAConv.cxx +++ b/src/runtime/XMLCORBAConv.cxx @@ -1,51 +1,84 @@ +#include "TypeConversions.hxx" #include "XMLCORBAConv.hxx" #include "CORBAXMLConv.hxx" -#include "TypeConversions.hxx" #include #include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" using namespace YACS::ENGINE; using namespace std; XmlCorba::XmlCorba(InputCorbaPort* p) - : ProxyPort(p), Port(p->getNode()) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), 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; + DEBTRACE((const char *)data); put((const char *)data); } -//!Convertit la valeur XML (char *) recue en CORBA::Any et la transmet au proxy port +//!Convert a XML (char *) to CORBA::Any and push it in the proxy port /*! * \param data : Xml::char * */ - void XmlCorba::put(const char *data) throw(ConversionException) { - cerr << "XmlCorba::put " << data << endl; + DEBTRACE(data); xmlDocPtr doc; xmlNodePtr cur; CORBA::Any *a; doc = xmlParseMemory(data, strlen(data)); + if (doc == NULL ) + { + stringstream msg; + msg << "Problem in conversion: XML Document not parsed successfully "; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } cur = xmlDocGetRootElement(doc); + if (cur == NULL) + { + xmlFreeDoc(doc); + stringstream msg; + msg << "Problem in conversion: empty XML Document"; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"value"))) - { - a=convertCorbaXml(type(),doc,cur); - break; - } + { + try + { + a=convertXmlCorba(edGetType(),doc,cur); + } + catch(ConversionException) + { + throw; + } + catch(...) + { + stringstream msg; + msg << "Problem in conversion: kind= " << edGetType()->kind() ; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } + break; + } cur = cur->next; } xmlFreeDoc(doc); - xmlCleanupParser(); + //xmlCleanupParser(); _port->put(a); - cerr << "Fin XmlCorba" << endl; + _port->setStringRef(data); + //delete Any that has been allocated by convertXmlCorba + delete a; } diff --git a/src/runtime/XMLCORBAConv.hxx b/src/runtime/XMLCORBAConv.hxx index b909c78f7..fd314c5c7 100644 --- a/src/runtime/XMLCORBAConv.hxx +++ b/src/runtime/XMLCORBAConv.hxx @@ -7,7 +7,7 @@ namespace YACS { namespace ENGINE { - //Ports adaptateurs Xml->Corba pour les différents types + //Adaptator Ports Xml->Corba for several types class XmlCorba : public ProxyPort { diff --git a/src/runtime/XMLCppConv.cxx b/src/runtime/XMLCppConv.cxx new file mode 100644 index 000000000..6fd7f7ddf --- /dev/null +++ b/src/runtime/XMLCppConv.cxx @@ -0,0 +1,86 @@ + +#include "TypeConversions.hxx" +#include "XMLCppConv.hxx" + + +#include +#include +#include +#include "Any.hxx" + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; + +namespace YACS +{ + namespace ENGINE + { + Any * convertXmlCpp(const TypeCode *t, xmlDocPtr doc, xmlNodePtr cur) + { + return convertXmlNeutral(t, doc, cur); + } + + XmlCpp::XmlCpp(InputPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) + { + } + + void XmlCpp::put(const void *data) throw(ConversionException) + { + DEBTRACE(" XmlCpp::put(const void *data)"); + put((const char *)data); + } + + //!Convert received XML (char *) value to C++ (Any *) value and send it to proxy port + /*! + * \param data : Xml::char * + */ + + void XmlCpp::put(const char *data) throw(ConversionException) + { + DEBTRACE("XmlCpp::put " << data); + xmlDocPtr doc; + xmlNodePtr cur; + Any *ob; + { + doc = xmlParseMemory(data, strlen(data)); + if (doc == NULL ) + { + stringstream msg; + msg << "Problem in conversion: XML Document not parsed successfully "; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } + cur = xmlDocGetRootElement(doc); + if (cur == NULL) + { + xmlFreeDoc(doc); + stringstream msg; + msg << "Problem in conversion: empty XML Document"; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"value"))) + { + ob=convertXmlCpp(edGetType(),doc,cur); + break; + } + cur = cur->next; + } + xmlFreeDoc(doc); + //xmlCleanupParser(); + } + _port->put(ob); + ob->decrRef(); + } + + int isAdaptableCppXml(const TypeCode *t1, const TypeCode *t2) + { + return isAdaptableNeutralXml(t1, t2); + } + } +} diff --git a/src/runtime/XMLCppConv.hxx b/src/runtime/XMLCppConv.hxx new file mode 100644 index 000000000..9f0e77702 --- /dev/null +++ b/src/runtime/XMLCppConv.hxx @@ -0,0 +1,23 @@ +#ifndef XMLCPPCONV_HXX_ +#define XMLCPPCONV_HXX_ + +#include "CppPorts.hxx" + +namespace YACS +{ + namespace ENGINE + { + //Proxy port to adapt C++ port to XML + + class XmlCpp : public ProxyPort + { + public: + XmlCpp(InputPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(const char *data) throw(ConversionException); + }; + int isAdaptableCppXml(const TypeCode *t1, const TypeCode *t2); + } +} + +#endif /*XMLCPPCONV_HXX_*/ diff --git a/src/runtime/XMLNeutralConv.cxx b/src/runtime/XMLNeutralConv.cxx new file mode 100644 index 000000000..e0d1f40fb --- /dev/null +++ b/src/runtime/XMLNeutralConv.cxx @@ -0,0 +1,70 @@ + +#include "TypeConversions.hxx" +#include "XMLNeutralConv.hxx" + +#include +#include +#include +#include "Any.hxx" + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +XmlNeutral::XmlNeutral(InputPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{ +} + +void XmlNeutral::put(const void *data) throw(ConversionException) +{ + DEBTRACE(" XmlNeutral::put(const void *data)"); + put((const char *)data); +} + +//!Convert received XML (char *) value to Neutral (Any *) value and send it to proxy port + /*! + * \param data : Xml::char * + */ + +void XmlNeutral::put(const char *data) throw(ConversionException) +{ + DEBTRACE("XmlNeutral::put " << data); + xmlDocPtr doc; + xmlNodePtr cur; + YACS::ENGINE::Any *ob; +{ + doc = xmlParseMemory(data, strlen(data)); + if (doc == NULL ) + { + stringstream msg; + msg << "Problem in conversion: XML Document not parsed successfully "; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } + cur = xmlDocGetRootElement(doc); + if (cur == NULL) + { + xmlFreeDoc(doc); + stringstream msg; + msg << "Problem in conversion: empty XML Document"; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"value"))) + { + ob=convertXmlNeutral(edGetType(),doc,cur); + break; + } + cur = cur->next; + } + xmlFreeDoc(doc); + //xmlCleanupParser(); +} + _port->put(ob); + ob->decrRef(); +} diff --git a/src/runtime/XMLNeutralConv.hxx b/src/runtime/XMLNeutralConv.hxx new file mode 100644 index 000000000..f4e610bf8 --- /dev/null +++ b/src/runtime/XMLNeutralConv.hxx @@ -0,0 +1,22 @@ +#ifndef __XMLNEUTRALCONV_HXX__ +#define __XMLNEUTRALCONV_HXX__ + +#include "InputPort.hxx" + +namespace YACS +{ + namespace ENGINE + { + //Proxy port to adapt Neutral port to XML + + class XmlNeutral : public ProxyPort + { + public: + XmlNeutral(InputPort* 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 index c0f3215f6..6265b5eb6 100644 --- a/src/runtime/XMLNode.cxx +++ b/src/runtime/XMLNode.cxx @@ -1,39 +1,317 @@ - #include "XMLNode.hxx" #include "XMLPorts.hxx" +#include "Mutex.hxx" + +#include +#include +#include #include +#include +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" using namespace YACS::ENGINE; using namespace std; -XmlNode::XmlNode(const string& name) - : ElementaryNode(name) +const char XmlNode::IMPL_NAME[]="XML"; +const char XmlNode::KIND[]="xmlsh"; +static YACS::BASES::Mutex MUTEX; + +XmlNode::XmlNode(const XmlNode& other, ComposedNode *father) + : _script(other._script), ServiceNode(other, father) { - _implementation="XML"; - cerr << "XMLNode::XMLNode " << name << endl; + _implementation=IMPL_NAME; + _ref = other._ref; } -void XmlNode::set_script(const string& script) +XmlNode::XmlNode(const std::string& name) + : ServiceNode(name) +{ + _implementation=IMPL_NAME; +} + +Node *XmlNode::simpleClone(ComposedNode *father, bool editionOnly) const +{ + return new XmlNode(*this,father); +} + +void XmlNode::setRef(const std::string& ref) +{ + //No component instance here + _ref=ref; +} + +void XmlNode::setScript(const std::string& script) { _script=script; } +std::string XmlNode::getKind() const +{ + return KIND; +} + void XmlNode::execute() { - cerr << "XmlNode::run" << endl; - cerr << "---------------XmlNode::inputs---------------" << endl; - set::iterator iter; + DEBTRACE("execute"); + char dir[]="yacsXXXXXX"; + // add a lock around mkdtemp (seems not thread safe) + MUTEX.lock(); + char* mdir=mkdtemp(dir); + MUTEX.unlock(); + if(mdir==NULL) + { + perror("mkdtemp failed"); + std::cerr << "Problem in mkdtemp " << dir << " " << mdir << std::endl; + throw Exception("Execution problem in mkdtemp"); + } + std::string sdir(dir); + std::string input=sdir+"/input"; + std::ofstream f(input.c_str()); + f<<" " << _method << " "<::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; + DEBTRACE("port name: " << p->getName()); + DEBTRACE("port kind: " << p->edGetType()->kind()); const char* ob=p->getXml(); - cerr << "Xml: " << ob << endl; - getOutputPort(p->getName())->put(ob); // obligation meme ports en entree et sortie + DEBTRACE("Xml: " << ob ); + f<<"" << ob << ""<"<"< stdout 2>&1 " << std::endl; + else + run << "../"<<_ref << "> stdout 2>&1 " << std::endl; + run << "cat stdout" << std::endl; + run.close(); + chmod(call.c_str(),00777); + + int ret=system(call.c_str()); + if(ret) + { + std::cerr << "Problem: " << ret << std::endl; + DEBTRACE("Problem: " << ret); + throw Exception("Execution problem"); + } + std::string output=sdir+"/output"; + xmlDocPtr doc; + doc = xmlReadFile(output.c_str(), NULL, 0); + if (doc == NULL) + { + DEBTRACE("Failed to parse " << output); + throw Exception("Execution problem"); + } + xmlNodePtr cur; + cur = xmlDocGetRootElement(doc); + if (cur == NULL) + { + DEBTRACE("empty document " ); + xmlFreeDoc(doc); + throw Exception("Execution problem"); + } + if (xmlStrcmp(cur->name, (const xmlChar *) "methodResponse")) + { + DEBTRACE("document of the wrong type, root node != methodResponse"); + xmlFreeDoc(doc); + throw Exception("Execution problem"); + } + cur = cur->xmlChildrenNode; + xmlBufferPtr buf=xmlBufferCreate(); + list::iterator iter2; + iter2 = _setOfOutputPort.begin(); + OutputXmlPort *p; + p=(OutputXmlPort *)*iter2; + int nres=0; + + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"fault"))) + { + DEBTRACE("exception in shell" ); + xmlFreeDoc(doc); + throw Exception("Execution problem"); + } + if ((!xmlStrcmp(cur->name, (const xmlChar *)"params"))) + { + xmlNodePtr cur0 = cur->xmlChildrenNode; + while (cur0 != NULL) + { + if ((!xmlStrcmp(cur0->name, (const xmlChar *)"param"))) + { + xmlNodePtr cur1 = cur0->xmlChildrenNode; + while (cur1 != NULL) + { + if ((!xmlStrcmp(cur1->name, (const xmlChar *)"value"))) + { + xmlNodePtr cur2=cur1->xmlChildrenNode; + while (cur2 != NULL) + { + if ((!xmlStrcmp(cur2->name, (const xmlChar *)"int"))) + { + //got an int + if(getNumberOfOutputPorts()!=1) + { + //mismatch + xmlBufferFree(buf); + xmlFreeDoc(doc); + throw Exception("Execution problem:mismatch in output numbers"); + } + xmlBufferEmpty(buf); + xmlNodeDump(buf,doc,cur1,0,0); + DEBTRACE(xmlBufferContent(buf)); + p->put(xmlBufferContent(buf)); + } + if ((!xmlStrcmp(cur2->name, (const xmlChar *)"double"))) + { + //got an double + if(getNumberOfOutputPorts()!=1) + { + //mismatch + xmlBufferFree(buf); + xmlFreeDoc(doc); + throw Exception("Execution problem:mismatch in output numbers"); + } + xmlBufferEmpty(buf); + xmlNodeDump(buf,doc,cur1,0,0); + DEBTRACE(xmlBufferContent(buf)); + p->put(xmlBufferContent(buf)); + } + if ((!xmlStrcmp(cur2->name, (const xmlChar *)"string"))) + { + //got an string + if(getNumberOfOutputPorts()!=1) + { + //mismatch + xmlBufferFree(buf); + xmlFreeDoc(doc); + throw Exception("Execution problem:mismatch in output port numbers"); + } + xmlBufferEmpty(buf); + xmlNodeDump(buf,doc,cur1,0,0); + DEBTRACE(xmlBufferContent(buf)); + p->put(xmlBufferContent(buf)); + } + if ((!xmlStrcmp(cur2->name, (const xmlChar *)"boolean"))) + { + //got an boolean + if(getNumberOfOutputPorts()!=1) + { + //mismatch + xmlBufferFree(buf); + xmlFreeDoc(doc); + throw Exception("Execution problem:mismatch in output port numbers"); + } + xmlBufferEmpty(buf); + xmlNodeDump(buf,doc,cur1,0,0); + DEBTRACE(xmlBufferContent(buf)); + p->put(xmlBufferContent(buf)); + } + if ((!xmlStrcmp(cur2->name, (const xmlChar *)"objref"))) + { + //got an objref + if(getNumberOfOutputPorts()!=1) + { + //mismatch + xmlBufferFree(buf); + xmlFreeDoc(doc); + throw Exception("Execution problem:mismatch in output port numbers"); + } + xmlBufferEmpty(buf); + xmlNodeDump(buf,doc,cur1,0,0); + DEBTRACE(xmlBufferContent(buf)); + p->put(xmlBufferContent(buf)); + } + if ((!xmlStrcmp(cur2->name, (const xmlChar *)"struct"))) + { + //got an struct + if(getNumberOfOutputPorts()!=1) + { + //mismatch + xmlBufferFree(buf); + xmlFreeDoc(doc); + throw Exception("Execution problem:mismatch in output port numbers"); + } + xmlBufferEmpty(buf); + xmlNodeDump(buf,doc,cur1,0,0); + DEBTRACE(xmlBufferContent(buf)); + p->put(xmlBufferContent(buf)); + } + if ((!xmlStrcmp(cur2->name, (const xmlChar *)"array"))) + { + //got a tuple of results or only one result (but a list) + if(getNumberOfOutputPorts()==1) + { + //It's a one result list + xmlBufferEmpty(buf); + xmlNodeDump(buf,doc,cur1,0,0); + DEBTRACE(xmlBufferContent(buf)); + p->put(xmlBufferContent(buf)); + } + else + { + //It's a list of results + xmlNodePtr cur3=cur2->xmlChildrenNode; + while (cur3 != NULL) + { + if ((!xmlStrcmp(cur3->name, (const xmlChar *)"data"))) + { + xmlNodePtr cur4=cur3->xmlChildrenNode; + while (cur4 != NULL) + { + if ((!xmlStrcmp(cur4->name, (const xmlChar *)"value"))) + { + nres++; + if(nres > getNumberOfOutputPorts()) + { + //mismatch + xmlBufferFree(buf); + xmlFreeDoc(doc); + throw Exception("Execution problem:mismatch in output port numbers"); + } + xmlBufferEmpty(buf); + xmlNodeDump(buf,doc,cur4,0,0); + DEBTRACE(xmlBufferContent(buf)); + p=(OutputXmlPort *)*iter2; + p->put(xmlBufferContent(buf)); + iter2++; + } + cur4 = cur4->next; + } // end while value + break; + } + cur3 = cur3->next; + } // end while data + } + break; + } + cur2 = cur2->next; + } // end while array + break; + } + cur1 = cur1->next; + } // end while value + } + cur0 = cur0->next; + }// end while param + } + cur = cur->next; } - cerr << "--------------XmlNode::calculation-----------" << _script << endl; + xmlBufferFree(buf); + xmlFreeDoc(doc); } diff --git a/src/runtime/XMLNode.hxx b/src/runtime/XMLNode.hxx index 4e35aa38d..c88fe84ec 100644 --- a/src/runtime/XMLNode.hxx +++ b/src/runtime/XMLNode.hxx @@ -1,25 +1,33 @@ - #ifndef _XMLNODE_HXX_ #define _XMLNODE_HXX_ -#include "ElementaryNode.hxx" +#include "ServiceNode.hxx" namespace YACS { namespace ENGINE { - - class XmlNode:public ENGINE::ElementaryNode + class XmlNode:public ServiceNode { + protected: + Node *simpleClone(ComposedNode *father, bool editionOnly) const; public: + XmlNode(const XmlNode& other, ComposedNode *father); XmlNode(const std::string& name); virtual void execute(); - virtual void set_script(const std::string& script); + //! \b DISTRIBUTION \b NOT \b YET implemented for XMLNode. + virtual void load() { } + virtual void setRef(const std::string& ref); + virtual void setScript(const std::string& script); + virtual ServiceNode* createNode(const std::string& name) + { throw Exception("not implemented"); } + virtual std::string getKind() const; + public: + static const char IMPL_NAME[]; + static const char KIND[]; protected: std::string _script; }; - - } } diff --git a/src/runtime/XMLPorts.cxx b/src/runtime/XMLPorts.cxx index de4da977d..f8dcaae2b 100644 --- a/src/runtime/XMLPorts.cxx +++ b/src/runtime/XMLPorts.cxx @@ -3,39 +3,96 @@ #include +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + using namespace YACS::ENGINE; using namespace std; -InputXmlPort::InputXmlPort(const string& name, Node * node, TypeCode * type) - : InputPort(name, node, type), Port(node) +InputXmlPort::InputXmlPort(const std::string& name, Node * node, TypeCode * type) + : InputPort(name, node, type), DataPort(name, node, type), Port(node), _initData(""), _data("") +{ +} + +InputXmlPort::InputXmlPort(const InputXmlPort& other, Node *newHelder):InputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder),_initData(other._initData),_data(other._data) +{ +} + +bool InputXmlPort::edIsManuallyInitialized() const +{ + return _initData != ""; +} + +void InputXmlPort::edRemoveManInit() { - _impl="XML"; + _initData=""; + InputPort::edRemoveManInit(); } -const char * InputXmlPort::getXml() const +const char *InputXmlPort::getXml() const { + DEBTRACE(_data); return _data.c_str(); } +void *InputXmlPort::get() const throw(Exception) +{ + return (void *) _data.c_str(); +} + void InputXmlPort::put(const void *data) throw (ConversionException) { + DEBTRACE("put(void *)"); put((const char*)data); - _empty = false; } void InputXmlPort::put(const char *data) throw (ConversionException) { - cerr << "InputXmlPort::put" << endl; + DEBTRACE(data); _data = data; - cerr << "data: " << data << endl; } +bool InputXmlPort::isEmpty() +{ + return _data.empty(); +} + +InputPort *InputXmlPort::clone(Node *newHelder) const +{ + return new InputXmlPort(*this,newHelder); +} + +//! Save the current data value for further reinitialization of the port +/*! + * + */ +void InputXmlPort::exSaveInit() +{ + _initData=_data; +} + +//! Restore the saved data value to current data value +/*! + * If no data has been saved (_initData == 0) don't restore + */ +void InputXmlPort::exRestoreInit() +{ + if(_initData!="")return; + _data=_initData; +} + +std::string InputXmlPort::dump() +{ + return _data; +} +OutputXmlPort::OutputXmlPort(const std::string& name, Node* node, TypeCode * type) + : OutputPort(name, node, type), DataPort(name, node, type), Port(node) +{ +} -OutputXmlPort::OutputXmlPort(const string& name, Node* node, TypeCode * type) - : OutputPort(name, node, type), Port(node) +OutputXmlPort::OutputXmlPort(const OutputXmlPort& other, Node *newHelder):OutputPort(other,newHelder),DataPort(other,newHelder),Port(other,newHelder) { - _impl="XML"; } const char * OutputXmlPort::get() const throw (ConversionException) @@ -50,14 +107,19 @@ void OutputXmlPort::put(const void *data) throw (ConversionException) void OutputXmlPort::put(const char *data) throw (ConversionException) { - cerr << "OutputXmlPort::put-------" << getName() << endl; + DEBTRACE(data); 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); - } + OutputPort::put(data); +} + +OutputPort *OutputXmlPort::clone(Node *newHelder) const +{ + return new OutputXmlPort(*this,newHelder); } + +std::string OutputXmlPort::dump() +{ + return _data; +} + diff --git a/src/runtime/XMLPorts.hxx b/src/runtime/XMLPorts.hxx index 1a16cb7e6..922194af6 100644 --- a/src/runtime/XMLPorts.hxx +++ b/src/runtime/XMLPorts.hxx @@ -9,24 +9,49 @@ namespace YACS { namespace ENGINE { +/*! \brief Class for XML Input Ports + * + * \ingroup Ports + * + * \see XmlNode + */ class InputXmlPort : public InputPort { public: InputXmlPort(const std::string& name, Node* node, TypeCode * type); + InputXmlPort(const InputXmlPort& other, Node *newHelder); + bool edIsManuallyInitialized() const; + void edRemoveManInit(); virtual void put(const void *data) throw (ConversionException); void put(const char *data) throw (ConversionException); + InputPort *clone(Node *newHelder) const; virtual const char * getXml() const; + void *get() const throw(Exception); + bool isEmpty(); + virtual void exSaveInit(); + virtual void exRestoreInit(); + virtual std::string dump(); protected: std::string _data; + std::string _initData; }; +/*! \brief Class for XML Output Ports + * + * \ingroup Ports + * + * \see XmlNode + */ class OutputXmlPort : public OutputPort { public: OutputXmlPort(const std::string& name, Node* node, TypeCode * type); + OutputXmlPort(const OutputXmlPort& other, Node *newHelder); virtual void put(const void *data) throw (ConversionException); void put(const char *data) throw (ConversionException); virtual const char * get() const throw (ConversionException); + OutputPort *clone(Node *newHelder) const; + virtual std::string dump(); protected: std::string _data; }; diff --git a/src/runtime/XMLPythonConv.cxx b/src/runtime/XMLPythonConv.cxx new file mode 100644 index 000000000..264c994f7 --- /dev/null +++ b/src/runtime/XMLPythonConv.cxx @@ -0,0 +1,76 @@ + +#include "XMLPythonConv.hxx" +#include "TypeConversions.hxx" + +#include +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +XmlPython::XmlPython(InputPyPort* p) + : ProxyPort(p), DataPort(p->getName(), p->getNode(), p->edGetType()), Port(p->getNode()) +{ +} + +void XmlPython::put(const void *data) throw(ConversionException) +{ + DEBTRACE((const char *)data); + put((const char *)data); +} + +//!Convert a XML (char *) to PyObject and push it into proxy port + /*! + * \param data : Xml::char * + */ + +void XmlPython::put(const char *data) throw(ConversionException) +{ + DEBTRACE(data); + xmlDocPtr doc; + xmlNodePtr cur; + PyObject *ob; +{ + InterpreterUnlocker l; + doc = xmlParseMemory(data, strlen(data)); + if (doc == NULL ) + { + stringstream msg; + msg << "Problem in conversion: XML Document not parsed successfully "; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } + cur = xmlDocGetRootElement(doc); + if (cur == NULL) + { + xmlFreeDoc(doc); + stringstream msg; + msg << "Problem in conversion: empty XML Document"; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"value"))) + { + ob=convertXmlPyObject(edGetType(),doc,cur); + break; + } + cur = cur->next; + } + xmlFreeDoc(doc); +// xmlCleanupParser(); +#ifdef _DEVDEBUG_ + PyObject_Print(ob,stderr,Py_PRINT_RAW); + cerr << endl; +#endif + _port->put(ob); + Py_XDECREF(ob); + DEBTRACE("ob refcnt: " << ob->ob_refcnt); + _port->setStringRef(data); +} +} diff --git a/src/runtime/XMLPythonConv.hxx b/src/runtime/XMLPythonConv.hxx new file mode 100644 index 000000000..c3dece903 --- /dev/null +++ b/src/runtime/XMLPythonConv.hxx @@ -0,0 +1,22 @@ +#ifndef __XMLPYTHONCONV_HXX__ +#define __XMLPYTHONCONV_HXX__ + +#include "PythonPorts.hxx" + +namespace YACS +{ + namespace ENGINE + { + //Proxy port to adapt Python port to XML + + class XmlPython : public ProxyPort + { + public: + XmlPython(InputPyPort* p); + virtual void put(const void *data) throw(ConversionException); + void put(const char *data) throw(ConversionException); + }; + } +} + +#endif diff --git a/src/salomeloader/Makefile.am b/src/salomeloader/Makefile.am new file mode 100644 index 000000000..68d186ffe --- /dev/null +++ b/src/salomeloader/Makefile.am @@ -0,0 +1,5 @@ +include $(top_srcdir)/adm/unix/make_begin.am + +pkgpython_PYTHON = salomeloader.py + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/salomeloader/salomeloader.py b/src/salomeloader/salomeloader.py new file mode 100644 index 000000000..4bc755887 --- /dev/null +++ b/src/salomeloader/salomeloader.py @@ -0,0 +1,1010 @@ +# -*- coding: iso-8859-1 -*- +"""Ce module sert pour lire un schema de calcul Salome décrit en XML. + et le convertir en schema de calcul YACS + + Cette lecture est réalisée au moyen de la classe SalomeLoader + et de sa méthode load. + +""" + +import sys,os +import cElementTree as ElementTree +from sets import Set +import pilot +import SALOMERuntime + +class UnknownKind(Exception):pass + +debug=0 +typeMap={} +streamTypes={ + '0':"Unknown", + '1':"CALCIUM_int", + '3':"CALCIUM_real", + } + +#Les fonctions suivantes : invert, reachable,InducedSubgraph,write_dot,display +#permettent de realiser des operations sur un graphe. +#Est considere comme un graphe un objet G qui supporte les +#operations suivantes : l'iteration sur les noeuds (for n in G parcourt +#tous les noeuds du graphe) et l'iteration sur les suivants +# (for v in G[n] parcourt tous les suivants du noeud n) +def invert(G): + """Construit le graphe inverse de G en inversant les liens de voisinage""" + I={} + for n in G: + I.setdefault(n,Set()) + for v in G[n]: + I.setdefault(v,Set()).add(n) + return I + +def reachable(G,n): + """Construit le set de noeuds atteignables depuis le noeud n + + Le noeud n n'est pas dans le set retourné sauf en cas de boucles + Ce cas n'est pas traité ici (limitation) + """ + s=G[n] + for v in G[n]: + s=s|reachable(G,v) + return s + +def InducedSubgraph(V,G,adjacency_list_type=Set): + """ Construit un sous graphe de G avec les noeuds contenus dans V """ + def neighbors(x): + for y in G[x]: + if y in V: + yield y + return dict([(x,adjacency_list_type(neighbors(x))) for x in G if x in V]) + +def write_dot(stream,G): + """Ecrit la representation (au format dot) du graphe G dans le fichier stream""" + name="toto" + stream.write('digraph %s {\nnode [ style="filled" ]\n' % name) + for node in G : + try: + label = "%s:%s"% (node.name,node.__class__.__name__) + except: + label=str(node) + color='green' + stream.write(' %s [fillcolor="%s" label=< %s >];\n' % ( id(node), color, label)) + for src in G: + for dst in G[src]: + stream.write(' %s -> %s;\n' % (id(src), id(dst))) + stream.write("}\n") + +def display(G,suivi="sync"): + """Affiche le graphe G avec l'outil dot""" + f=file("graph.dot", 'w') + write_dot(f,G) + f.close() + cmd="dot -Tpng graph.dot |display" + (suivi == "async" and "&" or "") + os.system(cmd) + + +def test(): + G={ + 1:Set([2,3]), + 2:Set([4]), + 3:Set([5]), + 4:Set([6]), + 5:Set([6]), + 6:Set(), + } + display(G) + I=invert(G) + print reachable(G,2) + print reachable(I,6) + print reachable(G,2) & reachable(I,6) + +#Fin des fonctions graphe + +currentProc=None + +class SalomeLoader: + """Loader de schéma Salome natif et convertisseur en schéma 'nouvelle formule'. + La méthode loadxml parse le fichier xml et retourne un objet SalomeProc + natif non converti + La méthode load parse le fichier xml et retourne un objet représentant + un schéma Salome converti (objet Proc de YACS) + """ + + def loadxml(self,filename): + """ + Lit un fichier XML du SUPERV de Salome et retourne la liste des + procedures (instances de SalomeProc) + """ + tree = ElementTree.ElementTree(file=filename) + root = tree.getroot() + if debug:print "root.tag:",root.tag,root + + procs=[] + if root.tag == "dataflow": + #un seul dataflow + dataflow=root + if debug:print dataflow + proc=SalomeProc(dataflow) + procs.append(proc) + else: + #un ou plusieurs dataflow. Le schema contient des macros. + # Toutes les macros sont + #décrites au meme niveau dans le fichier XML. + for dataflow in root.findall("dataflow"): + if debug:print dataflow + proc=SalomeProc(dataflow) + if debug:print "nom du dataflow:",proc.name + procs.append(proc) + return procs + + def load(self,filename): + """Lit un fichier XML et convertit les procedures lues en procedures + nouvelle formule + """ + global currentProc + procs=self.loadxml(filename) + #on récupère le schema de tete d'un coté et les éventuelles + #macros de l'autre: procs[0] + proc=procs.pop(0) + #proc.display() + + #Enregistrement des éventuelles macros dans macro_dict + macro_dict={} + for p in procs: + if debug:print "proc_name:",p.name,"coupled_node:",p.coupled_node + macro_dict[p.name]=p + + if debug:print filename + yacsproc=ProcNode(proc,macro_dict) + return yacsproc.createNode() + +class Service: + """Classe pour porter les caractéristiques d'un service""" +class Parameter: + """Classe pour porter les caractéristiques d'un parametre""" +class Link: + """Classe pour porter les caractéristiques d'un link""" +class Data: + """Classe pour porter les caractéristiques d'un data""" + +class Node: + """Node de calcul simple : classe de base à spécialiser """ + label="Node: " + def __init__(self): + self.links=[] # liste pour stocker les entrees sous forme de link + # le link doit avoir deux attributs : from_node qui donne le node origine + # et to_node qui donne le node cible + self.datas=[] + self.inStreamLinks=[] #liste des liens dataStream associés à ce node (in) + self.outStreamLinks=[] #liste des liens dataStream associés à ce node (out) + def createNode(self): + raise NotImplementedError + def getInputPort(self,p): + return self.node.getInputPort(".".join(p.split("__"))) + def getOutputPort(self,p): + return self.node.getOutputPort(".".join(p.split("__"))) + def getInputDataStreamPort(self,p): + return self.node.getInputDataStreamPort(p) + def getOutputDataStreamPort(self,p): + return self.node.getOutputDataStreamPort(p) + +class InlineNode(Node): + """Node de calcul inline salome : fonction dans self.codes[0]""" + def __init__(self): + Node.__init__(self) + self.codes=[] + def createNode(self): + r = pilot.getRuntime() + if self.fnames[0] == "?": + n=r.createScriptNode("",self.name) + else: + n=r.createFuncNode("",self.name) + n.setFname(self.fnames[0]) + n.setScript(self.codes[0]) + self.node=n + for para in self.service.inParameters: + if not typeMap.has_key(para.type): + #create the missing type and add it in type map + typeMap[para.type]= currentProc.createInterfaceTc("",para.type,[]) + currentProc.typeMap[para.type]=typeMap[para.type] + n.edAddInputPort(para.name,typeMap[para.type]) + for para in self.service.outParameters: + if not typeMap.has_key(para.type): + #create the missing type and add it in type map + typeMap[para.type]= currentProc.createInterfaceTc("",para.type,[]) + currentProc.typeMap[para.type]=typeMap[para.type] + n.edAddOutputPort(para.name,typeMap[para.type]) + + return n + +class ComputeNode(Node): + """Node de calcul pour exécuter un service Salome""" + def createNode(self): + r = pilot.getRuntime() + n=r.createCompoNode("",self.name) + n.setRef(self.sComponent) + n.setMethod(self.service.name) + self.node=n + + #ajout des ports in et out du service + for para in self.service.inParameters: + if not typeMap.has_key(para.type): + #on cree le type manquant et on l'ajoute dans la table des types + typeMap[para.type]= currentProc.createInterfaceTc("",para.type,[]) + currentProc.typeMap[para.type]=typeMap[para.type] + n.edAddInputPort(para.name,typeMap[para.type]) + for para in self.service.outParameters: + if not typeMap.has_key(para.type): + #on cree le type manquant et on l'ajoute dans la table des types + typeMap[para.type]= currentProc.createInterfaceTc("",para.type,[]) + currentProc.typeMap[para.type]=typeMap[para.type] + pout=n.edAddOutputPort(para.name,typeMap[para.type]) + + #ajout des ports datastream in et out + for para in self.inStreams: + if debug:print para.name,para.type,para.dependency,para.schema, para.interpolation, + if debug:print para.extrapolation + pin=n.edAddInputDataStreamPort(para.name,typeMap[streamTypes[para.type]]) + for para in self.outStreams: + if debug:print para.name,para.type,para.dependency,para.values + pout=n.edAddOutputDataStreamPort(para.name,typeMap[streamTypes[para.type]]) + + return n + +class ComposedNode(Node): + """Node de calcul composite Salome (classe de base)""" + + def reduceLoop(self): + """Transforme un graphe de type Salome avec les boucles + a plat en un graphe hierarchique + Le graphe de depart (Salome) est dans self.G. + On le transforme en place + """ + G=self.G + if debug:display(G) + #calcul du graphe inverse + I=invert(G) + #display(I) + + #on recherche toutes les boucles et leurs noeuds internes + loops={} + for n in G: + if n.kind == 4: + #Debut de boucle + loops[n]=reachable(G,n)&reachable(I,n.endloop) + n.inner_nodes=loops[n] + n.G=InducedSubgraph(loops[n],G) + + if debug:print "toutes les boucles du graphe" + if debug:print loops + + #on recherche les boucles les plus externes + outer_loops=loops.keys() + for l in loops: + for ll in outer_loops: + if loops[l] < loops[ll]: + #boucle interne + outer_loops.remove(l) + ll.set_inner(l) + break + + #a la fin, les boucles restantes dans outer_loops sont les plus externes + if debug:print outer_loops + + #on supprime les noeuds internes des boucles les plus externes + for l in outer_loops: + #on enleve les noeuds internes + for n in loops[l]: + del G[n] + #on enleve le noeud endloop + suiv=G[l.endloop] + del G[l.endloop] + #on remplace les noeuds suivants de loop par ceux de endloop + G[l]= suiv + + #on tente de transformer les liens entrants et sortants sur le noeud endloop + #en noeuds directs. On ne traite probablement pas tous les cas. + inputs={} + for link in l.endloop.links: + if debug:print link.from_node,link.to_node,link.from_param,link.to_param + inputs[link.to_param]=link.from_node,link.from_param + + for s in suiv: + for link in s.links: + if link.from_node == l.endloop: + link.from_node,link.from_param=inputs[link.from_param] + if debug:print link.from_node,link.to_node,link.from_param,link.to_param + + if debug:display(G) + + #on applique le traitement de reduction aux boucles les plus externes (recursif) + for l in outer_loops: + l.reduceLoop() + + def connect_macros(self,macro_dict): + """Cette methode rattache les macros salome contenues dans macro_dict + a la procedure YACS proc + On est ici dans le noeud auquel on veut rattacher une des macros + macro_dict est un dictionnaire dont la cle est le nom de la macro + et la valeur est un graphe Salome (objet SalomeProc) + Les noeuds concernes sont les MacroNode et les SalomeProc + """ + if debug:print "connect_macros",self.node,macro_dict + for node in self.G: + if isinstance(node,MacroNode): + #c'est une macro, il faut rattacher sa description + #p est le sous graphe Salome (objet SalomeProc) + #node est le MacroNode Salome qui utilise le sous graphe p + #node.node est le bloc YACS equivalent + p=macro_dict[node.coupled_node] + bloc=node.node + if debug:print "macronode:",node.name,node.coupled_node,p + #a partir de la procédure salome a plat on cree un + #graphe d'exécution hiérarchique nouvelle formule + G=p.create_graph() + node.G=G + for n in G: + #chaque noeud du graphe G cree un noeud YACS equivalent + nod=n.createNode() + bloc.edAddChild(nod) + + #on demande le rattachement des macros aux nodes du macroNode node + node.connect_macros(macro_dict) + + #on ajoute les liens de controle + for n in G: + for v in G[n]: + bloc.edAddCFLink(n.node,v.node) + #on ajoute les liens de donnees et les initialisations + for n in G: + #liens dataflow + for l in n.links: + bloc.edAddLink(l.from_node.getOutputPort(l.from_param), + l.to_node.getInputPort(l.to_param)) + #liens datastream + for l in n.outStreamLinks: + pout=l.from_node.getOutputDataStreamPort(l.from_param) + pin=l.to_node.getInputDataStreamPort(l.to_param) + bloc.edAddLink(pout,pin) + #initialisations + for l in n.datas: + if l.type == 7: + #double + n.getInputPort(l.tonodeparam).edInitDbl(l.value) + elif l.type == 3: + #int + n.getInputPort(l.tonodeparam).edInitInt(l.value) + +class LoopNode(ComposedNode): + """Objet qui simule le comportement d'une boucle Salome.""" + def __init__(self): + ComposedNode.__init__(self) + self.inner_loops=[] + #inner_nodes contient les noeuds internes au sens Salome (a plat + #avec les noeuds endloop) + self.inner_nodes=[] + + def set_node(self,node): + self.node=node + + def set_inner(self,loop): + for i in self.inner_loops: + if loop.inner_nodes < i.inner_nodes: + #la boucle est contenue dans i + i.set_inner(loop) + break + self.inner_loops.append(loop) + + def createNode(self): + """Cree l'objet boucle equivalent + + Un objet boucle Salome a n ports d'entrée et les memes ports en sortie. + La tete de boucle a 3 fonctions : init, next, more qui ont des signatures + tres voisines. init et next ont la meme signature : en entree les parametres + d'entree de la boucle et en sortie les parametres de sortie de la boucle c'est + à dire les memes qu'en entrée. more a les memes parametres d'entree et a un + parametre de sortie supplementaire qui vient en premiere position. Ce + parametre indique si la boucle doit etre poursuivie ou stoppée. + La fin de boucle a une fonction qui a la meme signature que next. + + Pour transformer ce type de boucle, on crée un ensemble de noeuds de calcul + regroupés dans un bloc. Dans ce bloc, on crée un noeud externe pour init suivi + d'une boucle while. + Ensuite on crée un bloc qui contiendra 2 noeuds (next et more) plus tous + les noeuds internes de la boucle. + """ + + r = pilot.getRuntime() + bloop=r.createBloc(self.name) + + #noeud init + init=r.createFuncNode("","init") + #print self.codes[0] + init.setScript(self.codes[0]) + init.setFname(self.fnames[0]) + for para in self.service.inParameters: + if not typeMap.has_key(para.type): + #create the missing type and add it in type map + typeMap[para.type]= currentProc.createInterfaceTc("",para.type,[]) + currentProc.typeMap[para.type]=typeMap[para.type] + init.edAddInputPort(para.name,typeMap[para.type]) + for para in self.service.outParameters: + if not typeMap.has_key(para.type): + #create the missing type and add it in type map + typeMap[para.type]= currentProc.createInterfaceTc("",para.type,[]) + currentProc.typeMap[para.type]=typeMap[para.type] + init.edAddOutputPort(para.name,typeMap[para.type]) + bloop.edAddChild(init) + self.init=init + + wh=r.createWhileLoop(self.name) + bloop.edAddChild(wh) + blnode=r.createBloc(self.name) + wh.edSetNode(blnode) + cport=wh.edGetConditionPort() + cport.edInitBool(True) + + #noeud next + next=r.createFuncNode("","next") + #print self.codes[2] + next.setScript(self.codes[2]) + next.setFname(self.fnames[2]) + for para in self.service.inParameters: + if not typeMap.has_key(para.type): + #create the missing type and add it in type map + typeMap[para.type]= currentProc.createInterfaceTc("",para.type,[]) + currentProc.typeMap[para.type]=typeMap[para.type] + next.edAddInputPort(para.name,typeMap[para.type]) + for para in self.service.outParameters: + if not typeMap.has_key(para.type): + #create the missing type and add it in type map + typeMap[para.type]= currentProc.createInterfaceTc("",para.type,[]) + currentProc.typeMap[para.type]=typeMap[para.type] + next.edAddOutputPort(para.name,typeMap[para.type]) + blnode.edAddChild(next) + self.next=next + + #noeud more + more=r.createFuncNode("","more") + #print self.codes[1] + more.setScript(self.codes[1]) + more.setFname(self.fnames[1]) + for para in self.service.inParameters: + if not typeMap.has_key(para.type): + #create the missing type and add it in type map + typeMap[para.type]= currentProc.createInterfaceTc("",para.type,[]) + currentProc.typeMap[para.type]=typeMap[para.type] + more.edAddInputPort(para.name,typeMap[para.type]) + more.edAddOutputPort("DoLoop",typeMap["int"]) + for para in self.service.outParameters: + if not typeMap.has_key(para.type): + #create the missing type and add it in type map + typeMap[para.type]= currentProc.createInterfaceTc("",para.type,[]) + currentProc.typeMap[para.type]=typeMap[para.type] + more.edAddOutputPort(para.name,typeMap[para.type]) + blnode.edAddChild(more) + self.more=more + + for para in self.service.outParameters: + bloop.edAddDFLink(init.getOutputPort(para.name),next.getInputPort(para.name)) + + for para in self.service.outParameters: + blnode.edAddDFLink(next.getOutputPort(para.name),more.getInputPort(para.name)) + + wh.edAddLink(more.getOutputPort("DoLoop"),wh.getInputPort("condition")) + + for para in self.service.outParameters: + wh.edAddLink(more.getOutputPort(para.name),next.getInputPort(para.name)) + + self.node=bloop + + for n in self.G: + node=n.createNode() + blnode.edAddChild(node) + + for n in self.G: + for v in self.G[n]: + blnode.edAddCFLink(n.node,v.node) + + for n in self.G: + for l in n.links: + print l.from_node.name,l.to_node.name + print l.from_param,l.to_param + blnode.edAddDFLink(l.from_node.getOutputPort(l.from_param), + l.to_node.getInputPort(l.to_param)) + + return bloop + + def getInputPort(self,p): + return self.init.getInputPort(p) + + def getOutputPort(self,p): + return self.more.getOutputPort(p) + +class Bloc(ComposedNode): + """ Objet composé d'un ensemble de nodes enchaines et qui se + comporte comme un node simple. + """ + label="Bloc: " + def __init__(self): + Node.__init__(self) + self.nodes=[] + + def addLink(self,node1,node2): + if node1 not in self.nodes:self.nodes.append(node1) + if node2 not in self.nodes:self.nodes.append(node2) + +class MacroNode(Bloc): + """Objet qui représente une Macro Salome c'est a dire un node + composite avec une interface : ports in et out. + """ + def createNode(self): + """Cree l'objet correspondant a une Macro Salome : un Bloc""" + r = pilot.getRuntime() + macro=r.createBloc(self.name) + self.node=macro + return macro + +def is_loop(n): + """Indique si n est un node de début de boucle""" + return isinstance(n,LoopNode) + +class ProcNode(ComposedNode): + """Procedure YACS equivalente a une procedure Salome accompagnee + de ses macros + """ + def __init__(self,proc,macro_dict): + ComposedNode.__init__(self) + self.proc=proc + self.macro_dict=macro_dict + + def createNode(self): + """Cree l'objet YACS equivalent""" + global currentProc + r = pilot.getRuntime() + + #create_graph retourne un graphe representatif de la + #procedure Salome transformee en un graphe hierarchique + G=self.proc.create_graph() + self.G=G + + #on utilise le graphe G pour construire la + #procedure YACS equivalente p + p=r.createProc("pr") + self.node=p + currentProc=p + typeMap["double"]=p.typeMap["double"] + typeMap["int"]=p.typeMap["int"] + typeMap["long"]=p.typeMap["int"] + typeMap["string"]=p.typeMap["string"] + typeMap["bool"]=p.typeMap["bool"] + typeMap["Unknown"]=p.createInterfaceTc("","Unknown",[]) + typeMap["GEOM_Object"]=p.createInterfaceTc("","GEOM_Object",[]) + typeMap["GEOM_Shape"]=typeMap["GEOM_Object"] + typeMap["CALCIUM_int"]=p.createInterfaceTc("","CALCIUM_int",[]) + typeMap["CALCIUM_real"]=p.createInterfaceTc("","CALCIUM_real",[]) + currentProc.typeMap["Unknown"]=typeMap["Unknown"] + currentProc.typeMap["GEOM_Object"]=typeMap["GEOM_Object"] + currentProc.typeMap["GEOM_Shape"]=typeMap["GEOM_Shape"] + currentProc.typeMap["CALCIUM_int"]=typeMap["CALCIUM_int"] + currentProc.typeMap["CALCIUM_real"]=typeMap["CALCIUM_real"] + + for n in G: + #chaque noeud du graphe G cree un noeud YACS equivalent + node=n.createNode() + p.edAddChild(node) + + #on demande le rattachement des macros aux nodes de la procédure p + self.connect_macros(self.macro_dict) + + #on ajoute les liens de controle + for n in G: + for v in G[n]: + p.edAddCFLink(n.node,v.node) + + #on ajoute les liens de donnees et les initialisations + for n in G: + #liens dataflow + for l in n.links: + print l.from_node.name,l.to_node.name + print l.from_param,l.to_param + p.edAddLink(l.from_node.getOutputPort(l.from_param), + l.to_node.getInputPort(l.to_param)) + + #liens datastream + for l in n.outStreamLinks: + pout=l.from_node.getOutputDataStreamPort(l.from_param) + pin=l.to_node.getInputDataStreamPort(l.to_param) + p.edAddLink(pout,pin) + #initialisations + for l in n.datas: + if l.type == 7: + #double + n.getInputPort(l.tonodeparam).edInitDbl(l.value) + elif l.type == 3: + #int + n.getInputPort(l.tonodeparam).edInitInt(l.value) + + return p + + +class SalomeProc(ComposedNode): + """Objet pour décrire un schéma Salome natif avec ses liens + dataflow, datastream et gate + L'objet est construit en parsant un fichier XML + """ + def __init__(self,dataflow): + self.name="name" + self.parse(dataflow) + #self.links : liste des liens dataflow du graphe (objets Link) + #self.nodes : liste des noeuds du graphe + #self.node_dict : le dictionnaire des noeuds (nom,node) + #self.datas : liste des datas du graphe + #chaque noeud a 2 listes de liens datastream (inStreams, outStreams) + + def parse(self,dataflow): + if debug:print "Tous les noeuds XML" + for node in dataflow: + if debug:print node.tag,node + + #Récupération des informations du dataflow + self.dataflow_info=self.parseService(dataflow.find("info-list/node/service")) + if debug:print self.dataflow_info + if debug:print self.dataflow_info.inParameters + if debug:print self.dataflow_info.outParameters + if debug: + for para in self.dataflow_info.inParameters: + print "inParam:",para.name,para.name.split("__",1) + + self.name=dataflow.findtext("info-list/node/node-name") + self.coupled_node=dataflow.findtext("info-list/node/coupled-node") + + if debug:print "Tous les noeuds XML dataflow/node-list" + nodes=[] + node_dict={} + #on parcourt tous les noeuds + for n in dataflow.findall('node-list/node'): + #n est un node de node-list + kind=n.findtext("kind") + comp=n.find("component-name").text + name=n.find("node-name").text + coupled_node=n.find("coupled-node").text + interface=n.find("interface-name").text + container=n.find("container").text + + #kind=1 : dataflow ? + #kind=2 : ? + #kind=9 : schema avec datastream ? + + if kind == "0": + #Il s'agit d'un service + node=ComputeNode() + node.kind=0 + node.sComponent = comp + node.interface=interface + elif kind == "3": + #il s'agit d'une fonction + node=InlineNode() + node.kind=3 + codes=[] + fnames=[] + for pyfunc in n.findall("PyFunction-list/PyFunction"): + fnames.append(pyfunc.findtext("FuncName")) + codes.append(self.parsePyFunction(pyfunc)) + node.fnames=fnames + node.codes=codes + elif kind == "4": + #si kind vaut 4 on a une boucle : on crée un LoopNode + #les fonctions python (next, more, init) sont stockées dans codes + node=LoopNode() + node.kind=4 + codes=[] + fnames=[] + for pyfunc in n.findall("PyFunction-list/PyFunction"): + fnames.append(pyfunc.findtext("FuncName")) + codes.append(self.parsePyFunction(pyfunc)) + node.fnames=fnames + node.codes=codes + elif kind == "5": + #noeud de fin de boucle : on crée un InlineNode + node=InlineNode() + node.kind=5 + codes=[] + fnames=[] + for pyfunc in n.findall("PyFunction-list/PyFunction"): + fnames.append(pyfunc.findtext("FuncName")) + codes.append(self.parsePyFunction(pyfunc)) + node.fnames=fnames + node.codes=codes + elif kind == "10": + #si kind vaut 10 on a un noeud Macro : on cree un MacroNode + node=MacroNode() + node.kind=10 + else: + raise UnknownKind,kind + + node.name=name + node.container=container + node.service=None + node.coupled_node=coupled_node + #on stocke les noeuds dans un dictionnaire pour faciliter les recherches + node_dict[node.name]=node + if debug:print "\tnode-name",node.name + if debug:print "\tkind",node.kind,node.__class__.__name__ + if debug:print "\tcontainer",node.container + + s=n.find("service") + if s: + node.service=self.parseService(s) + + + #on parcourt les ports datastream + if debug:print "DataStream" + inStreams=[] + for indata in n.findall("DataStream-list/inParameter"): + inStreams.append(self.parseInData(indata)) + node.inStreams=inStreams + outStreams=[] + outStreams_dict={} + for outdata in n.findall("DataStream-list/outParameter"): + p=self.parseOutData(outdata) + outStreams.append(p) + outStreams_dict[p.name]=p + node.outStreams=outStreams + node.outStreams_dict=outStreams_dict + if debug:print "\t++++++++++++++++++++++++++++++++++++++++++++" + nodes.append(node) + + self.nodes=nodes + self.node_dict=node_dict + #Le parcours des noeuds est fini. + #On parcourt les connexions dataflow et datastream + """ + + Node_A_1 + a_1 + Node_B_1 + b_1 + + + """ + if debug:print "Tous les noeuds XML dataflow/link-list" + links=[] + if debug:print "\t++++++++++++++++++++++++++++++++++++++++++++" + for link in dataflow.findall('link-list/link'): + l=Link() + l.from_name=link.findtext("fromnode-name") + l.to_name=link.findtext("tonode-name") + l.from_param=link.findtext("fromserviceparameter-name") + l.to_param=link.findtext("toserviceparameter-name") + links.append(l) + if debug:print "\tfromnode-name",l.from_name + if debug:print "\tfromserviceparameter-name",l.from_param + if debug:print "\ttonode-name",l.to_name + if debug:print "\ttoserviceparameter-name",l.to_param + if debug:print "\t++++++++++++++++++++++++++++++++++++++++++++" + + self.links=links + if debug:print "Tous les noeuds XML dataflow/data-list" + datas=[] + for data in dataflow.findall('data-list/data'): + d=self.parseData(data) + datas.append(d) + if debug:print "\ttonode-name",d.tonode + if debug:print "\ttoserviceparameter-name",d.tonodeparam + if debug:print "\tparameter-value",d.value + if debug:print "\tparameter-type",d.type + if debug:print "\t++++++++++++++++++++++++++++++++++++++++++++" + + self.datas=datas + + def parseService(self,s): + service=Service() + service.name=s.findtext("service-name") + if debug:print "\tservice-name",service.name + + inParameters=[] + for inParam in s.findall("inParameter-list/inParameter"): + p=Parameter() + p.name=inParam.findtext("inParameter-name") + p.type=inParam.findtext("inParameter-type") + if debug:print "\tinParameter-name",p.name + if debug:print "\tinParameter-type",p.type + inParameters.append(p) + service.inParameters=inParameters + if debug:print "\t++++++++++++++++++++++++++++++++++++++++++++" + + outParameters=[] + for outParam in s.findall("outParameter-list/outParameter"): + p=Parameter() + p.name=outParam.findtext("outParameter-name") + p.type=outParam.findtext("outParameter-type") + if debug:print "\toutParameter-name",p.name + if debug:print "\toutParameter-type",p.type + outParameters.append(p) + service.outParameters=outParameters + if debug:print "\t++++++++++++++++++++++++++++++++++++++++++++" + return service + + def parseData(self,d): + da=Data() + da.tonode=d.findtext("tonode-name") + da.tonodeparam=d.findtext("toserviceparameter-name") + da.value=d.findtext("data-value/value") + da.type=eval(d.findtext("data-value/value-type")) + if da.type < 9: + da.value=eval(da.value) + return da + + def parsePyFunction(self,pyfunc): + if debug:print pyfunc.tag,":",pyfunc + if debug:print "\tFuncName",pyfunc.findtext("FuncName") + text="" + for cdata in pyfunc.findall("PyFunc"): + if text:text=text+'\n' + text=text+ cdata.text + return text + + """1 + istream + 2 + 0 + 0 + 0 + + + 1 + ostream + 2 + 0 + + """ + + def parseInData(self,d): + if debug:print d.tag,":",d + p=Parameter() + p.name=d.findtext("inParameter-name") + p.type=d.findtext("inParameter-type") + p.dependency=d.findtext("inParameter-dependency") + p.schema=d.findtext("inParameter-schema") + p.interpolation=d.findtext("inParameter-interpolation") + p.extrapolation=d.findtext("inParameter-extrapolation") + if debug:print "\tinParameter-name",p.name + return p + + def parseOutData(self,d): + if debug:print d.tag,":",d + p=Parameter() + p.name=d.findtext("outParameter-name") + p.type=d.findtext("outParameter-type") + p.dependency=d.findtext("outParameter-dependency") + p.values=d.findtext("outParameter-values") + if debug:print "\toutParameter-name",p.name + return p + + def create_graph(self): + #un graphe est un dictionnaire dont la clé est un noeud et la valeur + #est la liste (en fait un set sans doublon) des noeuds voisins suivants + #for v in graphe (python >= 2.3): parcourt les noeuds du graphe + #for v in graphe[noeud] parcourt les voisins (suivants) de noeud + G={} + #on cree tous les noeuds avec un voisinage (suivants) vide + for n in self.nodes: + G[n]=Set() + + #on construit le voisinage en fonction des divers liens + for link in self.links: + from_node=self.node_dict[link.from_name] + if link.from_param == "Gate" or link.to_param == "Gate": + #control link salome : on ajoute le noeud to_name dans les voisins + if debug:print "ajout control link",link.from_name,link.to_name + G[self.node_dict[link.from_name]].add(self.node_dict[link.to_name]) + + elif from_node.outStreams_dict.has_key(link.from_param): + #lien datastream salome : + # 1- on ajoute le lien dans les listes de liens des noeuds + # 2- on ajoute dans le lien des pointeurs sur les noeuds (from_node et to_node) + if debug:print "ajout stream link",link.from_name,link.to_name + self.node_dict[link.to_name].inStreamLinks.append(link) + self.node_dict[link.from_name].outStreamLinks.append(link) + link.from_node=self.node_dict[link.from_name] + link.to_node=self.node_dict[link.to_name] + + else: + #autre lien salome + #si c'est un lien entre Loop node et EndOfLoop node, on l'ignore + #tous les autres sont conservés + from_node=self.node_dict[link.from_name] + to_node=self.node_dict[link.to_name] + if isinstance(to_node,LoopNode): + #Est-ce le lien entre EndOfLoop et Loop ? Si oui, on ne le garde pas + if to_node.coupled_node == from_node.name: + if debug:print "lien arriere loop:",from_node,to_node + #lien ignoré + continue + if debug:print "ajout dataflow link",link.from_name,link.to_name + G[self.node_dict[link.from_name]].add(self.node_dict[link.to_name]) + + if link.from_param != "DoLoop" and link.to_param != "DoLoop": + #Les liens sur parametre DoLoop servent au superviseur Salome, on les ignore + #on ajoute dans le lien des pointeurs sur les noeuds (from_node et to_node) + #on ajoute ce lien à la liste des liens du noeud cible (to) + self.node_dict[link.to_name].links.append(link) + link.from_node=self.node_dict[link.from_name] + link.to_node=self.node_dict[link.to_name] + + #Dans un graphe salome avec boucles, les noeuds de tete et de fin + #de boucle sont reliés par 2 liens de sens opposés + #on stocke le noeud de fin dans l'attribut endloop du noeud de tete. + if link.from_param == "DoLoop" and link.to_param == "DoLoop" \ + and is_loop(self.node_dict[link.from_name]) \ + and isinstance(self.node_dict[link.to_name],InlineNode): + #on repère le node inline de fin de boucle en le stockant + #dans l'attribut endloop du node loop + #self.node_dict[link.to_name] est le node de fin de boucle + #de self.node_dict[link.from_name] + if debug:print "ajout loop",link.from_name,link.to_name + self.node_dict[link.from_name].endloop=self.node_dict[link.to_name] + self.node_dict[link.to_name].loop=self.node_dict[link.from_name] + + for data in self.datas: + self.node_dict[data.tonode].datas.append(data) + + self.G=G + + #on modifie le graphe en place : + # transformation des boucles a plat en graphe hierarchique + self.reduceLoop() + + #on peut maintenant créer le schéma de calcul YACS + return G + + def display(self,suivi="sync"): + """Visualise la procedure Salome avec dot""" + #pour visualiser : dot -Tpng salome.dot |display + f=file("salome.dot", 'w') + self.write_dot(f) + f.close() + cmd="dot -Tpng salome.dot |display" + (suivi == "async" and "&" or "") + os.system(cmd) + + def write_dot(self,stream): + """Dumpe la procedure Salome dans stream au format dot""" + stream.write('digraph %s {\nnode [ style="filled" ]\n' % self.name) + for node in self.nodes: + label = "%s:%s"% (node.name,node.__class__.__name__) + color='green' + stream.write(' %s [fillcolor="%s" label=< %s >];\n' % ( + id(node), color, label + )) + for link in self.links: + from_node=self.node_dict[link.from_name] + to_node=self.node_dict[link.to_name] + stream.write(' %s -> %s;\n' % (id(from_node), id(to_node))) + stream.write("}\n") + +if __name__ == "__main__": + + import traceback + usage ="""Usage: %s salomeFile convertedFile + where salomeFile is the name of the input schema file (old Salome syntax) + and convertedFile is the name of the output schema file (new YACS syntax) + """ + try: + salomeFile=sys.argv[1] + convertedFile=sys.argv[2] + except : + print usage%(sys.argv[0]) + sys.exit(1) + + SALOMERuntime.RuntimeSALOME_setRuntime() + loader=SalomeLoader() + + try: + p= loader.load(salomeFile) + s= pilot.SchemaSave(p) + s.save(convertedFile) + except: + traceback.print_exc() + f=open(convertedFile,'w') + f.write("\n") + diff --git a/src/wrappergen/Makefile.am b/src/wrappergen/Makefile.am new file mode 100644 index 000000000..8b27e366f --- /dev/null +++ b/src/wrappergen/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS=src + diff --git a/src/wrappergen/bin/Cpp_Template__SRC/AUTHORS b/src/wrappergen/bin/Cpp_Template__SRC/AUTHORS new file mode 100644 index 000000000..8f4939d14 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/AUTHORS @@ -0,0 +1 @@ +Nicolas Crouzet (nicolas.crouzet@cea.fr) diff --git a/src/wrappergen/bin/Cpp_Template__SRC/ChangeLog b/src/wrappergen/bin/Cpp_Template__SRC/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/src/wrappergen/bin/Cpp_Template__SRC/Makefile.am b/src/wrappergen/bin/Cpp_Template__SRC/Makefile.am new file mode 100644 index 000000000..46e5489d9 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/Makefile.am @@ -0,0 +1,5 @@ + +SUBDIRS = src + +#install-exec-hook: +# cp -rf idl/* $(pythondir)/$(PACKAGE) diff --git a/src/wrappergen/bin/Cpp_Template__SRC/NEWS b/src/wrappergen/bin/Cpp_Template__SRC/NEWS new file mode 100644 index 000000000..e69de29bb diff --git a/src/wrappergen/bin/Cpp_Template__SRC/README b/src/wrappergen/bin/Cpp_Template__SRC/README new file mode 100644 index 000000000..eddf87ed2 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/README @@ -0,0 +1,15 @@ +This directory contains contain the tree directories to compile a C++ components linked with MED library. + + +Component sbased on automake. +To INSTALL it : + + mkdir ../COMPO_CXX_BUILD + mkdir ../COMPO_CXX_INSTALL + ./build_configure + cd ../COMPO_CXX_BUILD + ../COMPO_CXX_SRC/configure --prefix= + make + make install + + diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/ac_pkg_swig.m4 b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/ac_pkg_swig.m4 new file mode 100755 index 000000000..6810ca27b --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/ac_pkg_swig.m4 @@ -0,0 +1,150 @@ +dnl @synopsis AC_PROG_SWIG([major.minor.micro]) +dnl +dnl This macro searches for a SWIG installation on your system. If found you +dnl should) SWIG via $(SWIG). You can use the optional first argument to check +dnl if the version of the available SWIG is greater than or equal to the +dnl value of the argument. It should have the format: N[.N[.N]] (N is a +dnl number between 0 and 999. Only the first N is mandatory.) +dnl +dnl If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks that the +dnl swig package is this version number or higher. +dnl +dnl In configure.in, use as: +dnl +dnl AC_PROG_SWIG(1.3.17) +dnl SWIG_ENABLE_CXX +dnl SWIG_MULTI_MODULE_SUPPORT +dnl SWIG_PYTHON +dnl +dnl @authors Sebastian Huber , Alan W. Irwin +dnl , Rafael Laboissiere and +dnl Andrew Collier . +dnl +dnl +AC_DEFUN([AC_PROG_SWIG],[ + AC_PATH_PROG([SWIG],[swig]) + if test -z "$SWIG" ; then + AC_MSG_WARN([cannot find 'swig' program. You should look at http://www.swig.org]) + SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false' + elif test -n "$1" ; then + AC_MSG_CHECKING([for SWIG version]) + [swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`] + AC_MSG_RESULT([$swig_version]) + if test -n "$swig_version" ; then + # Calculate the required version number components + [required=$1] + [required_major=`echo $required | sed 's/[^0-9].*//'`] + if test -z "$required_major" ; then + [required_major=0] + fi + [required=`echo $required | sed 's/[0-9]*[^0-9]//'`] + [required_minor=`echo $required | sed 's/[^0-9].*//'`] + if test -z "$required_minor" ; then + [required_minor=0] + fi + [required=`echo $required | sed 's/[0-9]*[^0-9]//'`] + [required_patch=`echo $required | sed 's/[^0-9].*//'`] + if test -z "$required_patch" ; then + [required_patch=0] + fi + # Calculate the available version number components + [available=$swig_version] + [available_major=`echo $available | sed 's/[^0-9].*//'`] + if test -z "$available_major" ; then + [available_major=0] + fi + [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] + [available_minor=`echo $available | sed 's/[^0-9].*//'`] + if test -z "$available_minor" ; then + [available_minor=0] + fi + [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] + [available_patch=`echo $available | sed 's/[^0-9].*//'`] + if test -z "$available_patch" ; then + [available_patch=0] + fi + if test $available_major -ne $required_major \ + -o $available_minor -ne $required_minor \ + -o $available_patch -lt $required_patch ; then + AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org]) + SWIG='echo "Error: SWIG version >= $1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false' + else + AC_MSG_NOTICE([SWIG executable is '$SWIG']) + SWIG_LIB=`$SWIG -swiglib` + AC_MSG_NOTICE([SWIG runtime library directory is '$SWIG_LIB']) + fi + else + AC_MSG_WARN([cannot determine SWIG version]) + SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false' + fi + fi + AC_SUBST([SWIG_LIB]) +]) + +# SWIG_ENABLE_CXX() +# +# Enable SWIG C++ support. This affects all invocations of $(SWIG). +AC_DEFUN([SWIG_ENABLE_CXX],[ + AC_REQUIRE([AC_PROG_SWIG]) + AC_REQUIRE([AC_PROG_CXX]) + SWIG="$SWIG -c++" +]) + +# SWIG_MULTI_MODULE_SUPPORT() +# +# Enable support for multiple modules. This effects all invocations +# of $(SWIG). You have to link all generated modules against the +# appropriate SWIG runtime library. If you want to build Python +# modules for example, use the SWIG_PYTHON() macro and link the +# modules against $(SWIG_PYTHON_LIBS). +AC_DEFUN([SWIG_MULTI_MODULE_SUPPORT],[ + AC_REQUIRE([AC_PROG_SWIG]) + SWIG="$SWIG -c" +]) + +# SWIG_PYTHON([use-shadow-classes = {no, yes}]) +# +# Checks for Python and provides the $(SWIG_PYTHON_CPPFLAGS), +# $(SWIG_PYTHON_LIBS) and $(SWIG_PYTHON_OPT) output variables. +# $(SWIG_PYTHON_OPT) contains all necessary SWIG options to generate +# code for Python. Shadow classes are enabled unless the value of the +# optional first argument is exactly 'no'. If you need multi module +# support (provided by the SWIG_MULTI_MODULE_SUPPORT() macro) use +# $(SWIG_PYTHON_LIBS) to link against the appropriate library. It +# contains the SWIG Python runtime library that is needed by the type +# check system for example. +AC_DEFUN([SWIG_PYTHON],[ + AC_REQUIRE([AC_PROG_SWIG]) + AC_REQUIRE([AC_PYTHON_DEVEL]) + test "x$1" != "xno" || swig_shadow=" -noproxy" + AC_SUBST([SWIG_PYTHON_OPT],[-python$swig_shadow]) + AC_SUBST([SWIG_PYTHON_CPPFLAGS],[$PYTHON_CPPFLAGS]) + AC_SUBST([SWIG_PYTHON_LIBS],["-L$SWIG_LIB -lswigpy"]) +]) + + +dnl @synopsis AC_LIB_WAD +dnl +dnl This macro searches for installed WAD library. +dnl +AC_DEFUN([AC_LIB_WAD], +[ + AC_REQUIRE([AC_PYTHON_DEVEL]) + AC_ARG_ENABLE(wad, + AC_HELP_STRING([--enable-wad], [enable wad module]), + [ + case "${enableval}" in + no) ;; + *) if test "x${enableval}" = xyes; + then + check_wad="yes" + fi ;; + esac + ], []) + + if test -n "$check_wad"; + then + AC_CHECK_LIB(wadpy, _init, [WADPY=-lwadpy], [], $PYTHON_LDFLAGS $PYTHON_EXTRA_LIBS) + AC_SUBST(WADPY) + fi +]) diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/ac_python_devel.m4 b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/ac_python_devel.m4 new file mode 100755 index 000000000..e0ac20c9c --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/ac_python_devel.m4 @@ -0,0 +1,60 @@ +dnl @synopsis AC_PYTHON_DEVEL() +dnl +dnl Checks for Python and tries to get the include path to 'Python.h'. +dnl It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) output variable. +dnl +dnl @authors Sebastian Huber , Alan W. Irwin +dnl , Rafael Laboissiere and +dnl Andrew Collier . +dnl +dnl +AC_DEFUN([AC_PYTHON_DEVEL],[ + # + # should allow for checking of python version here... + # + AC_REQUIRE([AM_PATH_PYTHON]) + + # Check for Python include path + AC_MSG_CHECKING([for Python include path]) + python_path=`echo $PYTHON | sed "s,/bin.*$,,"` + for i in "$python_path/include/python$PYTHON_VERSION/" "$python_path/include/python/" "$python_path/" ; do + python_path=`find $i -type f -name Python.h -print | sed "1q"` + if test -n "$python_path" ; then + break + fi + done + python_path=`echo $python_path | sed "s,/Python.h$,,"` + AC_MSG_RESULT([$python_path]) + if test -z "$python_path" ; then + AC_MSG_ERROR([cannot find Python include path]) + fi + AC_SUBST([PYTHON_CPPFLAGS],[-I$python_path]) + + # Check for Python library path + AC_MSG_CHECKING([for Python library path]) + python_path=`echo $PYTHON | sed "s,/bin.*$,,"` + for i in "$python_path/lib/python$PYTHON_VERSION/config/" "$python_path/lib/python$PYTHON_VERSION/" "$python_path/lib/python/config/" "$python_path/lib/python/" "$python_path/" ; do + python_path=`find $i -type f -name libpython$PYTHON_VERSION.* -print | sed "1q"` + if test -n "$python_path" ; then + break + fi + done + python_path=`echo $python_path | sed "s,/libpython.*$,,"` + AC_MSG_RESULT([$python_path]) + if test -z "$python_path" ; then + AC_MSG_ERROR([cannot find Python library path]) + fi + AC_SUBST([PYTHON_LDFLAGS],["-L$python_path -lpython$PYTHON_VERSION"]) + # + python_site=`echo $python_path | sed "s/config/site-packages/"` + AC_SUBST([PYTHON_SITE_PKG],[$python_site]) + # + # libraries which must be linked in when embedding + # + AC_MSG_CHECKING(python extra libraries) + PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \ + conf = distutils.sysconfig.get_config_var; \ + print conf('LOCALMODLIBS')+' '+conf('LIBS')" + AC_MSG_RESULT($PYTHON_EXTRA_LIBS)` + AC_SUBST(PYTHON_EXTRA_LIBS) +]) diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_Kernel.m4 b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_Kernel.m4 new file mode 100644 index 000000000..fc07131da --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_Kernel.m4 @@ -0,0 +1,58 @@ +# Check availability of Salome's KERNEL binary distribution +# +# Author : Jerome Roy (CEA, 2003) +# + +AC_DEFUN([CHECK_KERNEL],[ + +AC_CHECKING(for Kernel) + +Kernel_ok=no + +AC_ARG_WITH(kernel, + [ --with-kernel=DIR root directory path of KERNEL build or installation], + KERNEL_DIR="$withval",KERNEL_DIR="") + +if test "x$KERNEL_DIR" = "x" ; then + +# no --with-kernel-dir option used + + if test "x$KERNEL_ROOT_DIR" != "x" ; then + + # KERNEL_ROOT_DIR environment variable defined + KERNEL_DIR=$KERNEL_ROOT_DIR + + else + + # search Kernel binaries in PATH variable + AC_PATH_PROG(TEMP, runSalome) + if test "x$TEMP" != "x" ; then + KERNEL_BIN_DIR=`dirname $TEMP` + KERNEL_DIR=`dirname $KERNEL_BIN_DIR` + fi + + fi +# +fi + +if test -f ${KERNEL_DIR}/bin/salome/runSalome ; then + Kernel_ok=yes + AC_MSG_RESULT(Using Kernel module distribution in ${KERNEL_DIR}) + + if test "x$KERNEL_ROOT_DIR" = "x" ; then + KERNEL_ROOT_DIR=${KERNEL_DIR} + fi + if test "x$KERNEL_SITE_DIR" = "x" ; then + KERNEL_SITE_DIR=${KERNEL_ROOT_DIR} + fi + AC_SUBST(KERNEL_ROOT_DIR) + AC_SUBST(KERNEL_SITE_DIR) + +else + AC_MSG_WARN("Cannot find compiled Kernel module distribution") +fi + +AC_MSG_RESULT(for Kernel: $Kernel_ok) + +])dnl + diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_Med.m4 b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_Med.m4 new file mode 100644 index 000000000..57a45d296 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_Med.m4 @@ -0,0 +1,61 @@ +# Check availability of Med binary distribution +# +# Author : Nicolas REJNERI (OPEN CASCADE, 2003) +# + +AC_DEFUN([CHECK_MED],[ + +CHECK_HDF5 +CHECK_MED2 + +AC_CHECKING(for Med) + +Med_ok=no + +AC_ARG_WITH(med, + [ --with-med=DIR root directory path of MED installation ], + MED_DIR="$withval",MED_DIR="") + +if test "x$MED_DIR" == "x" ; then + +# no --with-med-dir option used + + if test "x$MED_ROOT_DIR" != "x" ; then + + # MED_ROOT_DIR environment variable defined + MED_DIR=$MED_ROOT_DIR + + else + + # search Med binaries in PATH variable + AC_PATH_PROG(TEMP, libMEDMEM_Swig.py) + if test "x$TEMP" != "x" ; then + MED_BIN_DIR=`dirname $TEMP` + MED_DIR=`dirname $MED_BIN_DIR` + fi + + fi +# +fi + +if test -f ${MED_DIR}/bin/salome/libMEDMEM_Swig.py ; then + Med_ok=yes + AC_MSG_RESULT(Using Med module distribution in ${MED_DIR}) + + if test "x$MED_ROOT_DIR" == "x" ; then + MED_ROOT_DIR=${MED_DIR} + fi + AC_SUBST(MED_ROOT_DIR) + MED_INCLUDES="-I${MED_ROOT_DIR}/include/salome ${MED2_INCLUDES} ${HDF5_INCLUDES} -I${KERNEL_ROOT_DIR}/include/salome" + MED_LIBS="-L${MED_ROOT_DIR}/lib/salome -lmedmem ${MED2_LIBS} ${HDF5_LIBS} -L${KERNEL_ROOT_DIR}/lib/salome -lSALOMELocalTrace" + AC_SUBST(MED_INCLUDES) + AC_SUBST(MED_LIBS) + +else + AC_MSG_WARN("Cannot find Med module sources") +fi + +AC_MSG_RESULT(for Med: $Med_ok) + +])dnl + diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_hdf5.m4 b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_hdf5.m4 new file mode 100644 index 000000000..b3658afc1 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_hdf5.m4 @@ -0,0 +1,83 @@ +# Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +AC_DEFUN([CHECK_HDF5],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl + +AC_CHECKING(for HDF5) + +AC_ARG_WITH(hdf5, + [ --with-hdf5=DIR root directory path to hdf5 installation ], + [HDF5HOME="$withval" + AC_MSG_RESULT("select $withval as path to hdf5") + ]) + +AC_SUBST(HDF5_INCLUDES) +AC_SUBST(HDF5_LIBS) +AC_SUBST(HDF5_MT_LIBS) + +HDF5_INCLUDES="" +HDF5_LIBS="" +HDF5_MT_LIBS="" + +hdf5_ok=no + +LOCAL_INCLUDES="" +LOCAL_LIBS="" + +if test -z $HDF5HOME +then + AC_MSG_WARN(undefined HDF5HOME variable which specify hdf5 installation directory) +else + LOCAL_INCLUDES="-I$HDF5HOME/include" + LOCAL_LIBS="-L$HDF5HOME/lib" +fi + +dnl hdf5 headers + +CPPFLAGS_old="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $LOCAL_INCLUDES" +AC_CHECK_HEADER(hdf5.h,hdf5_ok=yes ,hdf5_ok=no) +CPPFLAGS="$CPPFLAGS_old" + + +if test "x$hdf5_ok" = "xyes" +then + +dnl hdf5 library + + LIBS_old="$LIBS" + LIBS="$LIBS $LOCAL_LIBS" + AC_CHECK_LIB(hdf5,H5open,hdf5_ok=yes,hdf5_ok=no) + LIBS="$LIBS_old" + +fi + +if test "x$hdf5_ok" = "xyes" +then + HDF5_INCLUDES="$LOCAL_INCLUDES" + HDF5_LIBS="$LOCAL_LIBS -lhdf5" + HDF5_MT_LIBS="$LOCAL_LIBS -lhdf5" +fi + +AC_MSG_RESULT(for hdf5: $hdf5_ok) + +])dnl diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_med2.m4 b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_med2.m4 new file mode 100644 index 000000000..68345204c --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_med2.m4 @@ -0,0 +1,86 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl + +AC_DEFUN([CHECK_MED2],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([CHECK_HDF5])dnl + +AC_CHECKING(for MED2) + +AC_ARG_WITH(med2, + [ --with-med2=DIR root directory path to med2 installation ], + [MED2HOME="$withval" + AC_MSG_RESULT("select $withval as path to med2") + ]) + +AC_SUBST(MED2_INCLUDES) +AC_SUBST(MED2_LIBS) +AC_SUBST(MED2_MT_LIBS) + +MED2_INCLUDES="" +MED2_LIBS="" +MED2_MT_LIBS="" + +med2_ok=no + +LOCAL_INCLUDES="$HDF5_INCLUDES" +LOCAL_LIBS="-lmed $HDF5_LIBS" + +if test -z $MED2HOME +then + AC_MSG_WARN(undefined MED2HOME variable which specify med2 installation directory) +else + LOCAL_INCLUDES="$LOCAL_INCLUDES -I$MED2HOME/include" + LOCAL_LIBS="-L$MED2HOME/lib $LOCAL_LIBS" +fi + +dnl check med2 header + +CPPFLAGS_old="$CPPFLAGS" +dnl we must test system : linux = -DPCLINUX +CPPFLAGS="$CPPFLAGS -DPCLINUX $LOCAL_INCLUDES" +AC_CHECK_HEADER(med.h,med2_ok=yes ,med2_ok=no) +CPPFLAGS="$CPPFLAGS_old" + +if test "x$med2_ok" = "xyes" +then + +dnl check med2 library + + LIBS_old="$LIBS" + LIBS="$LIBS $LOCAL_LIBS" + AC_CHECK_LIB(med,MEDouvrir,med2_ok=yes,med2_ok=no) + LIBS="$LIBS_old" + +fi + +if test "x$med2_ok" = "xyes" +then + MED2_INCLUDES="-DPCLINUX $LOCAL_INCLUDES" + MED2_LIBS="$LOCAL_LIBS" + MED2_MT_LIBS="$LOCAL_LIBS" +fi + +AC_MSG_RESULT(for med2: $med2_ok) + +])dnl diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_pthreads.m4 b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_pthreads.m4 new file mode 100644 index 000000000..0608c4a40 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_pthreads.m4 @@ -0,0 +1,51 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +#@synonpsis CHECK_PTHREADS +dnl check for pthreads system interfaces. +dnl set CFLAGS_PTHREADS, CXXFLAGS_PTHREADS and LIBS_PTHREADS to +dnl flags to compiler flags for multithread program compilation (if exists), +dnl and library, if one required. +dnl +dnl@author (C) Ruslan Shevchenko , 1998 +dnl@id $Id$ +dnl ---------------------------------------------------------------- +dnl CHECK_PTHREADS +AC_DEFUN(CHECK_PTHREADS,[ +AC_REQUIRE([AC_CANONICAL_SYSTEM])dnl +AC_CHECK_HEADER(pthread.h,AC_DEFINE(HAVE_PTHREAD_H)) +AC_CHECK_LIB(posix4,nanosleep, LIBS_PTHREADS="-lposix4",LIBS_PTHREADS="") +AC_CHECK_LIB(pthread,pthread_mutex_lock, + LIBS_PTHREADS="-lpthread $LIBS_PTHREADS") +AC_MSG_CHECKING([parameters for using pthreads]) +case $build_os in + freebsd*) + CFLAGS_PTHREADS="-pthread" + CXXFLAGS_PTHREADS="-pthread" + ;; + *) + ;; +esac +AC_MSG_RESULT(["flags: $CFLAGS_PTHREADS\;libs: $LIBS_PTHREADS"]) +threads_ok=yes +])dnl +dnl +dnl diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_python.m4 b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_python.m4 new file mode 100644 index 000000000..b86c21d35 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_python.m4 @@ -0,0 +1,163 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +## ------------------------ +## Python file handling +## From Andrew Dalke +## Modified by Marc Tajchman (06/2001) +## ------------------------ + +dnl CHECK_PYTHON([module, classes]) +dnl +dnl Adds support for distributing Python modules or classes. +dnl Python library files distributed as a `module' are installed +dnl under PYTHON_SITE_PACKAGE (eg, ./python1.5/site-package/package-name) +dnl while those distributed as `classes' are installed under PYTHON_SITE +dnl (eg, ./python1.5/site-packages). The default is to install as +dnl a `module'. + +AC_DEFUN(CHECK_PYTHON, + [ + AC_ARG_WITH(python, + [ --with-python=DIR root directory path of python installation ], + [PYTHON="$withval/bin/python" + AC_MSG_RESULT("select python distribution in $withval") + ], [ + AC_PATH_PROG(PYTHON, python) + ]) + + AC_CHECKING([local Python configuration]) + PYTHON_PREFIX=`echo $PYTHON | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + PYTHON_PREFIX=`echo $PYTHON_PREFIX | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + PYTHONHOME=$PYTHON_PREFIX + + AC_SUBST(PYTHON_PREFIX) + AC_SUBST(PYTHONHOME) + + changequote(<<, >>)dnl + PYTHON_VERSION=`$PYTHON -c "import sys; print sys.version[:3]"` + changequote([, ])dnl + AC_SUBST(PYTHON_VERSION) + + PY_MAKEFILE=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/config/Makefile + if test ! -f "$PY_MAKEFILE"; then + AC_MSG_ERROR([*** Couldn't find ${PY_MAKEFILE}. Maybe you are +*** missing the development portion of the python installation]) + fi + + AC_SUBST(PYTHON_INCLUDES) + AC_SUBST(PYTHON_LIBS) + + PYTHON_INCLUDES=-I$PYTHON_PREFIX/include/python$PYTHON_VERSION + PYTHON_LIBS="-L${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/config -lpython${PYTHON_VERSION}" + PYTHON_LIB=$PYTHON_LIBS + PYTHON_LIBA=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/config/libpython$PYTHON_VERSION.a + + dnl At times (like when building shared libraries) you may want + dnl to know which OS Python thinks this is. + + AC_SUBST(PYTHON_PLATFORM) + PYTHON_PLATFORM=`$PYTHON -c "import sys; print sys.platform"` + + AC_SUBST(PYTHON_SITE) + AC_ARG_WITH(python-site, +[ --with-python-site=DIR Use DIR for installing platform independent + Python site-packages], + +dnl modification : by default, we install python script in salome root tree + +dnl [PYTHON_SITE="$withval" +dnl python_site_given=yes], +dnl [PYTHON_SITE=$PYTHON_PREFIX"/lib/python"$PYTHON_VERSION/site-packages +dnl python_site_given=no]) + +[PYTHON_SITE="$withval" +python_site_given=yes], +[PYTHON_SITE=$prefix"/lib/python"$PYTHON_VERSION/site-packages +python_site_given=no]) + + AC_SUBST(PYTHON_SITE_PACKAGE) + PYTHON_SITE_PACKAGE=$PYTHON_SITE/$PACKAGE + + + dnl Get PYTHON_SITE from --with-python-site-exec or from + dnl --with-python-site or from running Python + + AC_SUBST(PYTHON_SITE_EXEC) + AC_ARG_WITH(python-site-exec, +[ --with-python-site-exec=DIR Use DIR for installing platform dependent + Python site-packages], +[PYTHON_SITE_EXEC="$withval"], +[if test "$python_site_given" = yes; then + PYTHON_SITE_EXEC=$PYTHON_SITE +else + PYTHON_SITE_EXEC=$PYTHON_EXEC_PREFIX"/lib/python"$PYTHON_VERSION/site-packages +fi]) + + dnl Set up the install directory + ifelse($1, classes, +[PYTHON_SITE_INSTALL=$PYTHON_SITE], +[PYTHON_SITE_INSTALL=$PYTHON_SITE_PACKAGE]) + AC_SUBST(PYTHON_SITE_INSTALL) + + dnl Also lets automake think PYTHON means something. + + pythondir=$PYTHON_PREFIX"/lib/python"$PYTHON_VERSION/ + AC_SUBST(pythondir) + + AC_MSG_CHECKING([if we need libdb]) + PY_NEEDOPENDB=`nm $PYTHON_LIBA | grep dbopen | grep U` + if test "x$PY_NEEDOPENDB" != "x"; then + PYTHON_LIBS="$PYTHON_LIBS -ldb" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + + AC_MSG_CHECKING([if we need libdl]) + PY_NEEDOPENDL=`nm $PYTHON_LIBA | grep dlopen | grep U` + if test "x$PY_NEEDOPENDL" != "x"; then + PYTHON_LIBS="$PYTHON_LIBS -ldl" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + + AC_MSG_CHECKING([if we need libutil]) + PY_NEEDOPENPTY=`nm $PYTHON_LIBA | grep openpty | grep U` + if test "x$PY_NEEDOPENPTY" != "x"; then + PYTHON_LIBS="$PYTHON_LIBS -lutil" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + + AC_MSG_CHECKING([if we need tcltk]) + PY_NEEDTCLTK=`nm $PYTHON_LIBA | grep Tcl_Init | grep U` + if test "x$PY_NEEDTCLTK" != "x"; then + PYTHON_LIBS="$PYTHON_LIBS -ltcl -ltk" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + + python_ok=yes + AC_MSG_RESULT(looks good)]) diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_swig.m4 b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_swig.m4 new file mode 100644 index 000000000..10408c009 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/check_swig.m4 @@ -0,0 +1,66 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl + +AC_DEFUN([CHECK_SWIG],[ +AC_REQUIRE([CHECK_PYTHON])dnl + +swig_ok=yes + +AC_ARG_WITH(swig, + [ --with-swig=EXEC swig executable ], + [SWIG="$withval" + AC_MSG_RESULT("select $withval as swig executable") + ], [ + AC_PATH_PROG(SWIG, swig) + ]) + +if test "x$SWIG" = "x" +then + swig_ok=no + AC_MSG_RESULT(swig not in PATH variable) +fi + +if test "x$swig_ok" = "xyes" +then + AC_MSG_CHECKING(python wrapper generation with swig) + cat > conftest.h << EOF +int f(double); +EOF + + $SWIG -module conftest -python conftest.h >/dev/null 2>&1 + if test -f conftest_wrap.c + then + SWIG_FLAGS="-c++ -python -shadow" + else + swig_ok=no + fi + rm -f conftest* + AC_MSG_RESULT($swig_ok) +fi + +AC_SUBST(SWIG_FLAGS) +AC_SUBST(SWIG) + +AC_MSG_RESULT(for swig: $swig_ok) + +])dnl +dnl diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/enable_pthreads.m4 b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/enable_pthreads.m4 new file mode 100644 index 000000000..45652fbb5 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/enable_pthreads.m4 @@ -0,0 +1,41 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl@synopsis ENABLE_PTHREADS +dnl +dnl modify CFLAGS, CXXFLAGS and LIBS for compiling pthread-based programs. +dnl +dnl@author (C) Ruslan Shevchenko , 1998, 2000 +dnl@id $Id$ +dnl +dnl +AC_DEFUN([ENABLE_PTHREADS],[ +AC_REQUIRE([CHECK_PTHREADS]) + +if test -z "$enable_pthreads_done" +then + CFLAGS="$CFLAGS $CFLAGS_PTHREADS" + CXXFLAGS="$CXXFLAGS $CXXFLAGS_PTHREADS" + LIBS="$LIBS $LIBS_PTHREADS" +fi +enable_pthreads_done=yes +])dnl +dnl diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/production.m4 b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/production.m4 new file mode 100644 index 000000000..633adc84f --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/config_files/production.m4 @@ -0,0 +1,99 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl define macros : +dnl AC_ENABLE_PRODUCTION AC_DISABLE_PRODUCTION +dnl and +dnl AC_ENABLE_DEBUG AC_DISABLE_DEBUG +dnl +dnl version $Id$ +dnl author Patrick GOLDBRONN +dnl + +# AC_ENABLE_PRODUCTION +AC_DEFUN(AC_ENABLE_PRODUCTION, [dnl +define([AC_ENABLE_PRODUCTION_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(production, +changequote(<<, >>)dnl +<< --enable-production[=PKGS] build without debug information [default=>>AC_ENABLE_PRODUCTION_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_production=yes ;; +no) enable_production=no ;; +*) + enable_production=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_production=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_production=AC_ENABLE_PRODUCTION_DEFAULT)dnl +if test "X$enable_production" = "Xyes"; then + FFLAGS="$FFLAGS -O3 " + CFLAGS="$CFLAGS -O3 " + CXXFLAGS="$CXXFLAGS -O3 " +fi +]) + +# AC_DISABLE_PRODUCTION - set the default flag to --disable-production +AC_DEFUN(AC_DISABLE_PRODUCTION, [AC_ENABLE_PRODUCTION(no)]) + +# AC_ENABLE_DEBUG +AC_DEFUN(AC_ENABLE_DEBUG, [dnl +define([AC_ENABLE_DEBUG_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(debug, +changequote(<<, >>)dnl +<< --enable-debug[=PKGS] build without debug information [default=>>AC_ENABLE_DEBUG_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_debug=yes ;; +no) enable_debug=no ;; +*) + enable_debug=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_debug=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_debug=AC_ENABLE_DEBUG_DEFAULT)dnl + +if test "X$enable_debug" = "Xyes"; then + FFLAGS="$FFLAGS -g -D_DEBUG_ " + CFLAGS="$CFLAGS -g -D_DEBUG_ " + CXXFLAGS="$CXXFLAGS -g -D_DEBUG_ " +fi +]) + +# AC_DISABLE_DEBUG - set the default flag to --disable-debug +AC_DEFUN(AC_DISABLE_DEBUG, [AC_ENABLE_DEBUG(no)]) + diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/make_begin.am b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/make_begin.am new file mode 100644 index 000000000..e69de29bb diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/make_check.am b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/make_check.am new file mode 100644 index 000000000..c6e161e22 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/make_check.am @@ -0,0 +1,15 @@ + +python_cmd = env \ + SELF_ROOT_DIR=$(prefix) \ + REP_TESTS=$(prefix)/tests \ + REP_MAIL=$(prefix)/tests/maillages \ + PATH=$(bindir)/$(PACKAGE):$(PATH) \ + PYTHONPATH=$(bindir)/$(PACKAGE):$(libdir)/$(PACKAGE):$(pythondir)/$(PACKAGE):$(PYTHONPATH) \ + python + +check-local: + for f in X $(scripts_SCRIPTS) ; do \ + if test $$f != X ; then \ + ( cd $(scriptsdir) && $(python_cmd) $$f ) || exit 1 ; \ + fi ; \ + done diff --git a/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/make_end.am b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/make_end.am new file mode 100644 index 000000000..b1b0f2a09 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/adm/unix/make_end.am @@ -0,0 +1,12 @@ +SUFFIXES = + +# -------------------------------------------- +# *.i --> *_wrap.cxx +# -------------------------------------------- + +SUFFIXES += .i _wrap.cxx + +.i_wrap.cxx : + $(SWIG) $(SWIG_PYTHON_OPT) $(SWIG_PYTHON_INCLUDES) -o $@ $< + + diff --git a/src/wrappergen/bin/Cpp_Template__SRC/archive b/src/wrappergen/bin/Cpp_Template__SRC/archive new file mode 100755 index 000000000..be9d5d890 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/archive @@ -0,0 +1,34 @@ +#! /bin/bash + +# +DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` +cd ${DIR} +DIR=`pwd` + +REP=`basename $DIR` + +if [ -z "$USER" ] +then + USER=`whoami 2> /dev/null` || true +fi + +mkdir -p /tmp/${USER} +\rm -rf /tmp/${USER}/${REP} + +cd ${DIR}/.. +cp -drf ${REP} /tmp/${USER}/${REP} + +cd /tmp/${USER}/${REP} +./root_clean +find . -name "CVS" -depth -exec \rm -rf {} \; +find . -type f -exec chmod u+rw {} \; + +cd /tmp/${USER} + +TAR_FILE=${REP}`date +_%d.%m.%Y_%H.%M`.tgz + +tar cvfz ${TAR_FILE} ${REP} + +cp ${TAR_FILE} ${DIR}/.. + +\rm -rf /tmp/${USER}/${REP} ${TAR_FILE} diff --git a/src/wrappergen/bin/Cpp_Template__SRC/build_configure b/src/wrappergen/bin/Cpp_Template__SRC/build_configure new file mode 100755 index 000000000..4c157cce3 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/build_configure @@ -0,0 +1,38 @@ +#! /bin/sh + +run() { + local logfile=$ORIG_DIR/build_configure.log + printf "%-50s" "$1 ... " + eval $1 > $logfile 2>&1 + if test $? != 0 ; then + echo "[FAILED]" + echo "see file build_configure.log ..." + exit 1 + fi + echo "[ OK ]" +} + +# -- +ORIG_DIR=`pwd` + +# -- +# -- goto build_configure dir +CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` +cd ${CONF_DIR} +# -- +# -- list all Makefile.am in Makefile.am.list +./rfind . Makefile.am > Makefile.am.list +# -- +# -- configure.in construction +cp configure.in.base configure.in +chmod +w configure.in +echo "AC_OUTPUT([ \\" >> configure.in +sed -e 's,\.am, \\,' -e 's,\.\/,,' Makefile.am.list >> configure.in +echo "])" >> configure.in + +# -- +run "libtoolize" +run "aclocal -I adm/unix/config_files" +run "autoconf" +run "automake --add-missing --copy" + diff --git a/src/wrappergen/bin/Cpp_Template__SRC/configure.in.base b/src/wrappergen/bin/Cpp_Template__SRC/configure.in.base new file mode 100644 index 000000000..5f25e692a --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/configure.in.base @@ -0,0 +1,23 @@ + +AC_INIT(salome, 0.1) +AC_CONFIG_SRCDIR(src) +AM_INIT_AUTOMAKE +AC_ENABLE_DEBUG(no) +AC_DISABLE_PRODUCTION + +AC_PROG_LIBTOOL +AC_PROG_CXX +AC_PROG_CXXCPP +CHECK_PYTHON +AM_PATH_PYTHON(2.2.1) +AC_PROG_SWIG(1.3.24) +SWIG_ENABLE_CXX +SWIG_PYTHON + +CHECK_KERNEL +CHECK_MED + +AC_ENABLE_STATIC(no) + +CXXFLAGS="${CXXFLAGS} -g" +AC_SUBST(CXXFLAGS) diff --git a/src/wrappergen/bin/Cpp_Template__SRC/rfind b/src/wrappergen/bin/Cpp_Template__SRC/rfind new file mode 100755 index 000000000..4d41b4415 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/rfind @@ -0,0 +1,46 @@ +#! /bin/sh + +# +# Usage : rfind dir suffix ... +# +# find all files *suffix in dir in a recursive way +# different of the usual command find ... +# + +if test $# != 2 ; then + echo "Usage : $0 dir suffix" + exit +fi + +local_find() { + # if the first argument is not a directory, returns + if test ! -d $1 ; then + # echo "$1 is not a directory" + return + fi + # dont look in the CVS directories + # dont look in the autom4te* directories + case "$1" in + */CVS) return ;; + */autom4te*) return ;; + *) ;; + esac + # for each regular file contained in the directory + # test if it's a *"$2" file + for i in $1/* + do + if test -f $i ; then + case `basename $i` in + *$2) echo " "$i ;; + *) ;; + esac + fi + done + # for each subdirectory of the first argument, proceeds recursively + for i in $1/* + do + local_find $i $2 + done +} + +local_find $1 $2 diff --git a/src/wrappergen/bin/Cpp_Template__SRC/root_clean b/src/wrappergen/bin/Cpp_Template__SRC/root_clean new file mode 100755 index 000000000..9855bdc35 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/root_clean @@ -0,0 +1,32 @@ +#!/bin/sh + + +CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` +cd ${CONF_DIR} + +TO_CLEAN= +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}' install-sh missing mkinstalldirs' +TO_CLEAN=${TO_CLEAN}' py-compile' +TO_CLEAN=${TO_CLEAN}' build_configure.log' +TO_CLEAN=${TO_CLEAN}' depcomp' +TO_CLEAN=${TO_CLEAN}' config.guess config.sub ltmain.sh' +TO_CLEAN=${TO_CLEAN}' Makefile.am.list' +# TO_CLEAN=${TO_CLEAN}' COPYING INSTALL' + +rm -rf $TO_CLEAN > /dev/null + +l=`find . -name "Makefile.in"` + +if test X"$l" != X ; then + rm -f $l +fi + +l=`find . -name "*~"` + +if test X"$l" != X ; then + rm -f $l +fi diff --git a/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/Cpp_Template_.cxx b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/Cpp_Template_.cxx new file mode 100644 index 000000000..945644a3d --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/Cpp_Template_.cxx @@ -0,0 +1,15 @@ +#include "Cpp_Template_.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_Mesh.hxx" +#include + +using namespace std; +using namespace MED_EN; + +Cpp_Template_::Cpp_Template_() +{ +} + +MEDMEM::FIELD* Cpp_Template_::createField() +{ +} diff --git a/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/Cpp_Template_.hxx b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/Cpp_Template_.hxx new file mode 100644 index 000000000..8dd25eabf --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/Cpp_Template_.hxx @@ -0,0 +1,20 @@ +#ifndef _Cpp_Template__HXX_ +#define _Cpp_Template__HXX_ + +// MED forward declaration +#include "MEDMEM_FieldForward.hxx" +namespace MEDMEM { + class MESH; +} + +class Cpp_Template_ +{ +// Méthodes publiques +public: + Cpp_Template_(); + MEDMEM::FIELD* createField(); + // ... +private: +}; + +#endif diff --git a/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/Makefile.am b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/Makefile.am new file mode 100644 index 000000000..b6e6a60e8 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/Makefile.am @@ -0,0 +1,33 @@ +# +# Common begin part +# + +include $(top_srcdir)/adm/unix/make_begin.am + +# +# Developper part +# + +lib_LTLIBRARIES = libCpp_Template_CXX.la +libCpp_Template_CXX_la_SOURCES = Cpp_Template_.cxx +libCpp_Template_CXX_la_LIBADD = $(MED_LIBS) + +# exported headers +library_includedir=$(includedir) +library_include_HEADERS = Cpp_Template_.hxx + +INCLUDES = $(MED_INCLUDES) + + +bin_PROGRAMS = Cpp_Template__test +Cpp_Template__test_SOURCES = main.cxx +Cpp_Template__test_LDADD = -L. -lCpp_Template_CXX + + +# +# Common end part +# + +include $(top_srcdir)/adm/unix/make_end.am + + diff --git a/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/main.cxx b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/main.cxx new file mode 100644 index 000000000..eca26454c --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__CXX/main.cxx @@ -0,0 +1,12 @@ +#include "Cpp_Template_.hxx" +#include "MEDMEM_Field.hxx" +#include + +using namespace std; +int main(int argc, char ** argv) +{ + if (getenv("SALOME_trace") == NULL ) + setenv("SALOME_trace","local",0); + Cpp_Template_ myCalc; + // test myCalc component ... +} diff --git a/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__SWIG/Cpp_Template_.i b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__SWIG/Cpp_Template_.i new file mode 100644 index 000000000..eda25659f --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__SWIG/Cpp_Template_.i @@ -0,0 +1,22 @@ +%module Cpp_Template_SWIG + +%{ +#include +#include "Cpp_Template_.hxx" +%} + +/* + Initialisation block due to the LocalTraceCollector mechanism + + */ + +%init %{ + if (getenv("SALOME_trace") == NULL ) + setenv("SALOME_trace","local",0); +%} + +%include "std_vector.i" +%include "std_string.i" +%include "Cpp_Template_.hxx" + + diff --git a/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__SWIG/Makefile.am b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__SWIG/Makefile.am new file mode 100644 index 000000000..4dcb20c8b --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__SWIG/Makefile.am @@ -0,0 +1,32 @@ +# +# Common begin part +# + +include $(top_srcdir)/adm/unix/make_begin.am + +# +# Developper part +# + +lib_LTLIBRARIES = libCpp_Template_SWIG.la +nodist_libCpp_Template_SWIG_la_SOURCES = Cpp_Template__wrap.cxx + +BUILT_SOURCES = Cpp_Template__wrap.cxx + +SWIG_PYTHON_INCLUDES = $(MED_INCLUDES) -I$(top_srcdir)/src/Cpp_Template_/Cpp_Template__CXX + +INCLUDES = -I$(top_srcdir)/src/Cpp_Template_/Cpp_Template__CXX $(PYTHON_INCLUDES) $(MED_INCLUDES) + +libCpp_Template_SWIG_la_LIBADD = -L../Cpp_Template__CXX -lCpp_Template_CXX $(MED_LIBS) -lMEDMEM_Swigcmodule + + +bin_SCRIPTS = Cpp_Template_SWIG.py + +clean-local: + $(RM) Cpp_Template_SWIG.py Cpp_Template__wrap.cxx + +# +# Common end part +# + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__TEST/Cpp_Template__test.py b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__TEST/Cpp_Template__test.py new file mode 100644 index 000000000..6c62af7c3 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__TEST/Cpp_Template__test.py @@ -0,0 +1,16 @@ +from os import getenv +if getenv("SALOMEPATH"): + import salome + import Cpp_Template__ORB + my_Cpp_Template_ = salome.lcc.FindOrLoadComponent("FactoryServer", "Cpp_Template_") + IN_SALOME_GUI = 1 +else: + import Cpp_Template_SWIG + my_Cpp_Template_=Cpp_Template_SWIG.Cpp_Template_() +pass +# +# +print "Test Program of Cpp_Template_ component" + +# ... + diff --git a/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__TEST/Makefile.am b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__TEST/Makefile.am new file mode 100644 index 000000000..e69b92b15 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Cpp_Template__TEST/Makefile.am @@ -0,0 +1,7 @@ +# data_DATA = +# datadir = + +scripts_SCRIPTS = Cpp_Template__test.py +scriptsdir = $(prefix)/bin/salome + +include $(top_srcdir)/adm/unix/make_check.am diff --git a/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Makefile.am b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Makefile.am new file mode 100644 index 000000000..06dcd553f --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/src/Cpp_Template_/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = Cpp_Template__CXX Cpp_Template__SWIG Cpp_Template__TEST + + diff --git a/src/wrappergen/bin/Cpp_Template__SRC/src/Makefile.am b/src/wrappergen/bin/Cpp_Template__SRC/src/Makefile.am new file mode 100644 index 000000000..2417bcfc6 --- /dev/null +++ b/src/wrappergen/bin/Cpp_Template__SRC/src/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = Cpp_Template_ + diff --git a/src/wrappergen/bin/Deprecated b/src/wrappergen/bin/Deprecated new file mode 100644 index 000000000..7182d889a --- /dev/null +++ b/src/wrappergen/bin/Deprecated @@ -0,0 +1 @@ +Directory to be removed diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/README b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/README new file mode 100644 index 000000000..feb997b16 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/README @@ -0,0 +1,3 @@ +This file is only here for CVS: +CVS does not always create empty directory, and adm_local/unix/config_file +is needed by build_configure. diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_depend_flag.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_depend_flag.m4 new file mode 100644 index 000000000..ee49cd8a3 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_depend_flag.m4 @@ -0,0 +1,144 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl @synopsis AC_C_DEPEND_FLAG +dnl +dnl define C_DEPEND_FLAG +dnl define CXX_DEPEND_FLAG +dnl +dnl @version $Id$ +dnl @author Marc Tajchman +dnl +AC_DEFUN(AC_DEPEND_FLAG, +[AC_CACHE_CHECK(which flag for dependency information generation, +ac_cv_depend_flag, +[AC_LANG_SAVE + AC_LANG_C + echo "conftest.o: conftest.c" > conftest.verif + echo "int main() { return 0; }" > conftest.c + +dnl Evolution portage sur CCRT/osf system + case $host_os in + osf*) +dnl sur CCRT/osf pas d'equivalent de l'option -MG de gcc avec compilo natif +dnl on utilise donc gnu pour generer les dependances. + DEPCC=gcc + DEPCXX=g++ + DEPCXXFLAGS="-Wno-deprecated" + DIFFFLAGS="-w" + MACHINE="OSF1" + ;; + *) + DEPCC=${CC-cc} + DEPCXX=${CXX-c++} + DEPCXXFLAGS="\${CXXFLAGS}" + DIFFFLAGS="-b -B" + MACHINE="PCLINUX" + ;; + esac + C_DEPEND_FLAG= + for ac_C_DEPEND_FLAG in -xM -MM -M ; do + + rm -f conftest.d conftest.err + ${DEPCC} ${ac_C_DEPEND_FLAG} -c conftest.c 1> conftest.d 2> conftest.err + if test -f conftest.u ; then + mv conftest.u conftest.d + fi + + rm -f conftest + diff ${DIFFFLAGS} conftest.d conftest.verif > conftest + if test ! -s conftest ; then + C_DEPEND_FLAG=${ac_C_DEPEND_FLAG} + break + fi + done + +dnl use gcc option -MG : asume unknown file will be construct later + rm -f conftest.d conftest.err + ${DEPCC} ${C_DEPEND_FLAG} -MG -c conftest.c 1> conftest.d 2> conftest.err + if test -f conftest.u ; then + mv conftest.u conftest.d + fi + rm -f conftest + diff ${DIFFFLAGS} conftest.d conftest.verif > conftest + if test ! -s conftest ; then + C_DEPEND_FLAG=${C_DEPEND_FLAG}" -MG" + fi + + rm -f conftest* + if test "x${C_DEPEND_FLAG}" = "x" ; then + echo "cannot determine flag (C language)" + exit + fi + + printf " C : ${DEPCC} ${C_DEPEND_FLAG}" + + AC_LANG_CPLUSPLUS + echo "conftest.o: conftest.cxx" > conftest.verif + echo "int main() { return 0; }" > conftest.cxx + + CXX_DEPEND_FLAG= + for ac_CXX_DEPEND_FLAG in -xM -MM -M ; do + + rm -f conftest.d conftest.err + ${DEPCXX} ${ac_CXX_DEPEND_FLAG} -c conftest.cxx 1> conftest.d 2> conftest.err + if test -f conftest.u ; then + mv conftest.u conftest.d + fi + + rm -f conftest + diff ${DIFFFLAGS} conftest.d conftest.verif > conftest + if test ! -s conftest ; then + CXX_DEPEND_FLAG=${ac_CXX_DEPEND_FLAG} + break + fi + done + +dnl use g++ option -MG : asume unknown file will be construct later + rm -f conftest.d conftest.err + ${DEPCXX} ${CXX_DEPEND_FLAG} -MG -c conftest.cxx 1> conftest.d 2> conftest.err + if test -f conftest.u ; then + mv conftest.u conftest.d + fi + rm -f conftest + diff ${DIFFFLAGS} conftest.d conftest.verif > conftest + if test ! -s conftest ; then + CXX_DEPEND_FLAG=${CXX_DEPEND_FLAG}" -MG" + fi + + + rm -f conftest* + if test "x${CXX_DEPEND_FLAG}" = "x" ; then + echo "cannot determine flag (C++ language)" + exit + fi + + printf " C++ : ${DEPCXX} ${CXX_DEPEND_FLAG}" + AC_LANG_RESTORE + + AC_SUBST(DEPCC) + AC_SUBST(DEPCXX) + AC_SUBST(DEPCXXFLAGS) + AC_SUBST(C_DEPEND_FLAG) + AC_SUBST(CXX_DEPEND_FLAG) + AC_SUBST(MACHINE) +]) +]) diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_option.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_option.m4 new file mode 100644 index 000000000..72ea0ab11 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_option.m4 @@ -0,0 +1,45 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl @synopsis AC_CXX_OPTION(-option,variable where we add option if ok,action if ok; action if not ok) +dnl +dnl Check options for C++ compiler +dnl +dnl @author Bernard Secher - 15/01/2004 +dnl +AC_DEFUN([AC_CXX_OPTION], [ + AC_MSG_CHECKING(wether $CXX accepts $1) + cat > conftest.cxx < conftest.log 2>&1 + var=`echo $1 | sed -e "s, .*$,," | sed -e "s,^-,,"` + if ! grep -e $var conftest.log > /dev/null 2>&1 ; then + AC_MSG_RESULT(yes) + $2="${$2} $1" + eval $3 + else + AC_MSG_RESULT(no) + eval $4 + fi +]) + + diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Comp_Env.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Comp_Env.m4 new file mode 100644 index 000000000..0c8f1c631 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Comp_Env.m4 @@ -0,0 +1,25 @@ +# Check if component environment is either defined or not +# +# Author : Jean-Yves PRADILLON (OPEN CASCADE, 2005) +# + +AC_DEFUN([CHECK_COMPONENT_ENV],[ + +AC_CHECKING(for Component Environment) + +Comp_Env_ok=no + +if test -d "$HXX2SALOME_GENERIC_CLASS_NAMECPP_ROOT_DIR" ; then + Comp_Env_ok=yes + AC_MSG_RESULT(Using Component Root Dir ${HXX2SALOME_GENERIC_CLASS_NAMECPP_ROOT_DIR}) +else + AC_MSG_WARN(Cannot find Component Root Dir "${HXX2SALOME_GENERIC_CLASS_NAMECPP_ROOT_DIR}") + if test "x$HXX2SALOME_GENERIC_CLASS_NAMECPP_ROOT_DIR" = "x" ; then + AC_MSG_WARN(Did you source the environment file?) + fi +fi + +AC_MSG_RESULT(for Component Environment: $Comp_Env_ok) + +])dnl + diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_GUI.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_GUI.m4 new file mode 100755 index 000000000..fab490fad --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_GUI.m4 @@ -0,0 +1,60 @@ +# Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +#------------------------------------------------------------ +# Check availability of Salome binary distribution +# +# Author : Marc Tajchman (CEA, 2002) +#------------------------------------------------------------ + +AC_DEFUN([CHECK_SALOME_GUI],[ + +AC_CHECKING(for SalomeGUI) + +SalomeGUI_ok=yes + +AC_ARG_WITH(gui, + --with-salome_gui=DIR root directory path of SALOME GUI installation, + SALOME_GUI_DIR="$withval",SALOME_GUI_DIR="") + +if test "x$SALOME_GUI_DIR" = "x" ; then + if test "x$GUI_ROOT_DIR" != "x" ; then + SALOME_GUI_DIR=$GUI_ROOT_DIR + else + # search Salome binaries in PATH variable + AC_PATH_PROG(TEMP, libSalomeApp.so) + if test "x$TEMP" != "x" ; then + SALOME_GUI_DIR=`dirname $TEMP` + fi + fi +fi + +if test -f ${SALOME_GUI_DIR}/lib/salome/libSalomeApp.so ; then + SalomeGUI_ok=yes + AC_MSG_RESULT(Using SALOME GUI distribution in ${SALOME_GUI_DIR}) + GUI_ROOT_DIR=${SALOME_GUI_DIR} + AC_SUBST(GUI_ROOT_DIR) +else + AC_MSG_WARN("Cannot find compiled SALOME GUI distribution") +fi + +AC_MSG_RESULT(for SALOME GUI: $SalomeGUI_ok) + +])dnl + diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Kernel.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Kernel.m4 new file mode 100644 index 000000000..fc07131da --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Kernel.m4 @@ -0,0 +1,58 @@ +# Check availability of Salome's KERNEL binary distribution +# +# Author : Jerome Roy (CEA, 2003) +# + +AC_DEFUN([CHECK_KERNEL],[ + +AC_CHECKING(for Kernel) + +Kernel_ok=no + +AC_ARG_WITH(kernel, + [ --with-kernel=DIR root directory path of KERNEL build or installation], + KERNEL_DIR="$withval",KERNEL_DIR="") + +if test "x$KERNEL_DIR" = "x" ; then + +# no --with-kernel-dir option used + + if test "x$KERNEL_ROOT_DIR" != "x" ; then + + # KERNEL_ROOT_DIR environment variable defined + KERNEL_DIR=$KERNEL_ROOT_DIR + + else + + # search Kernel binaries in PATH variable + AC_PATH_PROG(TEMP, runSalome) + if test "x$TEMP" != "x" ; then + KERNEL_BIN_DIR=`dirname $TEMP` + KERNEL_DIR=`dirname $KERNEL_BIN_DIR` + fi + + fi +# +fi + +if test -f ${KERNEL_DIR}/bin/salome/runSalome ; then + Kernel_ok=yes + AC_MSG_RESULT(Using Kernel module distribution in ${KERNEL_DIR}) + + if test "x$KERNEL_ROOT_DIR" = "x" ; then + KERNEL_ROOT_DIR=${KERNEL_DIR} + fi + if test "x$KERNEL_SITE_DIR" = "x" ; then + KERNEL_SITE_DIR=${KERNEL_ROOT_DIR} + fi + AC_SUBST(KERNEL_ROOT_DIR) + AC_SUBST(KERNEL_SITE_DIR) + +else + AC_MSG_WARN("Cannot find compiled Kernel module distribution") +fi + +AC_MSG_RESULT(for Kernel: $Kernel_ok) + +])dnl + diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med.m4 new file mode 100644 index 000000000..35d34f071 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med.m4 @@ -0,0 +1,119 @@ +# Check availability of Med binary distribution +# +# Author : Anthony GEAY (CEA, 2005) +# + +AC_DEFUN([CHECK_MED],[ + +CHECK_HDF5 +CHECK_MED2 + +AC_CHECKING(for Med) + +Med_ok=no + +AC_ARG_WITH(med, + [ --with-med=DIR root directory path of MED installation ], + MED_DIR="$withval",MED_DIR="") + +if test "x$MED_DIR" == "x" ; then + +# no --with-med-dir option used + + if test "x$MED_ROOT_DIR" != "x" ; then + + # MED_ROOT_DIR environment variable defined + MED_DIR=$MED_ROOT_DIR + + else + + # search Med binaries in PATH variable + AC_PATH_PROG(TEMP, libMEDMEM_Swig.py) + if test "x$TEMP" != "x" ; then + MED_BIN_DIR=`dirname $TEMP` + MED_DIR=`dirname $MED_BIN_DIR` + fi + + fi +# +fi + +if test -f ${MED_DIR}/bin/salome/libMEDMEM_Swig.py ; then + Med_ok=yes + AC_MSG_RESULT(Using Med module distribution in ${MED_DIR}) + + if test "x$MED_ROOT_DIR" == "x" ; then + MED_ROOT_DIR=${MED_DIR} + fi + AC_SUBST(MED_ROOT_DIR) + MED_INCLUDES="-I${MED_ROOT_DIR}/include/salome ${MED2_INCLUDES} ${HDF5_INCLUDES} -I${KERNEL_ROOT_DIR}/include/salome" + MED_LIBS="-L${MED_ROOT_DIR}/lib/salome -lmedmem" + AC_SUBST(MED_INCLUDES) + AC_SUBST(MED_LIBS) + +else + AC_MSG_WARN("Cannot find Med module sources") +fi + +AC_MSG_CHECKING([for MED memory version]) +[medmem_version=`cat ${MED_ROOT_DIR}/bin/salome/VERSION | cut -d" " -f7`] +[medmem_version=`expr $medmem_version : '\([0-9.]*\).*'`] +AC_MSG_RESULT([$medmem_version]) +AC_MSG_CHECKING([for g++ version]) +[gpp_version=`g++ --version | sed -e '2,$d' | cut -d" " -f3`] +AC_MSG_RESULT([$gpp_version]) +[available=$gpp_version] +dnl Analyzing g++ version +[available_major=`echo $available | sed 's/[^0-9].*//'`] +if test -z "$available_major" ; then + [available_major=0] +fi +[available=`echo $available | sed 's/[0-9]*[^0-9]//'`] +[available_minor=`echo $available | sed 's/[^0-9].*//'`] +if test -z "$available_minor" ; then + [available_minor=0] +fi +[available=`echo $available | sed 's/[0-9]*[^0-9]//'`] +[available_patch=`echo $available | sed 's/[^0-9].*//'`] +if test -z "$available_patch" ; then + [available_patch=0] +fi +dnl Testing if g++ verion >= 3.4.0 or not +if test $available_major -ne "3" \ + -o $available_minor -ne "4" \ + -o $available_patch -lt "0" ; then + [required_medmem_major=2] + [required_medmem_minor=2] + [required_medmem_patch=0] +else + [required_medmem_major=2] + [required_medmem_minor=2] + [required_medmem_patch=4] +fi +[available=$medmem_version] +[available_major=`echo $available | sed 's/[^0-9].*//'`] +if test -z "$available_major" ; then + [available_major=0] +fi +[available=`echo $available | sed 's/[0-9]*[^0-9]//'`] +[available_minor=`echo $available | sed 's/[^0-9].*//'`] +if test -z "$available_minor" ; then + [available_minor=0] +fi +[available=`echo $available | sed 's/[0-9]*[^0-9]//'`] +[available_patch=`echo $available | sed 's/[^0-9].*//'`] +if test -z "$available_patch" ; then + [available_patch=0] +fi +[available_num=`expr $available_major \* 100 + $available_minor \* 10 + $available_patch`] +[required_num=`expr $required_medmem_major \* 100 + $required_medmem_minor \* 10 + $required_medmem_patch`] +if test "x$Med_ok" == "xyes" ; then + if test $available_num -lt $required_num ; then + AC_MSG_WARN([MEDMEM version invalid with your compiler : MEDMEM version >=2.2.4 required !!!]) + Med_ok=no + fi +fi +AC_MSG_RESULT(for MED memory: $Med_ok) + +])dnl + diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med2.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med2.m4 new file mode 100644 index 000000000..82b107880 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med2.m4 @@ -0,0 +1,114 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl + +AC_DEFUN([CHECK_MED2],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([CHECK_HDF5])dnl + +AC_CHECKING(for MED2) + +AC_ARG_WITH(med2, + [ --with-med2=DIR root directory path to med2 installation ], + [MED2HOME="$withval" + AC_MSG_RESULT("select $withval as path to med2") + ]) + +AC_SUBST(MED2_INCLUDES) +AC_SUBST(MED2_LIBS) +AC_SUBST(MED2_MT_LIBS) + +MED2_INCLUDES="" +MED2_LIBS="" +MED2_MT_LIBS="" + +med2_ok=no + +LOCAL_INCLUDES="$HDF5_INCLUDES" +LOCAL_LIBS="-lmed $HDF5_LIBS" + +if test -z $MED2HOME +then + AC_MSG_WARN(undefined MED2HOME variable which specify med2 installation directory) + AC_PATH_PROG(MDUMP, mdump) + if test "xMDUMP" != "x" ; then + MED2HOME=$MDUMP + MED2HOME=`echo ${MED2HOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + MED2HOME=`echo ${MED2HOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + fi +fi +if test ! -z $MED2HOME +then + LOCAL_INCLUDES="$LOCAL_INCLUDES -I$MED2HOME/include" + if test "x$MED2HOME" = "x/usr" + then + LOCAL_LIBS="-lmed $LOCAL_LIBS" + else + LOCAL_LIBS="-L$MED2HOME/lib $LOCAL_LIBS" + fi +fi + +dnl check med2 header + +CPPFLAGS_old="$CPPFLAGS" +dnl we must test system : linux = -DPCLINUX +dnl we must test system : Alpha-OSF = -DOSF1 +case $host_os in + linux*) + CPPFLAGS="$CPPFLAGS -DPCLINUX $LOCAL_INCLUDES" + ;; + osf*) + CPPFLAGS="$CPPFLAGS -DOSF1 $LOCAL_INCLUDES" + ;; +esac +AC_CHECK_HEADER(med.h,med2_ok=yes ,med2_ok=no) +CPPFLAGS="$CPPFLAGS_old" + +if test "x$med2_ok" = "xyes" +then + +dnl check med2 library + + LIBS_old="$LIBS" + LIBS="$LIBS $LOCAL_LIBS" + AC_CHECK_LIB(med,MEDouvrir,med2_ok=yes,med2_ok=no) + LIBS="$LIBS_old" + +fi + +if test "x$med2_ok" = "xyes" +then +case $host_os in + linux*) + MED2_INCLUDES="-DPCLINUX $LOCAL_INCLUDES" + ;; + osf*) + MED2_INCLUDES="-DOSF1 $LOCAL_INCLUDES" + ;; +esac + MED2_LIBS="$LOCAL_LIBS" + MED2_MT_LIBS="$LOCAL_LIBS" +fi + +AC_MSG_RESULT(for med2: $med2_ok) + +])dnl diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_hdf5.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_hdf5.m4 new file mode 100644 index 000000000..b20db13ac --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_hdf5.m4 @@ -0,0 +1,88 @@ +# Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +AC_DEFUN([CHECK_HDF5],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl + +AC_CHECKING(for HDF5) + +AC_ARG_WITH(hdf5, + [ --with-hdf5=DIR root directory path to hdf5 installation ], + [HDF5HOME="$withval" + AC_MSG_RESULT("select $withval as path to hdf5") + ]) + +AC_SUBST(HDF5_INCLUDES) +AC_SUBST(HDF5_LIBS) +AC_SUBST(HDF5_MT_LIBS) + +HDF5_INCLUDES="" +HDF5_LIBS="" +HDF5_MT_LIBS="" + +hdf5_ok=no + +LOCAL_INCLUDES="" +LOCAL_LIBS="" + +if test -z $HDF5HOME +then + AC_MSG_WARN(undefined HDF5HOME variable which specify hdf5 installation directory) +else + LOCAL_INCLUDES="-I$HDF5HOME/include" + if test "x$HDF5HOME" = "x/usr" + then + LOCAL_LIBS="" + else + LOCAL_LIBS="-L$HDF5HOME/lib" + fi +fi + +dnl hdf5 headers + +CPPFLAGS_old="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $LOCAL_INCLUDES" +AC_CHECK_HEADER(hdf5.h,hdf5_ok=yes ,hdf5_ok=no) +CPPFLAGS="$CPPFLAGS_old" + + +if test "x$hdf5_ok" = "xyes" +then + +dnl hdf5 library + + LIBS_old="$LIBS" + LIBS="$LIBS $LOCAL_LIBS" + AC_CHECK_LIB(hdf5,H5open,hdf5_ok=yes,hdf5_ok=no) + LIBS="$LIBS_old" + +fi + +if test "x$hdf5_ok" = "xyes" +then + HDF5_INCLUDES="$LOCAL_INCLUDES" + HDF5_LIBS="$LOCAL_LIBS -lhdf5" + HDF5_MT_LIBS="$LOCAL_LIBS -lhdf5" +fi + +AC_MSG_RESULT(for hdf5: $hdf5_ok) + +])dnl diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_med2.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_med2.m4 new file mode 100644 index 000000000..c13888195 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_med2.m4 @@ -0,0 +1,96 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl + +AC_DEFUN([CHECK_MED2],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([CHECK_HDF5])dnl +AC_REQUIRE([AC_DEPEND_FLAG])dnl + +AC_CHECKING(for MED2) + +AC_ARG_WITH(med2, + [ --with-med2=DIR root directory path to med2 installation ], + [MED2HOME="$withval" + AC_MSG_RESULT("select $withval as path to med2") + ]) + +AC_SUBST(MED2_INCLUDES) +AC_SUBST(MED2_LIBS) +AC_SUBST(MED2_MT_LIBS) + +MED2_INCLUDES="" +MED2_LIBS="" +MED2_MT_LIBS="" + +LOCAL_INCLUDES="" +LOCAL_LIBS="" + +med2_ok=no + +dnl check, if there is MED library +if test -z $MED2HOME +then + AC_MSG_WARN(undefined MED2HOME variable which specify med2 installation directory) + AC_PATH_PROG(MDUMP, mdump) + if test "xMDUMP" != "x" ; then + MED2HOME=$MDUMP + MED2HOME=`echo ${MED2HOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + MED2HOME=`echo ${MED2HOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + fi +fi +if test ! -z $MED2HOME +then + LOCAL_INCLUDES="$HDF5_INCLUDES -I$MED2HOME/include" + if test "x$MED2HOME" = "x/usr" + then + LOCAL_LIBS="-lmed $HDF5_LIBS" + else + LOCAL_LIBS="-L$MED2HOME/lib -lmed $HDF5_LIBS" + fi +fi + +dnl check med2 header +CPPFLAGS_old="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS -D$MACHINE $LOCAL_INCLUDES" +AC_CHECK_HEADER(med.h,med2_ok=yes ,med2_ok=no) +CPPFLAGS="$CPPFLAGS_old" + +dnl check med2 library +if test "x$med2_ok" = "xyes" +then + LIBS_old="$LIBS" + LIBS="$LIBS $LOCAL_LIBS" + AC_CHECK_LIB(med,MEDouvrir,med2_ok=yes,med2_ok=no) + LIBS="$LIBS_old" +fi + +if test "x$med2_ok" = "xyes" +then + MED2_INCLUDES="-D$MACHINE $LOCAL_INCLUDES" + MED2_LIBS="$LOCAL_LIBS" + MED2_MT_LIBS="$LOCAL_LIBS" +fi + +AC_MSG_RESULT(for med2: $med2_ok) + +])dnl diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_omniorb.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_omniorb.m4 new file mode 100644 index 000000000..1f63365bf --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_omniorb.m4 @@ -0,0 +1,306 @@ + +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) + + ENABLE_PTHREADS + + 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 + 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="-bpython -I$OMNIORB_ROOT/idl" + 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/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_pthreads.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_pthreads.m4 new file mode 100644 index 000000000..80aef2aad --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_pthreads.m4 @@ -0,0 +1,50 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +#@synonpsis CHECK_PTHREADS +dnl check for pthreads system interfaces. +dnl set CFLAGS_PTHREADS, CXXFLAGS_PTHREADS and LIBS_PTHREADS to +dnl flags to compiler flags for multithread program compilation (if exists), +dnl and library, if one required. +dnl +dnl@author (C) Ruslan Shevchenko , 1998 +dnl@id $Id$ +dnl ---------------------------------------------------------------- +dnl CHECK_PTHREADS +AC_DEFUN([CHECK_PTHREADS],[ +AC_CXX_OPTION(-pthread,CPPFLAGS,flag=yes,flag=no) + +if test $flag = no; then + AC_REQUIRE([AC_CANONICAL_SYSTEM])dnl + AC_CHECK_HEADER(pthread.h,AC_DEFINE(HAVE_PTHREAD_H)) + AC_CHECK_LIB(posix4,nanosleep, LIBS_PTHREADS="-lposix4",LIBS_PTHREADS="") + AC_CHECK_LIB(pthread,pthread_mutex_lock, + LIBS_PTHREADS="-lpthread $LIBS_PTHREADS",LIBS_PTHREADS="") +fi + +if test $flag = no && x$LIBS_PTHREADS = x; then + threads_ok=no +else + threads_ok=yes +fi +])dnl +dnl +dnl diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/enable_pthreads.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/enable_pthreads.m4 new file mode 100644 index 000000000..45652fbb5 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/enable_pthreads.m4 @@ -0,0 +1,41 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl@synopsis ENABLE_PTHREADS +dnl +dnl modify CFLAGS, CXXFLAGS and LIBS for compiling pthread-based programs. +dnl +dnl@author (C) Ruslan Shevchenko , 1998, 2000 +dnl@id $Id$ +dnl +dnl +AC_DEFUN([ENABLE_PTHREADS],[ +AC_REQUIRE([CHECK_PTHREADS]) + +if test -z "$enable_pthreads_done" +then + CFLAGS="$CFLAGS $CFLAGS_PTHREADS" + CXXFLAGS="$CXXFLAGS $CXXFLAGS_PTHREADS" + LIBS="$LIBS $LIBS_PTHREADS" +fi +enable_pthreads_done=yes +])dnl +dnl diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/python.m4 b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/python.m4 new file mode 100644 index 000000000..ddd0c06a5 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/python.m4 @@ -0,0 +1,65 @@ +dnl @synopsis AC_PYTHON_DEVEL() +dnl +dnl Checks for Python and tries to get the include path to 'Python.h'. +dnl It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) output variable. +dnl +dnl @authors Sebastian Huber , Alan W. Irwin +dnl , Rafael Laboissiere and +dnl Andrew Collier . +dnl +dnl +AC_DEFUN([CHECK_PYTHON],[ + # + # should allow for checking of python version here... + # + AC_REQUIRE([AM_PATH_PYTHON]) + + case `uname -m` in + *64) LIB="64" ;; + *) LIB="" ;; + esac + + # Check for Python include path + AC_MSG_CHECKING([for Python include path]) + python_path=`echo $PYTHON | sed "s,/bin.*$,,"` + for i in "$python_path/include/python$PYTHON_VERSION/" "$python_path/include/python/" "$python_path/" ; do + python_path=`find $i -type f -name Python.h -print | sed "1q"` + if test -n "$python_path" ; then + break + fi + done + python_path=`echo $python_path | sed "s,/Python.h$,,"` + AC_MSG_RESULT([$python_path]) + if test -z "$python_path" ; then + AC_MSG_ERROR([cannot find Python include path]) + fi + AC_SUBST([PYTHON_CPPFLAGS],[-I$python_path]) + + # Check for Python library path + AC_MSG_CHECKING([for Python library path]) + python_path=`echo $PYTHON | sed "s,/bin.*$,,"` + for i in "$python_path/lib${LIB}/python$PYTHON_VERSION/config/" "$python_path/lib${LIB}/python$PYTHON_VERSION/" "$python_path/lib{LIB}/python/config/" "$python_path/lib${LIB}/python/" "$python_path/" ; do + python_path=`find $i -type f -name libpython$PYTHON_VERSION.* -print | sed "1q"` + if test -n "$python_path" ; then + break + fi + done + python_path=`echo $python_path | sed "s,/libpython.*$,,"` + AC_MSG_RESULT([$python_path]) + if test -z "$python_path" ; then + AC_MSG_ERROR([cannot find Python library path]) + fi + AC_SUBST([PYTHON_LDFLAGS],["-L$python_path -lpython$PYTHON_VERSION"]) + # + python_site=`echo $python_path | sed "s/config/site-packages/"` + AC_SUBST([PYTHON_SITE_PKG],[$python_site]) + # + # libraries which must be linked in when embedding + # + AC_MSG_CHECKING(python extra libraries) + PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \ + conf = distutils.sysconfig.get_config_var; \ + print conf('LOCALMODLIBS')+' '+conf('LIBS')" + AC_MSG_RESULT($PYTHON_EXTRA_LIBS)` + AC_SUBST(PYTHON_EXTRA_LIBS) +]) diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_commence.in b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_commence.in new file mode 100644 index 000000000..b4ab44da3 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_commence.in @@ -0,0 +1,260 @@ +# common directories to put headerfiles +inc_builddir=$(top_builddir)/include/salome + +@SET_MAKE@ +SHELL=/bin/sh + +# header missing + +HAVE_SSTREAM=@HAVE_SSTREAM@ + + +LIBS=@LIBS@ +LDFLAGS=@LDFLAGS@ -L$(top_builddir)/lib/salome -Xlinker -rpath-link -Xlinker -L$(top_builddir)/lib/salome +# add libstdc++ to link c++ library with libtool ! +LDFLAGS+= -lstdc++ + +CP=@CP@ + +# CPP + +CPP=@CPP@ +CXXCPP=@CXXCPP@ +CPPFLAGS=@CPPFLAGS@ -I$(inc_builddir) -I$(srcdir) -I. + +# C + +CC = @CC@ +CFLAGS = @CFLAGS@ +C_DEPEND_FLAG = @C_DEPEND_FLAG@ + +# C++ + +CXX = @CXX@ +CXXFLAGS = @CXXFLAGS@ +CXX_DEPEND_FLAG = @CXX_DEPEND_FLAG@ + +# BOOST Library + +BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ + +# JAVA + +JAVA_INCLUDES = @JAVA_INCLUDES@ +JAVA_LIBS = @JAVA_LIBS@ +JAVA_LDPATH = @JAVA_LDPATH@ + +# PYTHON + +PYTHON = @PYTHON@ +PYTHONHOME = @PYTHONHOME@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_LIBS = @PYTHON_LIBS@ +PYTHON_VERSION = @PYTHON_VERSION@ +PYTHON_SITE = @PYTHON_SITE@ +PYTHON_SITE_INSTALL = @PYTHON_SITE_INSTALL@ + +# QT + +QT_ROOT = @QT_ROOT@ +QT_INCLUDES = @QT_INCLUDES@ +QT_MT_INCLUDES = @QT_INCLUDES@ -DQT_THREAD_SUPPORT +QT_LIBS = @QT_LIBS@ +QT_MT_LIBS = @QT_MT_LIBS@ + +MOC = @MOC@ +UIC = @UIC@ + +# msg2qm + +MSG2QM = @MSG2QM@ + +#QWT + +QWT_INCLUDES=@QWT_INCLUDES@ +QWT_LIBS=@QWT_LIBS@ + +# SIP +SIP = @SIP@ +SIP_INCLUDES = @SIP_INCLUDES@ +SIP_LIBS = @SIP_LIBS@ + +# PYQT +PYQT_SIPS = @PYQT_SIPS@ +PYQT_LIBS = @PYQT_LIBS@ + +# openGL +OGL_INCLUDES=@OGL_INCLUDES@ +OGL_LIBS=@OGL_LIBS@ + +# VTK +VTK_INCLUDES=@VTK_INCLUDES@ +VTK_LIBS=@VTK_LIBS@ + +# HDF5 + +HDF5_INCLUDES=@HDF5_INCLUDES@ +HDF5_LIBS=@HDF5_LIBS@ +HDF5_MT_LIBS=@HDF5_MT_LIBS@ + +# MED2 + +MED2_INCLUDES=@MED2_INCLUDES@ +MED2_LIBS=@MED2_LIBS@ +MED2_MT_LIBS=@MED2_MT_LIBS@ + +# OpenCasCade + +OCC_INCLUDES=@CAS_CPPFLAGS@ +OCC_CXXFLAGS=@CAS_CXXFLAGS@ + +OCC_KERNEL_LIBS=@CAS_KERNEL@ +OCC_OCAF_LIBS=@CAS_OCAF@ +OCC_VIEWER_LIBS=@CAS_VIEWER@ +OCC_MODELER_LIBS=@CAS_MODELER@ +OCC_DATAEXCHANGE_LIBS=@CAS_DATAEXCHANGE@ +OCC_LIBS=@CAS_LDFLAGS@ + +# MPICH + +MPICH_INCLUDES=@MPICH_INCLUDES@ +MPICH_LIBS=@MPICH_LIBS@ + +# Swig C++ Python + +SWIG = @SWIG@ +SWIG_FLAGS = @SWIG_FLAGS@ -I$(inc_builddir) -I$(srcdir) -I. + +# OMNIORB + +OMNIORB_ROOT = @OMNIORB_ROOT@ +OMNIORB_INCLUDES = @OMNIORB_INCLUDES@ +OMNIORB_LIBS = @OMNIORB_LIBS@ +OMNIORB_CXXFLAGS = @OMNIORB_CXXFLAGS@ + +OMNIORB_IDL = @OMNIORB_IDL@ +OMNIORB_IDLCXXFLAGS = @OMNIORB_IDLCXXFLAGS@ +OMNIORB_IDLPYFLAGS = @OMNIORB_IDLPYFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl -I$(KERNEL_ROOT_DIR)/idl/salome + +OMNIORB_IDL_CLN_H = @OMNIORB_IDL_CLN_H@ +OMNIORB_IDL_CLN_CXX = @OMNIORB_IDL_CLN_CXX@ +OMNIORB_IDL_CLN_OBJ = @OMNIORB_IDL_CLN_OBJ@ + +OMNIORB_IDL_SRV_H = @OMNIORB_IDL_SRV_H@ +OMNIORB_IDL_SRV_CXX = @OMNIORB_IDL_SRV_CXX@ +OMNIORB_IDL_SRV_OBJ = @OMNIORB_IDL_SRV_OBJ@ + +# Default ORB + +CORBA_ROOT = @CORBA_ROOT@ +CORBA_INCLUDES = @CORBA_INCLUDES@ +CORBA_LIBS = @CORBA_LIBS@ +CORBA_CXXFLAGS = @CORBA_CXXFLAGS@ + +IDLCXXFLAGS = -bcxx @IDLCXXFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl -I$(KERNEL_ROOT_DIR)/idl/salome +IDLPYFLAGS = @IDLPYFLAGS@ + +IDL = @IDL@ + +IDL_CLN_H = @IDL_CLN_H@ +IDL_CLN_CXX = @IDL_CLN_CXX@ +IDL_CLN_OBJ = @IDL_CLN_OBJ@ + +IDL_SRV_H = @IDL_SRV_H@ +IDL_SRV_CXX = @IDL_SRV_CXX@ +IDL_SRV_OBJ = @IDL_SRV_OBJ@ + +CPPFLAGS+= $(CORBA_INCLUDES) +CXXFLAGS+= $(CORBA_CXXFLAGS) + +# add corba libs when link salome application ! +#LDFLAGS+= $(CORBA_LIBS) +LIBS+=$(CORBA_LIBS) + +## Shared libraries +LT_STATIC_EXEC=@LT_STATIC_EXEC@ +DYNAMIC_DIRS=@DYNAMIC_DIRS@ +LT_LIB=libtool +LT=$(top_builddir)/libtool +LT_COMPILE=$(LT) --mode=compile $(CC) +LT_LINK_LIB=$(LT_LIB) --mode=link $(CC) -rpath $(libdir) +LT_LINK_EXE=$(LT) --mode=link $(CC) $(LT_STATIC_EXEC) -dlopen self -rpath $(bindir) $(DYNAMIC_DIRS) +LT_RUN=$(LT) --mode=execute +LT_INSTALL_PROG=$(LT) --mode=install $(INSTALL_PROGRAM) +LT_INSTALL_LIB=$(LT) --mode=install $(INSTALL_DATA) +LT_UNINSTALL=$(LT) --mode=uninstall $(RM) + +INSTALL=@INSTALL@ +INSTALL_PROGRAM=@INSTALL_PROGRAM@ +INSTALL_DATA=@INSTALL_DATA@ + +# create a symbolic link (or a copie ?) +LN_S=@LN_S@ + +## Installation points +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@/salome +libdir=@libdir@/salome +# warning : if user give this path in configure we could have salome/salome :-( +includedir=@includedir@/salome +datadir=@datadir@/salome +idldir=$(prefix)/idl/salome +sharedpydir=@libdir@/python$(PYTHON_VERSION)/site-packages/salome/shared_modules + +docdir=$(datadir)/doc + +# +# begin of package rules +# + +.PHONY: all lib bin inc resources tests install uninstall dep depend depend_idl cleandep mostlyclean clean distclean + +.SUFFIXES: .cxx .cc .c .f .o .lo .idl .py .i .ui .po .qm + +all: + $(MAKE) inc + $(MAKE) depend_idl + $(MAKE) depend + $(MAKE) lib + $(MAKE) bin + $(MAKE) resources + +# +# add target to build administrative files +# + +Makefile: $(top_builddir)/config.status $(srcdir)/Makefile.in + cd $(top_builddir) ; ./config.status + +$(top_builddir)/config.status: $(top_srcdir)/configure + cd $(top_builddir) ; ./config.status --recheck + +# VPATH contain $(srcdir), so make configure is good in top_srcdir and we must add target configure otherwise :-) +ifneq ($(top_srcdir),$(srcdir)) +configure: $(top_srcdir)/configure +endif + +$(top_srcdir)/configure: $(top_srcdir)/configure.in $(top_srcdir)/aclocal.m4 + cd $(top_srcdir) ; autoconf + +$(top_srcdir)/configure.in: $(top_srcdir)/configure.in.base + cd $(top_srcdir) && ./build_configure + + +ACLOCAL_SRC = \ +ac_cxx_bool.m4 check_corba.m4 \ +ac_cxx_depend_flag.m4 check_hdf5.m4 enable_pthreads.m4 \ +ac_cxx_mutable.m4 check_mico.m4 libtool.m4 \ +ac_cxx_namespaces.m4 check_omniorb.m4 pyembed.m4 \ +ac_cxx_partial_specialization.m4 check_opengl.m4 python.m4 \ +ac_cxx_typename.m4 check_pthreads.m4 check_cas.m4 \ +ac_cc_warnings.m4 check_swig.m4 + +ACLOCAL_GUI = \ +check_vtk.m4 check_qt.m4 + +$(top_srcdir)/aclocal.m4: $(ACLOCAL_SRC:%=@KERNEL_ROOT_DIR@/salome_adm/unix/config_files/%) \ + $(ACLOCAL_GUI:%=@GUI_ROOT_DIR@/adm_local/unix/config_files/%) + cd $(top_srcdir) ; aclocal --acdir=adm_local/unix/config_files -I @KERNEL_ROOT_DIR@/salome_adm/unix/config_files \ + -I @GUI_ROOT_DIR@/adm_local/unix/config_files diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_omniorb.in b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_omniorb.in new file mode 100644 index 000000000..8e825769a --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_omniorb.in @@ -0,0 +1,56 @@ +#======================================================================= +# Begin specific part to omniorb +# (include from file adm/unix/make_omniorb generated by +# adm/unix/make_omniorb.in) +#======================================================================= +# -* Makefile *- +# +# Author : Patrick GOLDBRONN (CEA) +# Date : 29/06/2001 +# $Header$ +# + +# Client and server object are the same with omniorb +# There are one header file and one source file generate + +#IDLOBJ=$(IDLSRC:%.idl=%$(IDL_CLN_OBJ)) + +# dependancies between idl and it's generated files +%$(OMNIORB_IDL_CLN_CXX) %$(OMNIORB_IDL_CLN_H): ${KERNEL_ROOT_DIR}/idl/salome/%.idl + $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $< + +%$(OMNIORB_IDL_CLN_CXX) %$(OMNIORB_IDL_CLN_H): ${MED_ROOT_DIR}/idl/salome/%.idl + $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $< + +%$(OMNIORB_IDL_CLN_CXX) %$(OMNIORB_IDL_CLN_H): ${top_srcdir}/idl/%.idl + $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $< + +# dependncies between idl files +depend_idl: .depidl + +# we use cpp to generate dependencies between idl files. +# we change cpp output to keep only idl file and transform it to get a suitable rule +.depidl: $(IDL_FILES) + @touch $@ + @for dep in $? dummy; do \ + if [ $$dep != "dummy" ]; then \ + echo Building dependencies for $$dep; \ + basedep=`basename $$dep .idl`; \ + header="$$basedep"$(IDL_CLN_H); \ + sed '\%^'"$$header"':%,\%[^\\]$$%d' <$@ >$@- && mv $@- $@; \ + $(CPP) $(C_DEPEND_FLAG) -I$(srcdir) $$dep 2>/dev/null | \ + sed `echo "s%$$basedep\\.idl%$$header:%g"` | \ + sed 's% $(srcdir)/% %g' | \ + sed 's% $(top_srcdir)/% %g' | \ + sed 's% $(top_builddir)/% %g' | \ + sed 's%^.*:\.o: *%%' | sed 's%^ *\\ *%%'| sed 's%^ *\(.*\):%\1:%' | \ + sed 's/\.idl/$(IDL_CLN_H)/' >>$@; \ + echo '' >>$@; \ + fi; \ + done ; + +-include .depidl + +#======================================================================= +# End specific part to omniorb +#======================================================================= diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/VERSION b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/VERSION new file mode 100755 index 000000000..1c4649487 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/VERSION @@ -0,0 +1,2 @@ +SALOME 2 EXEMPLE MODULE C++ : HXX2SALOME_GENERIC_CLASS_NAME +This module works with KERNEL 1.2.1 diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runAppli.in b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runAppli.in new file mode 100755 index 000000000..38d2d74d1 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runAppli.in @@ -0,0 +1,8 @@ +#!/bin/sh + +export KERNEL_ROOT_DIR=@KERNEL_ROOT_DIR@ +export PYHXX2SALOME_GENERIC_CLASS_NAME_ROOT_DIR=@prefix@ + +python -i $HXX2SALOME_GENERIC_CLASS_NAME_ROOT_DIR/bin/salome/runSalome.py --modules=HXX2SALOME_GENERIC_CLASS_NAME --xterm --containers=cpp,python --killall + + diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runSalome.py b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runSalome.py new file mode 100755 index 000000000..d270554f7 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runSalome.py @@ -0,0 +1,506 @@ +#!/usr/bin/env python + +usage="""USAGE: runSalome.py [options] + +[command line options] : +--help : affichage de l'aide +--gui : lancement du GUI +--logger : redirection des messages dans un fichier +--xterm : les serveurs ouvrent une fenêtre xterm et les messages sont affichés dans cette fenêtre +--modules=module1,module2,... : où modulen est le nom d'un module Salome à charger dans le catalogue +--containers=cpp,python,superv: lancement des containers cpp, python et de supervision +--killall : arrêt des serveurs de salome + + La variable d'environnement _ROOT_DIR doit etre préalablement + positionnée (modulen doit etre en majuscule). + KERNEL_ROOT_DIR est obligatoire. +""" + +# ----------------------------------------------------------------------------- +# +# Fonction d'arrêt de salome +# + +def killSalome(): + print "arret des serveurs SALOME" + for pid, cmd in process_id.items(): + print "arret du process %s : %s"% (pid, cmd[0]) + try: + os.kill(pid,signal.SIGKILL) + except: + print " ------------------ process %s : %s inexistant"% (pid, cmd[0]) + print "arret du naming service" + os.system("killall -9 omniNames") + +# ----------------------------------------------------------------------------- +# +# Fonction message +# + +def message(code, msg=''): + if msg: print msg + sys.exit(code) + +import sys,os,string,glob,time,signal,pickle,getopt + +init_time=os.times() +opts, args=getopt.getopt(sys.argv[1:], 'hmglxck:', ['help','modules=','gui','logger','xterm','containers=','killall']) +modules_root_dir={} +process_id={} +liste_modules={} +liste_containers={} +with_gui=0 +with_logger=0 +with_xterm=0 + +with_container_cpp=0 +with_container_python=0 +with_container_superv=0 + +try: + for o, a in opts: + if o in ('-h', '--help'): + print usage + sys.exit(1) + elif o in ('-g', '--gui'): + with_gui=1 + elif o in ('-l', '--logger'): + with_logger=1 + elif o in ('-x', '--xterm'): + with_xterm=1 + elif o in ('-m', '--modules'): + liste_modules = [x.upper() for x in a.split(',')] + elif o in ('-c', '--containers'): + liste_containers = [x.lower() for x in a.split(',')] + for r in liste_containers: + if r not in ('cpp', 'python', 'superv'): + message(1, 'Invalid -c/--containers option: %s' % a) + if 'cpp' in liste_containers: + with_container_cpp=1 + else: + with_container_cpp=0 + if 'python' in liste_containers: + with_container_python=1 + else: + with_container_python=0 + if 'superv' in liste_containers: + with_container_superv=1 + else: + with_container_superv=0 + elif o in ('-k', '--killall'): + filedict='/tmp/'+os.getenv('USER')+'_SALOME_pidict' + #filedict='/tmp/'+os.getlogin()+'_SALOME_pidict' + found = 0 + try: + fpid=open(filedict, 'r') + found = 1 + except: + print "le fichier %s des process SALOME n'est pas accessible"% filedict + + if found: + process_id=pickle.load(fpid) + fpid.close() + killSalome() + process_id={} + os.remove(filedict) + +except getopt.error, msg: + print usage + sys.exit(1) + +# ----------------------------------------------------------------------------- +# +# Vérification des variables d'environnement +# +try: + kernel_root_dir=os.environ["KERNEL_ROOT_DIR"] + modules_root_dir["KERNEL"]=kernel_root_dir +except: + print usage + sys.exit(1) + +for module in liste_modules : + try: + module=module.upper() + module_root_dir=os.environ[module +"_ROOT_DIR"] + modules_root_dir[module]=module_root_dir + except: + print usage + sys.exit(1) + +# il faut KERNEL en premier dans la liste des modules +# - l'ordre des modules dans le catalogue sera identique +# - la liste des modules presents dans le catalogue est exploitée pour charger les modules CORBA python, +# il faut charger les modules python du KERNEL en premier + +if "KERNEL" in liste_modules:liste_modules.remove("KERNEL") +liste_modules[:0]=["KERNEL"] +#print liste_modules +#print modules_root_dir + +os.environ["SALOMEPATH"]=":".join(modules_root_dir.values()) +if "SUPERV" in liste_modules:with_container_superv=1 + + +# ----------------------------------------------------------------------------- +# +# Définition des classes d'objets pour le lancement des Server CORBA +# + +class Server: + CMD=[] + if with_xterm: + ARGS=['xterm', '-iconic', '-sb', '-sl', '500', '-e'] + else: + ARGS=[] + + def run(self): + args = self.ARGS+self.CMD + #print "args = ", args + pid = os.spawnvp(os.P_NOWAIT, args[0], args) + process_id[pid]=self.CMD + +class CatalogServer(Server): + SCMD1=['SALOME_ModuleCatalog_Server','-common'] + SCMD2=['-personal','${HOME}/Salome/resources/CatalogModulePersonnel.xml'] + + def setpath(self,liste_modules): + cata_path=[] + for module in liste_modules: + module_root_dir=modules_root_dir[module] + module_cata=module+"Catalog.xml" + print " ", module_cata + cata_path.extend(glob.glob(os.path.join(module_root_dir,"share","salome","resources",module_cata))) + self.CMD=self.SCMD1 + [string.join(cata_path,':')] + self.SCMD2 + +class SalomeDSServer(Server): + CMD=['SALOMEDS_Server'] + +class RegistryServer(Server): + CMD=['SALOME_Registry_Server', '--salome_session','theSession'] + +class ContainerCPPServer(Server): + CMD=['SALOME_Container','FactoryServer','-ORBInitRef','NameService=corbaname::localhost'] + +class ContainerPYServer(Server): + CMD=['SALOME_ContainerPy.py','FactoryServerPy','-ORBInitRef','NameService=corbaname::localhost'] + +class ContainerSUPERVServer(Server): + CMD=['SALOME_Container','SuperVisionContainer','-ORBInitRef','NameService=corbaname::localhost'] + +class LoggerServer(Server): + CMD=['SALOME_Logger_Server', 'logger.log'] + +class SessionLoader(Server): + CMD=['SALOME_Session_Loader'] + if with_container_cpp: + CMD=CMD+['CPP'] + if with_container_python: + CMD=CMD+['PY'] + if with_container_superv: + CMD=CMD+['SUPERV'] + if with_gui: + CMD=CMD+['GUI'] + +class SessionServer(Server): + CMD=['SALOME_Session_Server'] + +class NotifyServer(Server): + CMD=['notifd','-c','${KERNEL_ROOT_DIR}/share/salome/resources/channel.cfg -DFactoryIORFileName=/tmp/${LOGNAME}_rdifact.ior -DChannelIORFileName=/tmp/${LOGNAME}_rdichan.ior'] + +# ----------------------------------------------------------------------------- +# +# Fonction de test +# + +def test(clt): + """ + Test function that creates an instance of HXX2SALOME_GENERIC_CLASS_NAME component + usage : hello=test(clt) + """ + # create an LifeCycleCORBA instance + import LifeCycleCORBA + lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb) + import HXX2SALOME_GENERIC_CLASS_NAME_ORB + hello = lcc.FindOrLoadComponent("FactoryServer", "HXX2SALOME_GENERIC_CLASS_NAME") + return hello + +# ----------------------------------------------------------------------------- +# +# Fonctions helper pour ajouter des variables d'environnement +# + +def add_path(directory): + os.environ["PATH"]=directory + ":" + os.environ["PATH"] + +def add_ld_library_path(directory): + os.environ["LD_LIBRARY_PATH"]=directory + ":" + os.environ["LD_LIBRARY_PATH"] + +def add_python_path(directory): + os.environ["PYTHONPATH"]=directory + ":" + os.environ["PYTHONPATH"] + sys.path[:0]=[directory] + +# ----------------------------------------------------------------------------- +# +# initialisation des variables d'environnement +# + +python_version="python%d.%d" % sys.version_info[0:2] + +# +# Ajout du chemin d'acces aux executables de KERNEL dans le PATH +# + +add_path(os.path.join(kernel_root_dir,"bin","salome")) +#print "PATH=",os.environ["PATH"] + +# +# Ajout des modules dans le LD_LIBRARY_PATH +# +for module in liste_modules: + module_root_dir=modules_root_dir[module] + add_ld_library_path(os.path.join(module_root_dir,"lib","salome")) +#print "LD_LIBRARY_PATH=",os.environ["LD_LIBRARY_PATH"] + +# +# Ajout des modules dans le PYTHONPATH (KERNEL prioritaire, donc en dernier) +# + +liste_modules_reverse=liste_modules[:] +liste_modules_reverse.reverse() +#print liste_modules +#print liste_modules_reverse +for module in liste_modules_reverse: + module_root_dir=modules_root_dir[module] + add_python_path(os.path.join(module_root_dir,"bin","salome")) + add_python_path(os.path.join(module_root_dir,"lib",python_version,"site-packages","salome")) + add_python_path(os.path.join(module_root_dir,"lib","salome")) + add_python_path(os.path.join(module_root_dir,"lib",python_version,"site-packages","salome","shared_modules")) + +#print "PYTHONPATH=",sys.path + +import orbmodule + +# +# ----------------------------------------------------------------------------- +# + +def startGUI(): + import SALOME + session=clt.waitNS("/Kernel/Session",SALOME.Session) + + # + # Activation du GUI de Session Server + # + + session.GetInterface() + +# +# ----------------------------------------------------------------------------- +# + +def startSalome(): + + # + # Lancement Session Loader + # + SessionLoader().run() + + # + # Initialisation ORB et Naming Service + # + clt=orbmodule.client() + + # (non obligatoire) Lancement Logger Server et attente de sa + # disponibilite dans le naming service + # + if with_logger: + LoggerServer().run() + clt.waitLogger("Logger") + + # + # Lancement Registry Server + # + RegistryServer().run() + + # + # Attente de la disponibilité du Registry dans le Naming Service + # + clt.waitNS("/Registry") + + # + # Lancement Catalog Server + # + cataServer=CatalogServer() + cataServer.setpath(liste_modules) + cataServer.run() + + # + # Attente de la disponibilité du Catalog Server dans le Naming Service + # + import SALOME_ModuleCatalog + clt.waitNS("/Kernel/ModulCatalog",SALOME_ModuleCatalog.ModuleCatalog) + + # + # Lancement SalomeDS Server + # + os.environ["CSF_PluginDefaults"]=os.path.join(kernel_root_dir,"share","salome","resources") + os.environ["CSF_SALOMEDS_ResourcesDefaults"]=os.path.join(kernel_root_dir,"share","salome","resources") + SalomeDSServer().run() + + if "GEOM" in liste_modules: + print "GEOM OCAF Resources" + os.environ["CSF_GEOMDS_ResourcesDefaults"]=os.path.join(modules_root_dir["GEOM"],"share","salome","resources") + + + # + # Attente de la disponibilité du SalomeDS dans le Naming Service + # + clt.waitNS("/myStudyManager") + + # + # Lancement Session Server + # + SessionServer().run() + + # + # Attente de la disponibilité du Session Server dans le Naming Service + # + import SALOME + session=clt.waitNS("/Kernel/Session",SALOME.Session) + + # + # Lancement containers + # + theComputer = os.getenv("HOSTNAME") + theComputer = theComputer.split('.')[0] + + # + # Lancement Container C++ local + # + if with_container_cpp: + ContainerCPPServer().run() + # + # Attente de la disponibilité du Container C++ local + # dans le Naming Service + # + clt.waitNS("/Containers/" + theComputer + "/FactoryServer") + # + # Lancement Container Python local + # + if with_container_python: + ContainerPYServer().run() + # + # Attente de la disponibilité du Container Python local + # dans le Naming Service + # + clt.waitNS("/Containers/" + theComputer + "/FactoryServerPy") + + if with_container_superv: + # + # Lancement Container Supervision local + # + ContainerSUPERVServer().run() + # + # Attente de la disponibilité du Container Supervision local + # dans le Naming Service + # + clt.waitNS("/Containers/" + theComputer + "/SuperVisionContainer") + # + # Activation du GUI de Session Server + # + #session.GetInterface() + + end_time = os.times() + print + print "Start SALOME, elpased time : %5.1f seconds"% (end_time[4] - init_time[4]) + + return clt + +# +# ----------------------------------------------------------------------------- +# + +if __name__ == "__main__": + clt=None + try: + clt = startSalome() + except: + print + print + print "--- erreur au lancement Salome ---" + + #print process_id + + + filedict='/tmp/'+os.getenv('USER')+'_SALOME_pidict' + #filedict='/tmp/'+os.getlogin()+'_SALOME_pidict' + + fpid=open(filedict, 'w') + pickle.dump(process_id,fpid) + fpid.close() + + print """ + +Sauvegarde du dictionnaire des process dans , %s +Pour tuer les process SALOME, executer : python killSalome.py depuis +une console, ou bien killSalome() depuis le present interpreteur, +s'il n'est pas fermé. + +runSalome, avec l'option --killall, commence par tuer les process restants +d'une execution précédente. + +Pour lancer uniquement le GUI, executer startGUI() depuis le present interpreteur, +s'il n'est pas fermé. + +""" % filedict + + # + # Impression arborescence Naming Service + # + + if clt != None: + print + print " --- registered objects tree in Naming Service ---" + clt.showNS() + session=clt.waitNS("/Kernel/Session") + catalog=clt.waitNS("/Kernel/ModulCatalog") + import socket + container = clt.waitNS("/Containers/" + socket.gethostname().split('.')[0] + "/FactoryServerPy") + + if os.path.isfile("~/.salome/pystartup"): + f=open(os.path.expanduser("~/.salome/pystartup"),'w') + PYTHONSTARTUP=f.read() + f.close() + else: + PYTHONSTARTUP=""" +# Add auto-completion and a stored history file of commands to your Python +# interactive interpreter. Requires Python 2.0+, readline. Autocomplete is +# bound to the TAB key by default (you can change it - see readline docs). +# +# Store the history in ~/.salome/pyhistory, +# +import atexit +import os +import readline +import rlcompleter +readline.parse_and_bind('tab: complete') + +historyPath = os.path.expanduser("~/.salome/pyhistory") + +def save_history(historyPath=historyPath): + import readline + readline.write_history_file(historyPath) + +if os.path.exists(historyPath): + readline.read_history_file(historyPath) + +atexit.register(save_history) +del os, atexit, readline, rlcompleter, save_history, historyPath +""" + f=open(os.path.expanduser("~/.salome/pystartup"),'w') + f.write(PYTHONSTARTUP) + f.close() + + exec PYTHONSTARTUP in {} + diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/build_configure b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/build_configure new file mode 100755 index 000000000..35a2dc6ee --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/build_configure @@ -0,0 +1,208 @@ +#!/bin/bash + +# +# Tool for updating list of .in file for the SALOME project +# and regenerating configure script +# +# Author : Marc Tajchman - CEA +# Date : 10/10/2002 +# $Header $ +# + +ORIG_DIR=`pwd` +CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` + +######################################################################## +# Test if the KERNEL_ROOT_DIR is set correctly + +if test ! -d "${KERNEL_ROOT_DIR}"; then + echo "failed : KERNEL_ROOT_DIR variable is not correct !" + exit +fi + +######################################################################## +# find_in - utility function +# +# usage : +# find_in directory filename +# +# Finds files following the *.in pattern, recursively in the +# directory (first argument). +# Results are appended into the file (second argument) +# +# Difference from the standard unix find is that files are tested +# before directories +# + +find_in() +{ + local i + local f=$2 + +# if the first argument is not a directory, returns + + if [ ! -d "$1" ] ; then + return + fi + +# dont look in the CVS directories + + case $1 in + */CVS) return ;; + *) ;; + esac + +# for each regular file contained in the directory +# test if it's a .in file + + for i in "$1"/* + do + if [ -f "$i" ] ; then + case $i in + *.in) echo $i" \\" >> $f;; + *) ;; + esac + fi + done + +# for each subdirectory of the first argument, proceeds recursively + + for i in "$1"/* + do + if [ -d "$i" ] ; then + find_in "$i" "$f" + fi + done +} + + +####################################################################### +# Generate list of .in files (Makefile.in, config.h.in, etc) +# appending it in file configure.in + +cd ${CONF_DIR} +ABS_CONF_DIR=`pwd` + +# +# Common part of the configure.in file +# +chmod u+w configure.in.base +if ! \cp -f configure.in.base configure.in_tmp1 +then + echo + echo "error : can't create files in" ${CONF_DIR} + echo "aborting ..." + chmod u-w configure.in.base + exit +fi +chmod u-w configure.in.base + +if [ -e "${CONF_DIR}/salome_adm" ] ; then + \rm -f ${CONF_DIR}/salome_adm +fi + +# make a link allowing AC_OUTPUT to find the salome_adm/.../*.in files +echo "" >> configure.in_tmp1 +echo 'ln -fs ${KERNEL_ROOT_DIR}/salome_adm ${ROOT_SRCDIR}' >> configure.in_tmp1 + +echo "" >> configure.in_tmp1 +echo "AC_OUTPUT([ \\" >> configure.in_tmp1 + +# +# List of .in files in the adm/unix directory +# These files MUST be on top of AC_OUTPUT list so we +# put them "manually" +# + +echo "./salome_adm/unix/SALOMEconfig.h \\" >> configure.in_tmp1 +echo "./salome_adm/unix/F77config.h \\" >> configure.in_tmp1 +echo "./salome_adm/unix/sstream \\" >> configure.in_tmp1 +echo "./salome_adm/unix/depend \\" >> configure.in_tmp1 +echo "./adm_local/unix/make_omniorb \\" >> configure.in_tmp1 +echo "./salome_adm/unix/envScript \\" >> configure.in_tmp1 +echo "./adm_local/unix/make_commence \\" >> configure.in_tmp1 +echo "./salome_adm/unix/make_conclude \\" >> configure.in_tmp1 +echo "./salome_adm/unix/make_module \\" >> configure.in_tmp1 + +\rm -f configure.in_tmp2 +touch configure.in_tmp2 +find_in . configure.in_tmp2 + +sed -e '/^.\/salome_adm/d' \ + -e '/configure.in/d' \ + -e '/^.\/adm_local/d' \ + -e 's/.in / /' \ + configure.in_tmp2 >> configure.in_tmp1 + +echo "])" >> configure.in_tmp1 + +# delete the link created for AC_OUTPUT +echo "" >> configure.in_tmp1 +\mv configure.in_tmp1 configure.in_new +\rm -f configure.in_tmp2 + + +######################################################################## +# Create new (or replace old) configure.in file +# Print a message if the file is write protected +# + +echo +if test ! -f configure.in +then + echo -n "Creating new file 'configure.in' ... " + if \mv configure.in_new configure.in >& /dev/null + then + echo "done" + else + echo "error, check your file permissions" + fi +else + echo -n "Updating 'configure.in' file ... " + if ! \cp configure.in configure.in_old >& /dev/null + then + echo + echo + echo "Can't backup previous configure.in" + echo -n "Continue (you will not be able to revert) - (Y/N) ? " + read R + case "x$R" in + xn*) exit;; + xN*) exit;; + esac + echo + echo -n " " + fi + if \cp configure.in_new configure.in >& /dev/null + then + \rm -f configure.in_new + echo "done" + else + echo + echo "error, can't update previous configure.in" + fi +fi + +######################################################################## +# Use autoconf to rebuild the configure script +# + +if test -f configure +then + echo -n "Updating 'configure' script ... " +else + echo -n "Creating 'configure' script ... " +fi + +aclocal -I adm_local/unix/config_files -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \ + -I ${GUI_ROOT_DIR}/adm_local/unix/config_files +if autoconf +then + echo "done" +else + echo "failed (check file permissions and/or user quotas ...)" +fi + +cd ${ORIG_DIR} + +echo diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/configure.in.base b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/configure.in.base new file mode 100644 index 000000000..d87d74ffc --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/configure.in.base @@ -0,0 +1,313 @@ +# +# PLEASE DO NOT MODIFY configure.in FILE +# +# ALL CHANGES WILL BE DISCARDED BY THE NEXT +# build_configure COMMAND +# +# CHANGES MUST BE MADE IN configure.in.base FILE +# +# +# Author : Marc Tajchman (CEA) +# Date : 28/06/2001 +# Modified by : Patrick GOLDBRONN (CEA) +# Modified by : Marc Tajchman (CEA) +# +# Created from configure.in.base +# + +AC_INIT(src) +AC_CONFIG_AUX_DIR(${KERNEL_ROOT_DIR}/salome_adm/unix/config_files) +AC_CANONICAL_HOST + +PACKAGE=salome +AC_SUBST(PACKAGE) + +VERSION=1.2.1 +AC_SUBST(VERSION) + +dnl +dnl Initialize source and build root directories +dnl + +ROOT_BUILDDIR=`pwd` +ROOT_SRCDIR=`echo $0 | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` +cd $ROOT_SRCDIR +ROOT_SRCDIR=`pwd` +cd $ROOT_BUILDDIR + +AC_SUBST(ROOT_SRCDIR) +AC_SUBST(ROOT_BUILDDIR) + +echo +echo Source root directory : $ROOT_SRCDIR +echo Build root directory : $ROOT_BUILDDIR +echo +echo + +if test -z "$AR"; then + AC_CHECK_PROGS(AR,ar xar,:,$PATH) +fi +AC_SUBST(AR) + +dnl Export the AR macro so that it will be placed in the libtool file +dnl correctly. +export AR + +echo +echo --------------------------------------------- +echo testing make +echo --------------------------------------------- +echo + +AC_PROG_MAKE_SET +AC_PROG_INSTALL +dnl +dnl libtool macro check for CC, LD, NM, LN_S, RANLIB, STRIP + for shared libraries + +AC_ENABLE_DEBUG(yes) +AC_DISABLE_PRODUCTION + +echo --------------------------------------------- +echo testing libtool +echo --------------------------------------------- + +dnl first, we set static to no! +dnl if we want it, use --enable-static +AC_ENABLE_STATIC(no) + +AC_LIBTOOL_DLOPEN +AC_PROG_LIBTOOL + +dnl Fix up the INSTALL macro if it s a relative path. We want the +dnl full-path to the binary instead. +case "$INSTALL" in + *install-sh*) + INSTALL='\${KERNEL_ROOT_DIR}'/salome_adm/unix/config_files/install-sh + ;; +esac + +echo +echo --------------------------------------------- +echo testing C/C++ +echo --------------------------------------------- +echo + +cc_ok=no +dnl inutil car libtool +dnl AC_PROG_CC +AC_PROG_CXX +AC_CXX_WARNINGS +AC_CXX_TEMPLATE_OPTIONS +AC_CXX_HAVE_SSTREAM +AC_DEPEND_FLAG +# AC_CC_WARNINGS([ansi]) +cc_ok=yes + +dnl Library libdl : +AC_CHECK_LIB(dl,dlopen) + +dnl Library librt : for alpha/osf +AC_CHECK_LIB(rt,nanosleep) + +dnl add library libm : +AC_CHECK_LIB(m,ceil) + +AC_CXX_USE_STD_IOSTREAM +AC_CXX_HAVE_SSTREAM + +dnl +dnl --------------------------------------------- +dnl testing linker +dnl --------------------------------------------- +dnl + +AC_LINKER_OPTIONS + +echo +echo --------------------------------------------- +echo testing threads +echo --------------------------------------------- +echo + +ENABLE_PTHREADS + +echo +echo --------------------------------------------- +echo BOOST Library +echo --------------------------------------------- +echo + +CHECK_BOOST + +echo +echo --------------------------------------------- +echo testing python +echo --------------------------------------------- +echo + +CHECK_PYTHON + +echo +echo --------------------------------------------- +echo testing QT +echo --------------------------------------------- +echo + +CHECK_QT + +echo +echo --------------------------------------------- +echo testing msg2qm +echo --------------------------------------------- +echo + +CHECK_MSG2QM + +echo +echo --------------------------------------------- +echo Testing OpenCascade +echo --------------------------------------------- +echo + +CHECK_CAS + +echo +echo --------------------------------------------- +echo testing omniORB +echo --------------------------------------------- +echo + +CHECK_OMNIORB + +echo +echo --------------------------------------------- +echo default ORB : omniORB +echo --------------------------------------------- +echo + +DEFAULT_ORB=omniORB +CHECK_CORBA + +AC_SUBST_FILE(CORBA) +corba=make_$ORB +CORBA=adm_local/unix/$corba + +echo +echo --------------------------------------------- +echo Testing Kernel +echo --------------------------------------------- +echo + +CHECK_KERNEL + +echo +echo --------------------------------------------- +echo Testing GUI +echo --------------------------------------------- +echo + +CHECK_SALOME_GUI + +echo +echo --------------------------------------------- +echo testing HDF5 +echo --------------------------------------------- +echo + +CHECK_HDF5 + +echo +echo --------------------------------------------- +echo testing MED AND MED2 +echo --------------------------------------------- +echo + +CHECK_MED +CHECK_MED2 + +echo +echo --------------------------------------------- +echo testing Component Evironment +echo --------------------------------------------- +echo + +CHECK_COMPONENT_ENV + +echo +echo --------------------------------------------- +echo Summary +echo --------------------------------------------- +echo + +echo Configure +variables="cc_ok threads_ok boost_ok python_ok omniORB_ok qt_ok msg2qm_ok Kernel_ok SalomeGUI_ok Med_ok med2_ok hdf5_ok Comp_Env_ok" + +for var in $variables +do + printf " %10s : " `echo \$var | sed -e "s,_ok,,"` + eval echo \$$var +done + +echo +echo "Default ORB : $DEFAULT_ORB" +echo + +dnl generals files which could be included in every makefile + +AC_SUBST_FILE(COMMENCE) COMMENCE=adm_local/unix/make_commence +AC_SUBST_FILE(CONCLUDE) CONCLUDE=salome_adm/unix/make_conclude +AC_SUBST_FILE(MODULE) MODULE=salome_adm/unix/make_module + +dnl les dependences +AC_SUBST_FILE(DEPEND) DEPEND=salome_adm/unix/depend + +dnl We don t need to say when we re entering directories if we re using +dnl GNU make becuase make does it for us. +if test "X$GMAKE" = "Xyes"; then + AC_SUBST(SETX) SETX=":" +else + AC_SUBST(SETX) SETX="set -x" +fi + +# make other build directories +for rep in salome_adm adm_local doc bin/salome include/salome lib/salome share/salome/resources share/salome/doc idl +do + $INSTALL -d $rep +done + +echo +echo --------------------------------------------- +echo copying resource files, shell scripts, and +echo xml files +echo --------------------------------------------- +echo + +dnl copy shells and utilities contained in the bin directory +dnl excluding .in files (treated in AC-OUTPUT below) and CVS +dnl directory + +cd bin +for i in $ROOT_SRCDIR/bin/* +do + local_bin=`echo $i | sed -e "s,$ROOT_SRCDIR,.,"` + case "$local_bin" in + *.in | *~) ;; + ./bin/CVS) ;; + *) ln -fs $i; echo $local_bin ;; + esac +done +cd $ROOT_BUILDDIR + +AC_SUBST_FILE(ENVSCRIPT) ENVSCRIPT=salome_adm/unix/envScript + +echo +echo --------------------------------------------- +echo generating Makefiles and configure files +echo --------------------------------------------- +echo + +AC_OUTPUT_COMMANDS([ \ + chmod +x ./bin/* \ +]) + +## do not delete this line diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/dev_guide.txt b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/dev_guide.txt new file mode 100644 index 000000000..64d2d0368 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/dev_guide.txt @@ -0,0 +1,103 @@ +Code Wrapping into SALOME with hxx2salome +========================================= + + +1 Context +--------- + +Assuming you want to integrate the component "COMP" into SALOME, you may use the hxx2salome command. + +If you are able to read this document, it is assumed that you succeeded running hxx2salome command. +The command you typed looks like: + + hxx2salome -g -s sh ${COMP_CPP_ROOT_DIR} COMP.hxx libCOMPCXX.so ${COMP_ROOT_DIR} + + where: + ${COMP_CPP_ROOT_DIR} : is the directory (absolute path) where the component to be integrated lies + something as /export/home/john/COMP/COMP_CPP_INSTALL + + COMP.hxx : is the header file describing the methods to be wrapped (must lie in one + unique occurence in ${COMP_CPP_ROOT_DIR} tree) + + libCOMPCXX.so : is the library file containing the implemented methods of the component + (must lie in one unique occurence in ${COMP_CPP_ROOT_DIR} tree) + + ${COMP_BUILD_ROOT_DIR} : is the directory (absolute path) where the component building tree has to + be installed something as /usr/local/salome_3.x.x/COMPONENTS + + -g : is an hxx2salome option asking for the GUI part of the component + + -s sh : is an hxx2salome option asking to use a sh-style environment file + +The present file is ${COMP_ROOT_DIR}/COMP/COMP_SRC/doc/dev_guide.txt + + +2 Implementing your wrapper +--------------------------- + +In the ${COMP_BUILD_ROOT_DIR}/COMP/COMP_SRC/src/COMP directory you will find a COMP_i.hxx file describing +all wrapped methods from your component. + +2.1 Implementation for testing component from console + +In the same ${COMP_BUILD_ROOT_DIR}/COMP/COMP_SRC/src/COMP directory you will find a COMP_test.py file. Edit it +to add (at bottom part) some calls to your component methods. They will look like: my_COMP.method(...). + +2.2 Implementation for testing component from SALOME GUI + +If you used option -g, you will find another directory named ${COMP_BUILD_ROOT_DIR}/COMP/COMP_SRC/src/COMPGUI. +You have to edit the following files: + +COMPGUI.h : Mainly changing the class fields that are only preferences-oriented in the template +COMPGUI.cxx : - Constructor to fit your needs, + - initialize to define your menus, toolbars, dialogs and preferences as shown in template + - OnMyNewItem, OnCallAction and equivalent own call-back routine names (template includes + examples in OnCallAction to retrieve user preferences values). Here are included the + calls to component library. They will look like: COMPgen->method( arg1, arg2, ... ); + - createPreferences to define your own user preferences data entries + - preferencesChanged to get prepared for automatic SALOME call-back +COMP_msg_en.po: Resources file with all English text strings used in the source code COMPGUI.cxx +COMP_msg_xx.po: Resources file with all strings translated in language xx (for instance fr) + + +3 Building your component +------------------------- + +When your implementation is ready, the SALOME client side of the component is built the regular way: + + check definition of environment variables (COMP_SRC_DIR, COMP_BUILD_DIR, COMP_ROOT_DIR) in + file ${COMP_BUILD_ROOT_DIR}/COMP/COMP_SRC/env_COMP.sh and source it + cd ${COMP_SRC_DIR} + ./build_configure + mkdir -p ${COMP_BUILD_DIR} + cd ${COMP_BUILD_DIR} + ${COMP_SRC_DIR}/configure --prefix=${COMP_ROOT_DIR} + make + make install + +4 Using your component +---------------------- + +To be done once: + edit your configuration file ~/.SalomeApprc.3.x.x: + Somewhere between and add: +
+ + +
+
+ +
+ In launch section add reference to COMP +
+ +
+ +To be done at login: + source the Salome environment + source the component environment file (${COMP_BUILD_ROOT_DIR}/COMP/COMP_SRC/env_COMP.sh) + +To be done at execution: + run Salome (runSalome command) + kill any still runing process if necessary (killSalome.py command) + diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/idl/HXX2SALOME_GENERIC_CLASS_NAME_Gen.idl b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/idl/HXX2SALOME_GENERIC_CLASS_NAME_Gen.idl new file mode 100644 index 000000000..3084138be --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/idl/HXX2SALOME_GENERIC_CLASS_NAME_Gen.idl @@ -0,0 +1,20 @@ +#ifndef __HXX2SALOME_GENERIC_CLASS_NAME_GEN_hxx2salome__ +#define __HXX2SALOME_GENERIC_CLASS_NAME_GEN_hxx2salome__ + +#include "SALOME_Component.idl" +#include "SALOME_Exception.idl" +#include "MED.idl" +// this include is not protected and already present in MED.idl #include "SALOME_Comm.idl" + +module HXX2SALOME_GENERIC_CLASS_NAME_ORB +{ + /*! \brief Interface of the %HXX2SALOME_GENERIC_CLASS_NAME component + */ + interface HXX2SALOME_GENERIC_CLASS_NAME_Gen : Engines::Component, SALOME::MultiCommClass + { +HXX2SALOME_IDL_CODE + }; +}; + +#endif + diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/ExecHXX2SALOME_GENERIC_CLASS_NAME.png b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/ExecHXX2SALOME_GENERIC_CLASS_NAME.png new file mode 100644 index 0000000000000000000000000000000000000000..16a20c116e8243a6b49ed862613d2cc49bdf4caa GIT binary patch literal 831 zcmV-F1Hk-=P)A+3!%gdoE?w?yY*XMamxaAW~()k6;QGVVf3ZPpQcy+38CrH3{Qk zoaxN-vWJ+OcH(Y#5qvHK|CitMf1CdUU;7AQ8zF4-#i736F~#EMso~pq*Ek7JMLa$}POH_T(b)M|f)>8t;^3f3 zKA)#ntMKyW+7Z-s>l6xWsZ53jrMAEC5{41RXe`Snj$`6DMr+Vop|xgsc$hE@Sz20V zb@eG)%b|Y+_m{*NND_%L1}POFH@MUObOdhQq^%&CMdWZvC2q+x@_Pg_JQ$DGG%bJbwIyVzG#2o#E=$@5yGf z#Bm5%IplY1BB@I((}Bdlpj1;;nAaqNZEDBWHP2)F0;K|LMcrchIBe@ z&Ye4p5H>e&{)pCc=qTd1Z_6|q4IIZIpUy{Fg7-dG2KQ=nb2l+s9A+3!%gdoE?w?yY*XMamxaAW~()k6;QGVVf3ZPpQcy+38CrH3{Qk zoaxN-vWJ+OcH(Y#5qvHK|CitMf1CdUU;7AQ8zF4-#i736F~#EMso~pq*Ek7JMLa$}POH_T(b)M|f)>8t;^3f3 zKA)#ntMKyW+7Z-s>l6xWsZ53jrMAEC5{41RXe`Snj$`6DMr+Vop|xgsc$hE@Sz20V zb@eG)%b|Y+_m{*NND_%L1}POFH@MUObOdhQq^%&CMdWZvC2q+x@_Pg_JQ$DGG%bJbwIyVzG#2o#E=$@5yGf z#Bm5%IplY1BB@I((}Bdlpj1;;nAaqNZEDBWHP2)F0;K|LMcrchIBe@ z&Ye4p5H>e&{)pCc=qTd1Z_6|q4IIZIpUy{Fg7-dG2KQ=nb2l+s9 - + statusdict /prefeed known { + statusdict exch /prefeed exch put + } { + pop + } ifelse +} bind def + +/deffont { + findfont exch scalefont def +} bind def + +/reencode_font { + findfont reencode 2 copy definefont pop def +} bind def + +% Function c-show (str => -) +% centers text only according to x axis. +/c-show { + dup stringwidth pop + 2 div neg 0 rmoveto + show +} bind def + +% Function l-show (str => -) +% prints texts so that it ends at currentpoint +/l-show { + dup stringwidth pop neg + 0 + rmoveto show +} bind def + +% center-fit show (str w => -) +% show centered, and scale currentfont so that the width is less than w +/cfshow { + exch dup stringwidth pop + % If the title is too big, try to make it smaller + 3 2 roll 2 copy + gt + { % if, i.e. too big + exch div + currentfont exch scalefont setfont + } { % ifelse + pop pop + } + ifelse + c-show % center title +} bind def + +% Return the y size of the current font +% - => fontsize +/currentfontsize { + currentfont /FontType get 0 eq { + currentfont /FontMatrix get 3 get + }{ + currentfont /FontMatrix get 3 get 1000 mul + } ifelse +} bind def + +% reencode the font +% -> +/reencode { %def + dup length 5 add dict begin + { %forall + 1 index /FID ne + { def }{ pop pop } ifelse + } forall + /Encoding exch def + + % Use the font's bounding box to determine the ascent, descent, + % and overall height; don't forget that these values have to be + % transformed using the font's matrix. + % We use `load' because sometimes BBox is executable, sometimes not. + % Since we need 4 numbers an not an array avoid BBox from being executed + /FontBBox load aload pop + FontMatrix transform /Ascent exch def pop + FontMatrix transform /Descent exch def pop + /FontHeight Ascent Descent sub def + + % Define these in case they're not in the FontInfo (also, here + % they're easier to get to. + /UnderlinePosition 1 def + /UnderlineThickness 1 def + + % Get the underline position and thickness if they're defined. + currentdict /FontInfo known { + FontInfo + + dup /UnderlinePosition known { + dup /UnderlinePosition get + 0 exch FontMatrix transform exch pop + /UnderlinePosition exch def + } if + + dup /UnderlineThickness known { + /UnderlineThickness get + 0 exch FontMatrix transform exch pop + /UnderlineThickness exch def + } if + + } if + currentdict + end +} bind def + +% composite fonts for ASCII-EUC mixed string +% Version 1.2 1/31/1990 +% Orignal Ken'ichi HANDA (handa@etl.go.jp) +% Modified Norio Katayama (katayama@rd.nacsis.ac.jp),1998 +% Extend & Fix Koji Nakamaru (maru@on.cs.keio.ac.jp), 1999 +% Anyone can freely copy, modify, distribute this program. + +/copyfont { % font-dic extra-entry-count copyfont font-dic + 1 index maxlength add dict begin + { 1 index /FID ne 2 index /UniqueID ne and + {def} {pop pop} ifelse + } forall + currentdict + end +} bind def + +/compositefont { % ASCIIFontName EUCFontName RomanScale RomanOffset Rot(T/F) compositefont font + /RomanRotation exch def + /RomanOffset exch def + /RomanScale exch def + userdict /fixeucfont_dict known not { + userdict begin + /fixeucfont_dict 2 dict begin + /UpperByteEncoding [ + 16#00 1 16#20 { pop 0 } for + 16#21 1 16#28 { 16#20 sub } for + 16#29 1 16#2F { pop 0 } for + 16#30 1 16#74 { 16#27 sub } for + 16#75 1 16#FF { pop 0 } for + ] def + /LowerByteEncoding [ + 16#00 1 16#A0 { pop /.notdef } for + 16#A1 1 16#FE { 16#80 sub 16 2 string cvrs + (cXX) dup 1 4 -1 roll + putinterval cvn } for + /.notdef + ] def + currentdict + end def + end + } if + findfont dup /FontType get 0 eq { + 14 dict begin + % + % 7+8 bit EUC font + % + 12 dict begin + /EUCFont exch def + /FontInfo (7+8 bit EUC font) readonly def + /PaintType 0 def + /FontType 0 def + /FontMatrix matrix def + % /FontName + /Encoding fixeucfont_dict /UpperByteEncoding get def + /FMapType 2 def + EUCFont /WMode known + { EUCFont /WMode get /WMode exch def } + { /WMode 0 def } ifelse + /FDepVector [ + EUCFont /FDepVector get 0 get + [ 16#21 1 16#28 {} for 16#30 1 16#74 {} for ] + { + 13 dict begin + /EUCFont EUCFont def + /UpperByte exch 16#80 add def + % /FontName + /FontInfo (EUC lower byte font) readonly def + /PaintType 0 def + /FontType 3 def + /FontMatrix matrix def + /FontBBox {0 0 0 0} def + /Encoding + fixeucfont_dict /LowerByteEncoding get def + % /UniqueID + % /WMode + /BuildChar { + gsave + exch dup /EUCFont get setfont + /UpperByte get + 2 string + dup 0 4 -1 roll put + dup 1 4 -1 roll put + dup stringwidth setcharwidth + 0 0 moveto show + grestore + } bind def + currentdict + end + /lowerbytefont exch definefont + } forall + ] def + currentdict + end + /eucfont exch definefont + exch + findfont 1 copyfont dup begin + RomanRotation { + /FontMatrix FontMatrix + [ 0 RomanScale neg RomanScale 0 RomanOffset neg 0 ] + matrix concatmatrix def + }{ + /FontMatrix FontMatrix + [ RomanScale 0 0 RomanScale 0 RomanOffset ] matrix concatmatrix + def + /CDevProc + {pop pop pop pop 0 exch -1000 exch 2 div 880} def + } ifelse + end + /asciifont exch definefont + exch + /FDepVector [ 4 2 roll ] def + /FontType 0 def + /WMode 0 def + /FMapType 4 def + /FontMatrix matrix def + /Encoding [0 1] def + /FontBBox {0 0 0 0} def +% /FontHeight 1.0 def % XXXX + /FontHeight RomanScale 1.0 ge { RomanScale }{ 1.0 } ifelse def + /Descent -0.3 def % XXXX + currentdict + end + /tmpfont exch definefont + pop + /tmpfont findfont + }{ + pop findfont 0 copyfont + } ifelse +} def + +/slantfont { % FontName slant-degree slantfont font' + exch findfont 1 copyfont begin + [ 1 0 4 -1 roll 1 0 0 ] FontMatrix exch matrix concatmatrix + /FontMatrix exch def + currentdict + end +} def + +% Function print line number ( # -) +/# { + gsave + sx cw mul neg 2 div 0 rmoveto + f# setfont + c-show + grestore +} bind def + +% -------- Some routines to enlight plain b/w printings --------- + +% Underline +% width -- +/dounderline { + currentpoint + gsave + moveto + 0 currentfont /Descent get currentfontsize mul rmoveto + 0 rlineto + stroke + grestore +} bind def + +% Underline a string +% string -- +/dounderlinestring { + stringwidth pop + dounderline +} bind def + +/UL { + /ul exch store +} bind def + +% Draw a box of WIDTH wrt current font +% width -- +/dobox { + currentpoint + gsave + newpath + moveto + 0 currentfont /Descent get currentfontsize mul rmoveto + dup 0 rlineto + 0 currentfont /FontHeight get currentfontsize mul rlineto + neg 0 rlineto + closepath + stroke + grestore +} bind def + +/BX { + /bx exch store +} bind def + +% Box a string +% string -- +/doboxstring { + stringwidth pop + dobox +} bind def + +% +% ------------- Color routines --------------- +% +/FG /setrgbcolor load def + +% Draw the background +% width -- +/dobackground { + currentpoint + gsave + newpath + moveto + 0 currentfont /Descent get currentfontsize mul rmoveto + dup 0 rlineto + 0 currentfont /FontHeight get currentfontsize mul rlineto + neg 0 rlineto + closepath + bgcolor aload pop setrgbcolor + fill + grestore +} bind def + +% Draw bg for a string +% string -- +/dobackgroundstring { + stringwidth pop + dobackground +} bind def + + +/BG { + dup /bg exch store + { mark 4 1 roll ] /bgcolor exch store } if +} bind def + + +/Show { + bg { dup dobackgroundstring } if + ul { dup dounderlinestring } if + bx { dup doboxstring } if + show +} bind def + +% Function T(ab), jumps to the n-th tabulation in the current line +/T { + cw mul x0 add + bg { dup currentpoint pop sub dobackground } if + ul { dup currentpoint pop sub dounderline } if + bx { dup currentpoint pop sub dobox } if + y0 moveto +} bind def + +% Function n: move to the next line +/n { + /y0 y0 bfs sub store + x0 y0 moveto +} bind def + +% Function N: show and move to the next line +/N { + Show + /y0 y0 bfs sub store + x0 y0 moveto +} bind def + +/S { + Show +} bind def + +%%BeginResource: procset a2ps-a2ps-hdr 2.0 2 +%%Copyright: (c) 1988, 89, 90, 91, 92, 93 Miguel Santana +%%Copyright: (c) 1995, 96, 97, 98 Akim Demaille, Miguel Santana +% Function title: prints page header. +% are passed as argument +/title { + % 1. Draw the background + x v get y v get moveto + gsave + 0 th 2 div neg rmoveto + th setlinewidth + 0.95 setgray + pw 0 rlineto stroke + grestore + % 2. Border it + gsave + 0.7 setlinewidth + pw 0 rlineto + 0 th neg rlineto + pw neg 0 rlineto + closepath stroke + grestore + % stk: ct rt lt + x v get y v get th sub 1 add moveto +%%IncludeResource: font Helvetica + fHelvetica fnfs 0.8 mul scalefont setfont + % 3. The left title + gsave + dup stringwidth pop fnfs 0.8 mul add exch % leave space took on stack + fnfs 0.8 mul hm rmoveto + show % left title + grestore + exch + % stk: ct ltw rt + % 4. the right title + gsave + dup stringwidth pop fnfs 0.8 mul add exch % leave space took on stack + dup + pw exch stringwidth pop fnfs 0.8 mul add sub + hm + rmoveto + show % right title + grestore + % stk: ct ltw rtw + % 5. the center title + gsave + pw 3 1 roll + % stk: ct pw ltw rtw + 3 copy + % Move to the center of the left room + sub add 2 div hm rmoveto + % What is the available space in here? + add sub fnfs 0.8 mul sub fnfs 0.8 mul sub + % stk: ct space_left +%%IncludeResource: font Helvetica-Bold + fHelvetica-Bold fnfs scalefont setfont + cfshow + grestore +} bind def + +% Function border: prints virtual page border +/border { %def + gsave % print four sides + 0 setgray + x v get y v get moveto + 0.7 setlinewidth % of the square + pw 0 rlineto + 0 ph neg rlineto + pw neg 0 rlineto + closepath stroke + grestore +} bind def + +% Function water: prints a water mark in background +/water { %def + gsave + scx scy moveto rotate +%%IncludeResource: font Times-Bold + fTimes-Bold 100 scalefont setfont + .97 setgray + dup stringwidth pop 2 div neg -50 rmoveto + show + grestore +} bind def + +% Function rhead: prints the right header +/rhead { %def + lx ly moveto + fHelvetica fnfs 0.8 mul scalefont setfont + l-show +} bind def + +% Function footer (cf rf lf -> -) +/footer { + fHelvetica fnfs 0.8 mul scalefont setfont + dx dy moveto + show + + snx sny moveto + l-show + + fnx fny moveto + c-show +} bind def +%%EndResource +%%BeginResource: procset a2ps-black+white-Prolog 2.0 1 + +% Function T(ab), jumps to the n-th tabulation in the current line +/T { + cw mul x0 add y0 moveto +} bind def + +% Function n: move to the next line +/n { %def + /y0 y0 bfs sub store + x0 y0 moveto +} bind def + +% Function N: show and move to the next line +/N { + Show + /y0 y0 bfs sub store + x0 y0 moveto +} bind def + +/S { + Show +} bind def + +/p { + false UL + false BX + fCourier bfs scalefont setfont + Show +} bind def + +/sy { + false UL + false BX + fSymbol bfs scalefont setfont + Show +} bind def + +/k { + false UL + false BX + fCourier-Oblique bfs scalefont setfont + Show +} bind def + +/K { + false UL + false BX + fCourier-Bold bfs scalefont setfont + Show +} bind def + +/c { + false UL + false BX + fCourier-Oblique bfs scalefont setfont + Show +} bind def + +/C { + false UL + false BX + fCourier-BoldOblique bfs scalefont setfont + Show +} bind def + +/l { + false UL + false BX + fHelvetica bfs scalefont setfont + Show +} bind def + +/L { + false UL + false BX + fHelvetica-Bold bfs scalefont setfont + Show +} bind def + +/str{ + false UL + false BX + fTimes-Roman bfs scalefont setfont + Show +} bind def + +/e{ + false UL + true BX + fHelvetica-Bold bfs scalefont setfont + Show +} bind def + +%%EndResource +%%EndProlog +%%BeginSetup +%%IncludeResource: font Courier +%%IncludeResource: font Courier-Oblique +%%IncludeResource: font Courier-Bold +%%IncludeResource: font Times-Roman +%%IncludeResource: font Symbol +%%IncludeResource: font Courier-BoldOblique +%%BeginResource: encoding ISO-8859-1Encoding +/ISO-8859-1Encoding [ +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright +/parenleft /parenright /asterisk /plus /comma /minus /period /slash +/zero /one /two /three /four /five /six /seven +/eight /nine /colon /semicolon /less /equal /greater /question +/at /A /B /C /D /E /F /G +/H /I /J /K /L /M /N /O +/P /Q /R /S /T /U /V /W +/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +/quoteleft /a /b /c /d /e /f /g +/h /i /j /k /l /m /n /o +/p /q /r /s /t /u /v /w +/x /y /z /braceleft /bar /braceright /asciitilde /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/space /exclamdown /cent /sterling /currency /yen /brokenbar /section +/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron +/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /bullet +/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown +/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla +/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis +/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply +/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls +/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla +/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis +/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide +/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis +] def +%%EndResource +% Initialize page description variables. +/sh 612 def +/sw 792 def +/llx 24 def +/urx 768 def +/ury 588 def +/lly 24 def +/#copies 1 def +/th 20.000000 def +/fnfs 15 def +/bfs 8.000000 def +/cw 4.800000 def + +% Dictionary for ISO-8859-1 support +/iso1dict 8 dict begin + /fCourier ISO-8859-1Encoding /Courier reencode_font + /fCourier-Bold ISO-8859-1Encoding /Courier-Bold reencode_font + /fCourier-BoldOblique ISO-8859-1Encoding /Courier-BoldOblique reencode_font + /fCourier-Oblique ISO-8859-1Encoding /Courier-Oblique reencode_font + /fHelvetica ISO-8859-1Encoding /Helvetica reencode_font + /fHelvetica-Bold ISO-8859-1Encoding /Helvetica-Bold reencode_font + /fTimes-Bold ISO-8859-1Encoding /Times-Bold reencode_font + /fTimes-Roman ISO-8859-1Encoding /Times-Roman reencode_font +currentdict end def +/bgcolor [ 0 0 0 ] def +/bg false def +/ul false def +/bx false def +% The font for line numbering +/f# /Helvetica findfont bfs .6 mul scalefont def +/fSymbol /Symbol findfont def +/hm fnfs 0.25 mul def +/pw + cw 154.400000 mul +def +/ph + 517.600000 th add +def +/pmw 0 def +/pmh 0 def +/v 0 def +/x [ + 0 +] def +/y [ + pmh ph add 0 mul ph add +] def +/scx sw 2 div def +/scy sh 2 div def +/snx urx def +/sny lly 2 add def +/dx llx def +/dy sny def +/fnx scx def +/fny dy def +/lx snx def +/ly ury fnfs 0.8 mul sub def +/sx 0 def +/tab 8 def +/x0 0 def +/y0 0 def +%%EndSetup + +%%Page: (1) 1 +%%BeginPageSetup +/pagesave save def +sh 0 translate 90 rotate +%%EndPageSetup +iso1dict begin +gsave +llx lly 12 add translate +/v 0 store +/x0 x v get 3.360000 add sx cw mul add store +/y0 y v get bfs th add sub store +x0 y0 moveto +() p n +() N +() N +() N +() N +() N +( ) N +( ) N +( ) N +() N +() N +() N +( ) N +() N +() N +() N +() N +(PYHXX2SALOME_GENERIC_CLASS_NAME_en.xml) (Page 1/1) (Oct 14, 03 10:41) title +border +grestore +(Printed by Nicolas CROUZET - SFME/LGLS) rhead +(PYHXX2SALOME_GENERIC_CLASS_NAME_en.xml) (1/1) (Tuesday November 04, 2003) footer +end % of iso1dict +pagesave restore +showpage + +%%Trailer +end +%%EOF diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_en.xml b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_en.xml new file mode 100644 index 000000000..5fe8b84e5 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_en.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_fr.xml b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_fr.xml new file mode 100644 index 000000000..500c5d2fc --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_fr.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/SalomeApp.xml b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/SalomeApp.xml new file mode 100644 index 000000000..15fbf1c25 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/SalomeApp.xml @@ -0,0 +1,11 @@ + +
+ + + +
+
+ + +
+
diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/config b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/config new file mode 100644 index 000000000..e3471120d --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/config @@ -0,0 +1 @@ +language=en diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME/HXX2SALOME_GENERIC_CLASS_NAME_TEST.py b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME/HXX2SALOME_GENERIC_CLASS_NAME_TEST.py new file mode 100755 index 000000000..2fb01b79d --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME/HXX2SALOME_GENERIC_CLASS_NAME_TEST.py @@ -0,0 +1,7 @@ +mport salome +import HXX2SALOME_GENERIC_CLASS_NAME_ORB +myHXX2SALOME_GENERIC_CLASS_NAME = salome.lcc.FindOrLoadComponent("FactoryServer", "HXX2SALOME_GENERIC_CLASS_NAME") +# +# +print "Hello HXX2SALOME_GENERIC_CLASS_NAME" +# Test here some of HXX2SALOME_GENERIC_CLASS_NAME methods ... diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME/HXX2SALOME_GENERIC_CLASS_NAME_i.cxx b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME/HXX2SALOME_GENERIC_CLASS_NAME_i.cxx new file mode 100755 index 000000000..eeffeacfc --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME/HXX2SALOME_GENERIC_CLASS_NAME_i.cxx @@ -0,0 +1,55 @@ +#include "HXX2SALOME_GENERIC_CLASS_NAME_i.hxx" +// HXX2SALOME_CPP_INCLUDE +using namespace std; +#include "FIELDClient.hxx" +#include "MESHClient.hxx" +#include +#include "MEDMEM_Support_i.hxx" +#include "MEDMEM_Mesh_i.hxx" +#include "MEDMEM_FieldTemplate_i.hxx" +#include "SenderFactory.hxx" +#include "MultiCommException.hxx" +#include "ReceiverFactory.hxx" +#include "SALOME_Matrix_i.hxx" +#include "MatrixClient.hxx" + +//============================================================================= +/*! + * standard constructor + */ +//============================================================================= +HXX2SALOME_GENERIC_CLASS_NAME_i::HXX2SALOME_GENERIC_CLASS_NAME_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName) : + Engines_Component_i(orb, poa, contId, instanceName, interfaceName),cppCompo_(new HXX2SALOME_GENERIC_CLASS_NAME) +{ + MESSAGE("activate object"); + _thisObj = this ; + _id = _poa->activate_object(_thisObj); +} + +HXX2SALOME_GENERIC_CLASS_NAME_i::~HXX2SALOME_GENERIC_CLASS_NAME_i() +{ +} + +// HXX2SALOME_CXX_CODE + + +extern "C" +{ + PortableServer::ObjectId * HXX2SALOME_GENERIC_CLASS_NAMEEngine_factory( + CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName) + { + MESSAGE("PortableServer::ObjectId * HXX2SALOME_GENERIC_CLASS_NAMEEngine_factory()"); + SCRUTE(interfaceName); + HXX2SALOME_GENERIC_CLASS_NAME_i * myHXX2SALOME_GENERIC_CLASS_NAME + = new HXX2SALOME_GENERIC_CLASS_NAME_i(orb, poa, contId, instanceName, interfaceName); + return myHXX2SALOME_GENERIC_CLASS_NAME->getId() ; + } +} diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME/HXX2SALOME_GENERIC_CLASS_NAME_i.hxx b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME/HXX2SALOME_GENERIC_CLASS_NAME_i.hxx new file mode 100644 index 000000000..77bafb536 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME/HXX2SALOME_GENERIC_CLASS_NAME_i.hxx @@ -0,0 +1,42 @@ +#ifndef __HXX2SALOME_GENERIC_CLASS_NAME_HXX_hxx2salome__ +#define __HXX2SALOME_GENERIC_CLASS_NAME_HXX_hxx2salome__ + +#include +#include CORBA_SERVER_HEADER(HXX2SALOME_GENERIC_CLASS_NAME_Gen) +#include CORBA_CLIENT_HEADER(MED) +#include "SALOME_Component_i.hxx" +#include "SALOMEMultiComm.hxx" +class HXX2SALOME_GENERIC_CLASS_NAME; // forward declaration + +class HXX2SALOME_GENERIC_CLASS_NAME_i: + public POA_HXX2SALOME_GENERIC_CLASS_NAME_ORB::HXX2SALOME_GENERIC_CLASS_NAME_Gen, + public Engines_Component_i, + public SALOMEMultiComm +{ + +public: + HXX2SALOME_GENERIC_CLASS_NAME_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName); + virtual ~HXX2SALOME_GENERIC_CLASS_NAME_i(); + +// HXX2SALOME_HXX_CODE + +private: + std::auto_ptr cppCompo_; + +}; + + +extern "C" + PortableServer::ObjectId * HXX2SALOME_GENERIC_CLASS_NAMEEngine_factory( + CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName); + + +#endif diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.cxx b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.cxx new file mode 100644 index 000000000..ed549ea2b --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.cxx @@ -0,0 +1,221 @@ +#include "HXX2SALOME_GENERIC_CLASS_NAMEGUI.h" + +#include +#include +#include +#include +#include + +#include + +#define COMPONENT_NAME "HXX2SALOME_GENERIC_CLASS_NAME" + +using namespace std; + +// Constructor +HXX2SALOME_GENERIC_CLASS_NAMEGUI::HXX2SALOME_GENERIC_CLASS_NAMEGUI() : + SalomeApp_Module( COMPONENT_NAME ) // Module name +{ + // Initializations + default_bool = false; + default_int = 0; + default_spinInt = 0; + default_spinDbl = 0.; + default_selection = QString(""); + + // List for the selector + selector_strings.clear(); + selector_strings.append( tr( "PREF_LIST_TEXT_0" ) ); + selector_strings.append( tr( "PREF_LIST_TEXT_1" ) ); + selector_strings.append( tr( "PREF_LIST_TEXT_2" ) ); +} + +// Gets a reference to the module's engine +HXX2SALOME_GENERIC_CLASS_NAME_ORB::HXX2SALOME_GENERIC_CLASS_NAME_Gen_ptr HXX2SALOME_GENERIC_CLASS_NAMEGUI::InitHXX2SALOME_GENERIC_CLASS_NAMEGen( SalomeApp_Application* app ) +{ + Engines::Component_var comp = app->lcc()->FindOrLoad_Component( "FactoryServer",COMPONENT_NAME ); + HXX2SALOME_GENERIC_CLASS_NAME_ORB::HXX2SALOME_GENERIC_CLASS_NAME_Gen_ptr clr = HXX2SALOME_GENERIC_CLASS_NAME_ORB::HXX2SALOME_GENERIC_CLASS_NAME_Gen::_narrow(comp); + ASSERT(!CORBA::is_nil(clr)); + return clr; +} + +// Module's initialization +void HXX2SALOME_GENERIC_CLASS_NAMEGUI::initialize( CAM_Application* app ) +{ + // Get handle to Application, Desktop and Resource Manager + SalomeApp_Module::initialize( app ); + + InitHXX2SALOME_GENERIC_CLASS_NAMEGen( dynamic_cast( app ) ); + + QWidget* aParent = app->desktop(); + + SUIT_ResourceMgr* aResourceMgr = app->resourceMgr(); + + // GUI items + // --> Create actions: 190 is linked to item in "File" menu + // and 901 is linked to both specific menu and toolbar + createAction( 190, tr( "TLT_MY_NEW_ITEM" ), QIconSet(), tr( "MEN_MY_NEW_ITEM" ), tr( "STS_MY_NEW_ITEM" ), 0, aParent, false, + this, SLOT( OnMyNewItem() ) ); + + QPixmap aPixmap = aResourceMgr->loadPixmap( COMPONENT_NAME,tr( "ICON_HXX2SALOME_GENERIC_CLASS_NAME" ) ); + createAction( 901, tr( "TLT_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" ), QIconSet( aPixmap ), tr( "MEN_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" ), tr( "STS_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" ), 0, aParent, false, + this, SLOT( OnCallAction() ) ); + + // --> Create item in "File" menu + int aMenuId; + aMenuId = createMenu( tr( "MEN_FILE" ), -1, -1 ); + createMenu( separator(), aMenuId, -1, 10 ); + aMenuId = createMenu( tr( "MEN_FILE_HXX2SALOME_GENERIC_CLASS_NAME" ), aMenuId, -1, 10 ); + createMenu( 190, aMenuId ); + + // --> Create specific menu + aMenuId = createMenu( tr( "MEN_HXX2SALOME_GENERIC_CLASS_NAME" ), -1, -1, 30 ); + createMenu( 901, aMenuId, 10 ); + + // --> Create toolbar item + int aToolId = createTool ( tr( "TOOL_HXX2SALOME_GENERIC_CLASS_NAME" ) ); + createTool( 901, aToolId ); +} + +// Module's engine IOR +QString HXX2SALOME_GENERIC_CLASS_NAMEGUI::engineIOR() const +{ + CORBA::String_var anIOR = getApp()->orb()->object_to_string( InitHXX2SALOME_GENERIC_CLASS_NAMEGen( getApp() ) ); + return QString( anIOR.in() ); +} + +// Module's activation +bool HXX2SALOME_GENERIC_CLASS_NAMEGUI::activateModule( SUIT_Study* theStudy ) +{ + bool bOk = SalomeApp_Module::activateModule( theStudy ); + + setMenuShown( true ); + setToolShown( true ); + + return bOk; +} + +// Module's deactivation +bool HXX2SALOME_GENERIC_CLASS_NAMEGUI::deactivateModule( SUIT_Study* theStudy ) +{ + setMenuShown( false ); + setToolShown( false ); + + return SalomeApp_Module::deactivateModule( theStudy ); +} + +// Default windows +void HXX2SALOME_GENERIC_CLASS_NAMEGUI::windows( QMap& theMap ) const +{ + theMap.clear(); + theMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::DockLeft ); + theMap.insert( SalomeApp_Application::WT_PyConsole, Qt::DockBottom ); +} + +// Action slot: Launched with action 190 +void HXX2SALOME_GENERIC_CLASS_NAMEGUI::OnMyNewItem() +{ + SUIT_MessageBox::warn1( getApp()->desktop(),tr( "INF_HXX2SALOME_GENERIC_CLASS_NAME_TITLE" ), tr( "INF_HXX2SALOME_GENERIC_CLASS_NAME_TEXT" ), tr( "BUT_OK" ) ); +} + +// Action slot: Launched with action 901 +void HXX2SALOME_GENERIC_CLASS_NAMEGUI::OnCallAction() +{ + // Create a HXX2SALOME_GENERIC_CLASS_NAME component + HXX2SALOME_GENERIC_CLASS_NAME_ORB::HXX2SALOME_GENERIC_CLASS_NAME_Gen_ptr HXX2SALOME_GENERIC_CLASS_NAMEgen = HXX2SALOME_GENERIC_CLASS_NAMEGUI::InitHXX2SALOME_GENERIC_CLASS_NAMEGen( getApp() ); + + // Do the job... + // + // HXX2SALOME_GENERIC_CLASS_NAMEgen->method( arg1, arg2, ... ); + + // Open a dialog showing Preferences values (just to display something) + + // ****** Direct access to preferences: implementation at 12/12/05 ****** + // Comment out this section when "preferencesChanged" called back + SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr(); + + default_bool = mgr->booleanValue(COMPONENT_NAME, "default_bool", false); + + default_int = mgr->integerValue(COMPONENT_NAME, "default_integer", 3); + + default_spinInt = mgr->integerValue(COMPONENT_NAME, "default_spinint", 4); + + default_spinDbl = mgr->doubleValue(COMPONENT_NAME, "default_spindbl", 4.5); + + int selectorIndex = mgr->integerValue(COMPONENT_NAME, "default_selector"); + default_selection = (0<=selectorIndex && selectorIndex<=selector_strings.count() ? selector_strings[selectorIndex]: QString("None")); + // ****** End of section to be commented out ****** + + QString SUC = ( default_bool ? QString( tr ("INF_HXX2SALOME_GENERIC_CLASS_NAME_CHECK") ) : QString( tr("INF_HXX2SALOME_GENERIC_CLASS_NAME_UNCHECK") ) ) ; + + QString textResult = QString( tr( "RES_HXX2SALOME_GENERIC_CLASS_NAME_TEXT" ) ).arg(SUC).arg(default_int).arg(default_spinInt).arg(default_spinDbl).arg(default_selection); + SUIT_MessageBox::info1( getApp()->desktop(), tr( "RES_HXX2SALOME_GENERIC_CLASS_NAME_TITLE" ), textResult, tr( "BUT_OK" ) ); +} + +void HXX2SALOME_GENERIC_CLASS_NAMEGUI::createPreferences() +{ + // A sample preference dialog + + // One only tab + int genTab = addPreference( tr( "PREF_TAB_GENERAL" ) ); + + // One only group + int defaultsGroup = addPreference( tr( "PREF_GROUP_DEFAULTS" ), genTab ); + + // A checkbox + addPreference( tr( "PREF_DEFAULT_BOOL" ), defaultsGroup, LightApp_Preferences::Bool, COMPONENT_NAME, "default_bool" ); + + // An entry for integer + addPreference( tr( "PREF_DEFAULT_INTEGER" ), defaultsGroup, LightApp_Preferences::Integer, COMPONENT_NAME, "default_integer" ); + + // An integer changed by spinbox + int spinInt = addPreference( tr( "PREF_DEFAULT_SPININT" ), defaultsGroup, LightApp_Preferences::IntSpin, COMPONENT_NAME, "default_spinint" ); + setPreferenceProperty( spinInt, "min", 0 ); + setPreferenceProperty( spinInt, "max", 20 ); + setPreferenceProperty( spinInt, "step", 2 ); + + // A Double changed by spinbox + int spinDbl = addPreference( tr( "PREF_DEFAULT_SPINDBL" ), defaultsGroup, LightApp_Preferences::DblSpin, COMPONENT_NAME, "default_spindbl" ); + setPreferenceProperty( spinDbl, "min", 1 ); + setPreferenceProperty( spinDbl, "max", 10 ); + setPreferenceProperty( spinDbl, "step", 0.1 ); + + // A choice in a list + int options = addPreference( tr( "PREF_DEFAULT_SELECTOR" ), defaultsGroup, LightApp_Preferences::Selector, COMPONENT_NAME, "default_selector" ); + QValueList indices; + indices.append( 0 ); + indices.append( 1 ); + indices.append( 2 ); + setPreferenceProperty( options, "strings", selector_strings ); + setPreferenceProperty( options, "indexes", indices ); +} + +void HXX2SALOME_GENERIC_CLASS_NAMEGUI::preferencesChanged( const QString& sect, const QString& name ) +{ +// ****** This is normal way: Not yet called back at 12/12/05 ****** + SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr(); + if( sect==COMPONENT_NAME ) + { + if( name=="default_bool" ) + default_bool = mgr->booleanValue(COMPONENT_NAME, "default_bool", false); + if( name=="default_integer" ) + default_int = mgr->integerValue(COMPONENT_NAME, "default_integer", 3); + if( name=="default_spinint" ) + default_spinInt = mgr->integerValue(COMPONENT_NAME, "default_spinint", 4); + if( name=="default_spindbl" ) + default_spinDbl = mgr->doubleValue(COMPONENT_NAME, "default_spindbl", 4.5); + if( name=="default_selector" ) + { + int selectorIndex = mgr->integerValue(COMPONENT_NAME, "default_selector"); + default_selection = (0<=selectorIndex && selectorIndex<=selector_strings.count() ? selector_strings[selectorIndex]: QString("None")); + } + } +} + +// Export the module +extern "C" { + CAM_Module* createModule() + { + return new HXX2SALOME_GENERIC_CLASS_NAMEGUI(); + } +} diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.h b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.h new file mode 100644 index 000000000..ac1e50b1d --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.h @@ -0,0 +1,48 @@ +// HXX2SALOME_GENERIC_CLASS_NAMEGUI : HXX2SALOME_GENERIC_CLASS_NAME component GUI implemetation +// + +#ifndef _HXX2SALOME_GENERIC_CLASS_NAMEGUI_H_ +#define _HXX2SALOME_GENERIC_CLASS_NAMEGUI_H_ + +#include + +#include +#include CORBA_CLIENT_HEADER(HXX2SALOME_GENERIC_CLASS_NAME_Gen) + +class SalomeApp_Application; +class HXX2SALOME_GENERIC_CLASS_NAMEGUI: public SalomeApp_Module +{ + Q_OBJECT + +public: + HXX2SALOME_GENERIC_CLASS_NAMEGUI(); + + void initialize( CAM_Application* ); + QString engineIOR() const; + void windows( QMap& ) const; + + static HXX2SALOME_GENERIC_CLASS_NAME_ORB::HXX2SALOME_GENERIC_CLASS_NAME_Gen_ptr InitHXX2SALOME_GENERIC_CLASS_NAMEGen( SalomeApp_Application* ); + + virtual void createPreferences(); + virtual void preferencesChanged( const QString&, const QString& ); + +public slots: + bool deactivateModule( SUIT_Study* ); + bool activateModule( SUIT_Study* ); + +protected slots: + void OnMyNewItem(); + void OnCallAction(); + +private: + bool default_bool; + int default_int; + int default_spinInt; + double default_spinDbl; + QString default_selection; + + QStringList selector_strings; + +}; + +#endif diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_icons.po b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_icons.po new file mode 100644 index 000000000..a2f2c9a54 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_icons.po @@ -0,0 +1,14 @@ +# This is a Qt message file in .po format. Each msgid starts with +# a scope. This scope should *NOT* be translated - eg. "Foo::Bar" +# would be translated to "Pub", not "Foo::Pub". +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + +msgid "ICON_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "ExecHXX2SALOME_GENERIC_CLASS_NAME.png" + diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_en.po b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_en.po new file mode 100644 index 000000000..ecb36b546 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_en.po @@ -0,0 +1,99 @@ +# This is a Qt message file in .po format. Each msgid starts with +# a scope. This scope should *NOT* be translated - eg. translating +# from French to English, "Foo::Bar" would be translated to "Pub", +# not "Foo::Pub". +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2003-11-19 03:10:19 PM CET\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::BUT_OK" +msgstr "OK" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::BUT_CANCEL" +msgstr "Cancel" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_TITLE" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME Information" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_TEXT" +msgstr "This is just a test" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_CHECK" +msgstr "Checked" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_UNCHECK" +msgstr "Unchecked" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::RES_HXX2SALOME_GENERIC_CLASS_NAME_TITLE" +msgstr "Sample HXX2SALOME_GENERIC_CLASS_NAME dialog" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::RES_HXX2SALOME_GENERIC_CLASS_NAME_TEXT" +msgstr "Preferences are: \n\tCheckbox: %1\n\tInteger: %2\n\tInteger2: %3\n\tDouble: %4\n\tText: %5" + +msgid "TLT_MY_NEW_ITEM" +msgstr "A HXX2SALOME_GENERIC_CLASS_NAME owned menu item" + +msgid "MEN_MY_NEW_ITEM" +msgstr "My menu" + +msgid "STS_MY_NEW_ITEM" +msgstr "Display a simple dialog" + +msgid "TLT_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" +msgstr "Open HXX2SALOME_GENERIC_CLASS_NAME dialog" + +msgid "MEN_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME dialog" + +msgid "STS_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" +msgstr "Open HXX2SALOME_GENERIC_CLASS_NAME dialog" + +msgid "MEN_FILE" +msgstr "&File" + +msgid "MEN_FILE_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME menu" + +msgid "MEN_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "TOOL_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME" + +#------------------------------------------------------------------------- +# PREFEERENCES +#------------------------------------------------------------------------- + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_TAB_GENERAL" +msgstr "General" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_GROUP_DEFAULTS" +msgstr "Default Values" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_BOOL" +msgstr "Check me" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_INTEGER" +msgstr "Type in integer:" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_SPININT" +msgstr "Click arrows (integer) :" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_SPINDBL" +msgstr "Click arrows (double) :" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_SELECTOR" +msgstr "Select an option" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_LIST_TEXT_0" +msgstr "First option" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_LIST_TEXT_1" +msgstr "Second option" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_LIST_TEXT_2" +msgstr "Third option" diff --git a/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_fr.po b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_fr.po new file mode 100644 index 000000000..8ba648d45 --- /dev/null +++ b/src/wrappergen/bin/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_fr.po @@ -0,0 +1,99 @@ +# This is a Qt message file in .po format. Each msgid starts with +# a scope. This scope should *NOT* be translated - eg. translating +# from French to English, "Foo::Bar" would be translated to "Pub", +# not "Foo::Pub". +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2003-11-19 03:10:25 PM CET\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::BUT_OK" +msgstr "OK" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::BUT_CANCEL" +msgstr "Annuler" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_TITLE" +msgstr "Information HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_TEXT" +msgstr "Ceci est un simple test" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_CHECK" +msgstr "Cochée" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_UNCHECK" +msgstr "Décochée" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::RES_HXX2SALOME_GENERIC_CLASS_NAME_TITLE" +msgstr "Dialogue example de HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::RES_HXX2SALOME_GENERIC_CLASS_NAME_TEXT" +msgstr "Les préférences sont : \n\tCase à cocher : %1\n\tEntier : %2\n\tEntier2 : %3\n\tDouble : %4\n\tTexte : %5" + +msgid "TLT_MY_NEW_ITEM" +msgstr "Un article de menu propre à HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "MEN_MY_NEW_ITEM" +msgstr "Mon menu" + +msgid "STS_MY_NEW_ITEM" +msgstr "Affiche une boîte de dialogue simple" + +msgid "TLT_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" +msgstr "Ouvre la boîte de dialogue de HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "MEN_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" +msgstr "Boîte de dialogue de HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "STS_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" +msgstr "Ouvre la boîte de dialogue de HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "MEN_FILE" +msgstr "&File" + +msgid "MEN_FILE_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "Menu de HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "MEN_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "TOOL_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME" + +#------------------------------------------------------------------------- +# PREFEERENCES +#------------------------------------------------------------------------- + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_TAB_GENERAL" +msgstr "Général" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_GROUP_DEFAULTS" +msgstr "Valeurs par défaut" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_BOOL" +msgstr "Cochez-moi" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_INTEGER" +msgstr "Entrez un entier :" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_SPININT" +msgstr "Cliquez sur les flèches (entier) :" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_SPINDBL" +msgstr "Cliquez sur les flèches (double) :" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_SELECTOR" +msgstr "Choisissez une option" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_LIST_TEXT_0" +msgstr "Première option" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_LIST_TEXT_1" +msgstr "Seconde option" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_LIST_TEXT_2" +msgstr "Troisième option" diff --git a/src/wrappergen/bin/Makefile.am b/src/wrappergen/bin/Makefile.am new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/wrappergen/bin/Makefile.am @@ -0,0 +1 @@ + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/AUTHORS b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/AUTHORS new file mode 100644 index 000000000..e69de29bb diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/COPYING b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/COPYING new file mode 100644 index 000000000..623b6258a --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/ChangeLog b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/INSTALL b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/INSTALL new file mode 100644 index 000000000..23e5f25d0 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +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' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', 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 +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files 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 option `--target=TYPE' 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/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/Makefile.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/Makefile.am new file mode 100644 index 000000000..490d134ee --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/Makefile.am @@ -0,0 +1,29 @@ +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +if SALOME_KERNEL + SUBDIRS=idl + DIST_SUBDIRS=idl +else + SUBDIRS= + DIST_SUBDIRS= +endif + +SUBDIRS += adm_local src doc bin resources +DIST_SUBDIRS += adm_local src doc bin resources + +DISTCLEANFILES = a.out + +install-exec-local: + cp ${srcdir}/env_HXX2SALOME_GENERIC_CLASS_NAME.sh ${prefix} + +dist-hook: + rm -rf `find $(distdir) -name CVS` + +usr_docs: + (cd doc && $(MAKE) $(AM_MAKEFLAGS) usr_docs) + +docs:usr_docs + +dev_docs: + (cd doc && $(MAKE) $(AM_MAKEFLAGS) dev_docs) + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/NEWS b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/NEWS new file mode 100644 index 000000000..e69de29bb diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/README b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/README new file mode 100644 index 000000000..e69de29bb diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/Makefile.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/Makefile.am new file mode 100644 index 000000000..17e24c797 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = unix diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/Makefile.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/Makefile.am new file mode 100644 index 000000000..fabc465af --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/Makefile.am @@ -0,0 +1,4 @@ +include $(top_srcdir)/adm_local/unix/make_common_starter.am + + + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/SALOMEconfig.h.in b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/SALOMEconfig.h.in new file mode 100644 index 000000000..e08b51846 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/SALOMEconfig.h.in @@ -0,0 +1,36 @@ +#ifndef SALOME_CONFIG_H +#define SALOME_CONFIG_H + +#define DEBUG + +#define QUOTE(x) #x +#define CORBA_CLIENT_HEADER(x) QUOTE(x@IDL_CLN_H@) +#define CORBA_SERVER_HEADER(x) QUOTE(x@IDL_SRV_H@) + +#ifndef @MACHINE@ + #define @MACHINE@ +#endif + + +/* A path to a rcp-like command */ +#define RCP "@RCP@" + +/* A path to a rm-like command */ +#define RM "@RM@" + +/* A path to a cp-like command */ +#define CP "@CP@" + +/* A path to a rsh-like command */ +#define RSH "@RSH@" + +/* A path to a scp-like command */ +#define SCP "@SCP@" + +/* A path to a sh-like command */ +#define SH "@SH@" + +/* A path to a ssh-like command */ +#define SSH "@SSH@" + +#endif diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/README b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/README new file mode 100644 index 000000000..feb997b16 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/README @@ -0,0 +1,3 @@ +This file is only here for CVS: +CVS does not always create empty directory, and adm_local/unix/config_file +is needed by build_configure. diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cc_warnings.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cc_warnings.m4 new file mode 100644 index 000000000..9f3aa1a7f --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cc_warnings.m4 @@ -0,0 +1,119 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl Synopsis : AC_CC_WARNINGS([ANSI]) +dnl +dnl Version : 1.1 (2000/12/31) +dnl +dnl Author : Ville Laurikari +dnl +dnl Description : +dnl +dnl Enables a reasonable set of warnings for the C compiler. +dnl Optionally, if the first argument is nonempty, turns on +dnl flags which enforce and/or enable proper ANSI C if such +dnl flags are known to the compiler used. +dnl +dnl Currently this macro knows about GCC, Solaris C compiler, +dnl Digital Unix C compiler, C for AIX Compiler, HP-UX C +dnl compiler, and IRIX C compiler. + +AC_DEFUN([AC_CC_WARNINGS], [ + ansi=$1 + if test -z "$ansi"; then + msg="for C compiler warning flags" + else + msg="for C compiler warning and ANSI conformance flags" + fi + AC_CACHE_CHECK($msg, ac_cv_prog_cc_warnings, [ + if test -n "$CC"; then + cat > conftest.c <&1 | grep "Xc.*strict ANSI C" > /dev/null 2>&1 && + $CC -c -v -Xc conftest.c > /dev/null 2>&1 && + test -f conftest.o; then + if test -z "$ansi"; then + ac_cv_prog_cc_warnings="-v" + else + ac_cv_prog_cc_warnings="-v -Xc" + fi + + dnl HP-UX C compiler + elif $CC > /dev/null 2>&1 && + $CC -c -Aa +w1 conftest.c > /dev/null 2>&1 && + test -f conftest.o; then + if test -z "$ansi"; then + ac_cv_prog_cc_warnings="+w1" + else + ac_cv_prog_cc_warnings="+w1 -Aa" + fi + + dnl Digital Unix C compiler + elif ! $CC > /dev/null 2>&1 && + $CC -c -verbose -w0 -warnprotos -std1 conftest.c > /dev/null 2>&1 && + test -f conftest.o; then + if test -z "$ansi"; then + ac_cv_prog_cc_warnings="-verbose -w0 -warnprotos" + else + ac_cv_prog_cc_warnings="-verbose -w0 -warnprotos -std1" + fi + + dnl C for AIX Compiler + elif $CC > /dev/null 2>&1 | grep AIX > /dev/null 2>&1 && + $CC -c -qlanglvl=ansi -qinfo=all conftest.c > /dev/null 2>&1 && + test -f conftest.o; then + if test -z "$ansi"; then + ac_cv_prog_cc_warnings="-qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" + else + ac_cv_prog_cc_warnings="-qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd -qlanglvl=ansi" + fi + + dnl IRIX C compiler + elif $CC -fullwarn -ansi -ansiE > /dev/null 2>&1 && + test -f conftest.o; then + if test -z "$ansi"; then + ac_cv_prog_cc_warnings="-fullwarn" + else + ac_cv_prog_cc_warnings="-fullwarn -ansi -ansiE" + fi + + fi + rm -f conftest.* + fi + if test -n "$ac_cv_prog_cc_warnings"; then + CFLAGS="$CFLAGS $ac_cv_prog_cc_warnings" + CXXFLAGS="$CXXFLAGS $ac_cv_prog_cc_warnings" + else + ac_cv_prog_cc_warnings="unknown" + fi + ]) +]) diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_depend_flag.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_depend_flag.m4 new file mode 100644 index 000000000..9dc8b0fd3 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_depend_flag.m4 @@ -0,0 +1,144 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl @synopsis AC_C_DEPEND_FLAG +dnl +dnl define C_DEPEND_FLAG +dnl define CXX_DEPEND_FLAG +dnl +dnl @version $Id$ +dnl @author Marc Tajchman +dnl +AC_DEFUN([AC_DEPEND_FLAG], +[AC_CACHE_CHECK(which flag for dependency information generation, +ac_cv_depend_flag, +[AC_LANG_SAVE + AC_LANG_C + echo "conftest.o: conftest.c" > conftest.verif + echo "int main() { return 0; }" > conftest.c + +dnl Evolution portage sur CCRT/osf system + case $host_os in + osf*) +dnl sur CCRT/osf pas d'equivalent de l'option -MG de gcc avec compilo natif +dnl on utilise donc gnu pour generer les dependances. + DEPCC=gcc + DEPCXX=g++ + DEPCXXFLAGS="-Wno-deprecated" + DIFFFLAGS="-w" + MACHINE="OSF1" + ;; + *) + DEPCC=${CC-cc} + DEPCXX=${CXX-c++} + DEPCXXFLAGS="\${CXXFLAGS}" + DIFFFLAGS="-b -B" + MACHINE="PCLINUX" + ;; + esac + C_DEPEND_FLAG= + for ac_C_DEPEND_FLAG in -xM -MM -M ; do + + rm -f conftest.d conftest.err + ${DEPCC} ${ac_C_DEPEND_FLAG} -c conftest.c 1> conftest.d 2> conftest.err + if test -f conftest.u ; then + mv conftest.u conftest.d + fi + + rm -f conftest + diff ${DIFFFLAGS} conftest.d conftest.verif > conftest + if test ! -s conftest ; then + C_DEPEND_FLAG=${ac_C_DEPEND_FLAG} + break + fi + done + +dnl use gcc option -MG : asume unknown file will be construct later + rm -f conftest.d conftest.err + ${DEPCC} ${C_DEPEND_FLAG} -MG -c conftest.c 1> conftest.d 2> conftest.err + if test -f conftest.u ; then + mv conftest.u conftest.d + fi + rm -f conftest + diff ${DIFFFLAGS} conftest.d conftest.verif > conftest + if test ! -s conftest ; then + C_DEPEND_FLAG=${C_DEPEND_FLAG}" -MG" + fi + + rm -f conftest* + if test "x${C_DEPEND_FLAG}" = "x" ; then + echo "cannot determine flag (C language)" + exit + fi + + printf " C : ${DEPCC} ${C_DEPEND_FLAG}" + + AC_LANG_CPLUSPLUS + echo "conftest.o: conftest.cxx" > conftest.verif + echo "int main() { return 0; }" > conftest.cxx + + CXX_DEPEND_FLAG= + for ac_CXX_DEPEND_FLAG in -xM -MM -M ; do + + rm -f conftest.d conftest.err + ${DEPCXX} ${ac_CXX_DEPEND_FLAG} -c conftest.cxx 1> conftest.d 2> conftest.err + if test -f conftest.u ; then + mv conftest.u conftest.d + fi + + rm -f conftest + diff ${DIFFFLAGS} conftest.d conftest.verif > conftest + if test ! -s conftest ; then + CXX_DEPEND_FLAG=${ac_CXX_DEPEND_FLAG} + break + fi + done + +dnl use g++ option -MG : asume unknown file will be construct later + rm -f conftest.d conftest.err + ${DEPCXX} ${CXX_DEPEND_FLAG} -MG -c conftest.cxx 1> conftest.d 2> conftest.err + if test -f conftest.u ; then + mv conftest.u conftest.d + fi + rm -f conftest + diff ${DIFFFLAGS} conftest.d conftest.verif > conftest + if test ! -s conftest ; then + CXX_DEPEND_FLAG=${CXX_DEPEND_FLAG}" -MG" + fi + + + rm -f conftest* + if test "x${CXX_DEPEND_FLAG}" = "x" ; then + echo "cannot determine flag (C++ language)" + exit + fi + + printf " C++ : ${DEPCXX} ${CXX_DEPEND_FLAG}" + AC_LANG_RESTORE + + AC_SUBST(DEPCC) + AC_SUBST(DEPCXX) + AC_SUBST(DEPCXXFLAGS) + AC_SUBST(C_DEPEND_FLAG) + AC_SUBST(CXX_DEPEND_FLAG) + AC_SUBST(MACHINE) +]) +]) diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_have_sstream.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_have_sstream.m4 new file mode 100644 index 000000000..b3b009f3a --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_have_sstream.m4 @@ -0,0 +1,45 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl @synopsis AC_CXX_HAVE_SSTREAM +dnl +dnl If the C++ library has a working stringstream, define HAVE_SSTREAM. +dnl +dnl @author Ben Stanley +dnl @version $Id$ +dnl +dnl modified by Marc Tajchman (CEA) - 10/10/2002 +dnl +AC_DEFUN([AC_CXX_HAVE_SSTREAM], +[AC_CACHE_CHECK(whether the compiler has stringstream, +HAVE_SSTREAM, +[AC_REQUIRE([AC_CXX_NAMESPACES]) + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_COMPILE([#include +#ifdef HAVE_NAMESPACES +using namespace std; +#endif],[stringstream message; message << "Hello"; return 0;], + HAVE_SSTREAM=yes, HAVE_SSTREAM=no) + AC_LANG_RESTORE +]) +AC_SUBST(HAVE_SSTREAM) +]) diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_namespaces.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_namespaces.m4 new file mode 100644 index 000000000..76b815ace --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_namespaces.m4 @@ -0,0 +1,43 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl @synopsis AC_CXX_NAMESPACES +dnl +dnl If the compiler can prevent names clashes using namespaces, define +dnl HAVE_NAMESPACES. +dnl +dnl @version $Id$ +dnl @author Luc Maisonobe +dnl +AC_DEFUN([AC_CXX_NAMESPACES], +[AC_CACHE_CHECK(whether the compiler implements namespaces, +ac_cv_cxx_namespaces, +[AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_COMPILE([namespace Outer { namespace Inner { int i = 0; }}], + [using namespace Outer::Inner; return i;], + ac_cv_cxx_namespaces=yes, ac_cv_cxx_namespaces=no) + AC_LANG_RESTORE +]) +if test "$ac_cv_cxx_namespaces" = yes; then + AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces]) +fi +]) diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_option.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_option.m4 new file mode 100644 index 000000000..72ea0ab11 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_option.m4 @@ -0,0 +1,45 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl @synopsis AC_CXX_OPTION(-option,variable where we add option if ok,action if ok; action if not ok) +dnl +dnl Check options for C++ compiler +dnl +dnl @author Bernard Secher - 15/01/2004 +dnl +AC_DEFUN([AC_CXX_OPTION], [ + AC_MSG_CHECKING(wether $CXX accepts $1) + cat > conftest.cxx < conftest.log 2>&1 + var=`echo $1 | sed -e "s, .*$,," | sed -e "s,^-,,"` + if ! grep -e $var conftest.log > /dev/null 2>&1 ; then + AC_MSG_RESULT(yes) + $2="${$2} $1" + eval $3 + else + AC_MSG_RESULT(no) + eval $4 + fi +]) + + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_template_options.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_template_options.m4 new file mode 100644 index 000000000..4192ec011 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_template_options.m4 @@ -0,0 +1,39 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl @synopsis AC_CXX_TEMPLATE_OPTIONS +dnl +dnl Check template options for C++ compiler +dnl +dnl @author Bernard Secher (CEA) - 04/12/2003 +dnl +AC_DEFUN([AC_CXX_TEMPLATE_OPTIONS],[ +dnl + for opt in -ftemplate-depth-42 "-pending_instantiations 42" ; do + AC_CXX_OPTION($opt,CXXTMPDPTHFLAGS,flag=yes,flag=no) + if test "$flag" = "yes"; then + break + fi + AC_SUBST(CXXTMPDPTHFLAGS) + done +dnl + AC_CXX_OPTION(-tweak,CXXFLAGS) +]) diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_use_std_iostream.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_use_std_iostream.m4 new file mode 100644 index 000000000..8e44db9ac --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_use_std_iostream.m4 @@ -0,0 +1,55 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl @synopsis AC_CXX_USE_STD_IOSTREAM +dnl +dnl If the C++ library use std iostream +dnl +dnl @author Bernard Secher (CEA) - 05/12/2003 +dnl +AC_DEFUN([AC_CXX_USE_STD_IOSTREAM], +[ + +AC_MSG_CHECKING(whether the compiler use std iostream) + +cat > conftest.cxx < +int main(int argc, char **argv) {std::cout << "Hello" << std::endl; return 0;} +EOF + +fUSE_STD_IOSTREAM=no +for ac_CXX_USE_STD_IOSTREAM in "" -D__USE_STD_IOSTREAM ; do + if $CXX ${ac_CXX_USE_STD_IOSTREAM} conftest.cxx > /dev/null 2>&1; then + CPPFLAGS="$CPPFLAGS ${ac_CXX_USE_STD_IOSTREAM}" + if test x${ac_CXX_USE_STD_IOSTREAM} = x; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(${ac_CXX_USE_STD_IOSTREAM}) + fi + fUSE_STD_IOSTREAM=yes + break + fi +done +if test $fUSE_STD_IOSTREAM = no; then + AC_MSG_RESULT(no) +fi + +]) diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_warnings.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_warnings.m4 new file mode 100644 index 000000000..b23ca3bd2 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_cxx_warnings.m4 @@ -0,0 +1,34 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl @synopsis AC_CXX_WARNINGS +dnl +dnl Check warning flags for C++ compiler to control warning messages +dnl +dnl @author Bernard Secher (CEA) - 04/12/2003 +dnl +AC_DEFUN([AC_CXX_WARNINGS],[ + AC_CXX_OPTION(-Wno-deprecated,CXXFLAGS) + AC_CXX_OPTION(-Wparentheses,CXXFLAGS) + AC_CXX_OPTION(-Wreturn-type,CXXFLAGS) + AC_CXX_OPTION(-Wmissing-declarations,CXXFLAGS) + AC_CXX_OPTION(-Wunused,CXXFLAGS) +]) diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_linker_options.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_linker_options.m4 new file mode 100644 index 000000000..81321d4ec --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/ac_linker_options.m4 @@ -0,0 +1,57 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl @synopsis AC_LINKER_OPTIONS +dnl +dnl Check warning flags for C++ compiler to control warning messages +dnl +dnl @author Bernard Secher (CEA) - 04/12/2003 +dnl +AC_DEFUN([AC_LINKER_OPTIONS],[ + + AC_CHECKING(for LIB_LOCATION_SUFFIX) + LIB_LOCATION_SUFFIX="" + case "$build_cpu" in + *64*) LIB_LOCATION_SUFFIX="64" ;; + *) LIB_LOCATION_SUFFIX="" ;; + esac + AC_SUBST(LIB_LOCATION_SUFFIX) + AC_MSG_RESULT(LIB_LOCATION_SUFFIX is $LIB_LOCATION_SUFFIX) + + for opt in "-Xlinker -export-dynamic" -transitive_link; do + AC_CXX_OPTION($opt,LDEXPDYNFLAGS,flag=yes,flag=no) + if test "$flag" = "yes"; then + break + fi + done + AC_SUBST(LDEXPDYNFLAGS) + +dnl + case $host_os in + osf*) + STDLIB="-lcxxstd" + ;; + *) + STDLIB="-lstdc++" + ;; + esac + AC_SUBST(STDLIB) +]) diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Comp_Env.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Comp_Env.m4 new file mode 100644 index 000000000..0c8f1c631 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Comp_Env.m4 @@ -0,0 +1,25 @@ +# Check if component environment is either defined or not +# +# Author : Jean-Yves PRADILLON (OPEN CASCADE, 2005) +# + +AC_DEFUN([CHECK_COMPONENT_ENV],[ + +AC_CHECKING(for Component Environment) + +Comp_Env_ok=no + +if test -d "$HXX2SALOME_GENERIC_CLASS_NAMECPP_ROOT_DIR" ; then + Comp_Env_ok=yes + AC_MSG_RESULT(Using Component Root Dir ${HXX2SALOME_GENERIC_CLASS_NAMECPP_ROOT_DIR}) +else + AC_MSG_WARN(Cannot find Component Root Dir "${HXX2SALOME_GENERIC_CLASS_NAMECPP_ROOT_DIR}") + if test "x$HXX2SALOME_GENERIC_CLASS_NAMECPP_ROOT_DIR" = "x" ; then + AC_MSG_WARN(Did you source the environment file?) + fi +fi + +AC_MSG_RESULT(for Component Environment: $Comp_Env_ok) + +])dnl + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_GUI.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_GUI.m4 new file mode 100644 index 000000000..fab490fad --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_GUI.m4 @@ -0,0 +1,60 @@ +# Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +#------------------------------------------------------------ +# Check availability of Salome binary distribution +# +# Author : Marc Tajchman (CEA, 2002) +#------------------------------------------------------------ + +AC_DEFUN([CHECK_SALOME_GUI],[ + +AC_CHECKING(for SalomeGUI) + +SalomeGUI_ok=yes + +AC_ARG_WITH(gui, + --with-salome_gui=DIR root directory path of SALOME GUI installation, + SALOME_GUI_DIR="$withval",SALOME_GUI_DIR="") + +if test "x$SALOME_GUI_DIR" = "x" ; then + if test "x$GUI_ROOT_DIR" != "x" ; then + SALOME_GUI_DIR=$GUI_ROOT_DIR + else + # search Salome binaries in PATH variable + AC_PATH_PROG(TEMP, libSalomeApp.so) + if test "x$TEMP" != "x" ; then + SALOME_GUI_DIR=`dirname $TEMP` + fi + fi +fi + +if test -f ${SALOME_GUI_DIR}/lib/salome/libSalomeApp.so ; then + SalomeGUI_ok=yes + AC_MSG_RESULT(Using SALOME GUI distribution in ${SALOME_GUI_DIR}) + GUI_ROOT_DIR=${SALOME_GUI_DIR} + AC_SUBST(GUI_ROOT_DIR) +else + AC_MSG_WARN("Cannot find compiled SALOME GUI distribution") +fi + +AC_MSG_RESULT(for SALOME GUI: $SalomeGUI_ok) + +])dnl + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Kernel.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Kernel.m4 new file mode 100644 index 000000000..fc07131da --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Kernel.m4 @@ -0,0 +1,58 @@ +# Check availability of Salome's KERNEL binary distribution +# +# Author : Jerome Roy (CEA, 2003) +# + +AC_DEFUN([CHECK_KERNEL],[ + +AC_CHECKING(for Kernel) + +Kernel_ok=no + +AC_ARG_WITH(kernel, + [ --with-kernel=DIR root directory path of KERNEL build or installation], + KERNEL_DIR="$withval",KERNEL_DIR="") + +if test "x$KERNEL_DIR" = "x" ; then + +# no --with-kernel-dir option used + + if test "x$KERNEL_ROOT_DIR" != "x" ; then + + # KERNEL_ROOT_DIR environment variable defined + KERNEL_DIR=$KERNEL_ROOT_DIR + + else + + # search Kernel binaries in PATH variable + AC_PATH_PROG(TEMP, runSalome) + if test "x$TEMP" != "x" ; then + KERNEL_BIN_DIR=`dirname $TEMP` + KERNEL_DIR=`dirname $KERNEL_BIN_DIR` + fi + + fi +# +fi + +if test -f ${KERNEL_DIR}/bin/salome/runSalome ; then + Kernel_ok=yes + AC_MSG_RESULT(Using Kernel module distribution in ${KERNEL_DIR}) + + if test "x$KERNEL_ROOT_DIR" = "x" ; then + KERNEL_ROOT_DIR=${KERNEL_DIR} + fi + if test "x$KERNEL_SITE_DIR" = "x" ; then + KERNEL_SITE_DIR=${KERNEL_ROOT_DIR} + fi + AC_SUBST(KERNEL_ROOT_DIR) + AC_SUBST(KERNEL_SITE_DIR) + +else + AC_MSG_WARN("Cannot find compiled Kernel module distribution") +fi + +AC_MSG_RESULT(for Kernel: $Kernel_ok) + +])dnl + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med.m4 new file mode 100644 index 000000000..35d34f071 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med.m4 @@ -0,0 +1,119 @@ +# Check availability of Med binary distribution +# +# Author : Anthony GEAY (CEA, 2005) +# + +AC_DEFUN([CHECK_MED],[ + +CHECK_HDF5 +CHECK_MED2 + +AC_CHECKING(for Med) + +Med_ok=no + +AC_ARG_WITH(med, + [ --with-med=DIR root directory path of MED installation ], + MED_DIR="$withval",MED_DIR="") + +if test "x$MED_DIR" == "x" ; then + +# no --with-med-dir option used + + if test "x$MED_ROOT_DIR" != "x" ; then + + # MED_ROOT_DIR environment variable defined + MED_DIR=$MED_ROOT_DIR + + else + + # search Med binaries in PATH variable + AC_PATH_PROG(TEMP, libMEDMEM_Swig.py) + if test "x$TEMP" != "x" ; then + MED_BIN_DIR=`dirname $TEMP` + MED_DIR=`dirname $MED_BIN_DIR` + fi + + fi +# +fi + +if test -f ${MED_DIR}/bin/salome/libMEDMEM_Swig.py ; then + Med_ok=yes + AC_MSG_RESULT(Using Med module distribution in ${MED_DIR}) + + if test "x$MED_ROOT_DIR" == "x" ; then + MED_ROOT_DIR=${MED_DIR} + fi + AC_SUBST(MED_ROOT_DIR) + MED_INCLUDES="-I${MED_ROOT_DIR}/include/salome ${MED2_INCLUDES} ${HDF5_INCLUDES} -I${KERNEL_ROOT_DIR}/include/salome" + MED_LIBS="-L${MED_ROOT_DIR}/lib/salome -lmedmem" + AC_SUBST(MED_INCLUDES) + AC_SUBST(MED_LIBS) + +else + AC_MSG_WARN("Cannot find Med module sources") +fi + +AC_MSG_CHECKING([for MED memory version]) +[medmem_version=`cat ${MED_ROOT_DIR}/bin/salome/VERSION | cut -d" " -f7`] +[medmem_version=`expr $medmem_version : '\([0-9.]*\).*'`] +AC_MSG_RESULT([$medmem_version]) +AC_MSG_CHECKING([for g++ version]) +[gpp_version=`g++ --version | sed -e '2,$d' | cut -d" " -f3`] +AC_MSG_RESULT([$gpp_version]) +[available=$gpp_version] +dnl Analyzing g++ version +[available_major=`echo $available | sed 's/[^0-9].*//'`] +if test -z "$available_major" ; then + [available_major=0] +fi +[available=`echo $available | sed 's/[0-9]*[^0-9]//'`] +[available_minor=`echo $available | sed 's/[^0-9].*//'`] +if test -z "$available_minor" ; then + [available_minor=0] +fi +[available=`echo $available | sed 's/[0-9]*[^0-9]//'`] +[available_patch=`echo $available | sed 's/[^0-9].*//'`] +if test -z "$available_patch" ; then + [available_patch=0] +fi +dnl Testing if g++ verion >= 3.4.0 or not +if test $available_major -ne "3" \ + -o $available_minor -ne "4" \ + -o $available_patch -lt "0" ; then + [required_medmem_major=2] + [required_medmem_minor=2] + [required_medmem_patch=0] +else + [required_medmem_major=2] + [required_medmem_minor=2] + [required_medmem_patch=4] +fi +[available=$medmem_version] +[available_major=`echo $available | sed 's/[^0-9].*//'`] +if test -z "$available_major" ; then + [available_major=0] +fi +[available=`echo $available | sed 's/[0-9]*[^0-9]//'`] +[available_minor=`echo $available | sed 's/[^0-9].*//'`] +if test -z "$available_minor" ; then + [available_minor=0] +fi +[available=`echo $available | sed 's/[0-9]*[^0-9]//'`] +[available_patch=`echo $available | sed 's/[^0-9].*//'`] +if test -z "$available_patch" ; then + [available_patch=0] +fi +[available_num=`expr $available_major \* 100 + $available_minor \* 10 + $available_patch`] +[required_num=`expr $required_medmem_major \* 100 + $required_medmem_minor \* 10 + $required_medmem_patch`] +if test "x$Med_ok" == "xyes" ; then + if test $available_num -lt $required_num ; then + AC_MSG_WARN([MEDMEM version invalid with your compiler : MEDMEM version >=2.2.4 required !!!]) + Med_ok=no + fi +fi +AC_MSG_RESULT(for MED memory: $Med_ok) + +])dnl + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med2.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med2.m4 new file mode 100644 index 000000000..82b107880 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_Med2.m4 @@ -0,0 +1,114 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl + +AC_DEFUN([CHECK_MED2],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([CHECK_HDF5])dnl + +AC_CHECKING(for MED2) + +AC_ARG_WITH(med2, + [ --with-med2=DIR root directory path to med2 installation ], + [MED2HOME="$withval" + AC_MSG_RESULT("select $withval as path to med2") + ]) + +AC_SUBST(MED2_INCLUDES) +AC_SUBST(MED2_LIBS) +AC_SUBST(MED2_MT_LIBS) + +MED2_INCLUDES="" +MED2_LIBS="" +MED2_MT_LIBS="" + +med2_ok=no + +LOCAL_INCLUDES="$HDF5_INCLUDES" +LOCAL_LIBS="-lmed $HDF5_LIBS" + +if test -z $MED2HOME +then + AC_MSG_WARN(undefined MED2HOME variable which specify med2 installation directory) + AC_PATH_PROG(MDUMP, mdump) + if test "xMDUMP" != "x" ; then + MED2HOME=$MDUMP + MED2HOME=`echo ${MED2HOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + MED2HOME=`echo ${MED2HOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + fi +fi +if test ! -z $MED2HOME +then + LOCAL_INCLUDES="$LOCAL_INCLUDES -I$MED2HOME/include" + if test "x$MED2HOME" = "x/usr" + then + LOCAL_LIBS="-lmed $LOCAL_LIBS" + else + LOCAL_LIBS="-L$MED2HOME/lib $LOCAL_LIBS" + fi +fi + +dnl check med2 header + +CPPFLAGS_old="$CPPFLAGS" +dnl we must test system : linux = -DPCLINUX +dnl we must test system : Alpha-OSF = -DOSF1 +case $host_os in + linux*) + CPPFLAGS="$CPPFLAGS -DPCLINUX $LOCAL_INCLUDES" + ;; + osf*) + CPPFLAGS="$CPPFLAGS -DOSF1 $LOCAL_INCLUDES" + ;; +esac +AC_CHECK_HEADER(med.h,med2_ok=yes ,med2_ok=no) +CPPFLAGS="$CPPFLAGS_old" + +if test "x$med2_ok" = "xyes" +then + +dnl check med2 library + + LIBS_old="$LIBS" + LIBS="$LIBS $LOCAL_LIBS" + AC_CHECK_LIB(med,MEDouvrir,med2_ok=yes,med2_ok=no) + LIBS="$LIBS_old" + +fi + +if test "x$med2_ok" = "xyes" +then +case $host_os in + linux*) + MED2_INCLUDES="-DPCLINUX $LOCAL_INCLUDES" + ;; + osf*) + MED2_INCLUDES="-DOSF1 $LOCAL_INCLUDES" + ;; +esac + MED2_LIBS="$LOCAL_LIBS" + MED2_MT_LIBS="$LOCAL_LIBS" +fi + +AC_MSG_RESULT(for med2: $med2_ok) + +])dnl diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_boost.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_boost.m4 new file mode 100644 index 000000000..0298be6ee --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_boost.m4 @@ -0,0 +1,145 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +AC_DEFUN([CHECK_BOOST],[ + +AC_CHECKING(for BOOST Library) + +AC_REQUIRE([ENABLE_PTHREADS])dnl + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +BOOST_CPPFLAGS="" +BOOST_LIBSUFFIX="-mt" +BOOST_LIBS="" + +AC_CHECKING(for BOOST location) +AC_ARG_WITH(boost, + [AC_HELP_STRING([--with-boost=DIR],[root directory path to BOOST library installation])], + [BOOSTDIR="$withval" + AC_MSG_RESULT("select $withval as path to BOOST library") + ]) + +if test "x${BOOSTDIR}" = "x" ; then + BOOSTDIR="/usr" +fi + +AC_MSG_RESULT(\$BOOSTDIR = ${BOOSTDIR}) + +CPPFLAGS_old="${CPPFLAGS}" +LIBS_old=$LIBS + +if test "x${BOOSTDIR}" != "x" ; then + BOOST_CPPFLAGS="-I${BOOSTDIR}/include" + BOOST_LIBS="-L${BOOSTDIR}/lib${LIB_LOCATION_SUFFIX}" +fi + +boost_ok=no +boost_headers_ok=no +boost_binaries_ok=no + +dnl BOOST headers +AC_CHECKING(for BOOST headers) +CPPFLAGS="${CPPFLAGS_old} ${BOOST_CPPFLAGS}" + +boost_include_dir_ok=yes +if test "x${BOOSTDIR}" != "x" ; then + AC_CHECK_FILE(${BOOSTDIR}/include/boost/shared_ptr.hpp, + boost_include_dir_ok=yes, + boost_include_dir_ok=no) +fi + +if test "x${boost_include_dir_ok}" = "xyes" ; then + AC_TRY_COMPILE([#include ], + [boost::shared_ptr(new int)], + boost_headers_ok=yes, + boost_headers_ok=no) +fi + +if test "x${boost_headers_ok}" = "xno" ; then + BOOST_CPPFLAGS="BOOST_CPPFLAGS_NOT_DEFINED" +else + AC_MSG_RESULT(\$BOOST_CPPFLAGS = ${BOOST_CPPFLAGS}) +fi +AC_MSG_RESULT(for boost headers: $boost_headers_ok) + +if test "x${boost_headers_ok}" = "xyes" ; then + dnl BOOST binaries + AC_CHECKING(for BOOST binaries) + boost_lib_dir_ok=yes + if test "x${BOOSTDIR}" != "x" ; then + AC_CHECK_FILE(${BOOSTDIR}/lib${LIB_LOCATION_SUFFIX}/libboost_thread${BOOST_LIBSUFFIX}.so, + boost_lib_dir_ok=yes, + boost_lib_dir_ok=no) + if test "x${boost_lib_dir_ok}" = "xno" ; then + BOOST_LIBSUFFIX="" + AC_CHECK_FILE(${BOOSTDIR}/lib${LIB_LOCATION_SUFFIX}/libboost_thread${BOOST_LIBSUFFIX}.so, + boost_lib_dir_ok=yes, + boost_lib_dir_ok=no) + fi + fi + if test "x${boost_lib_dir_ok}" = "xyes" ; then + LIBS="${LIBS_old} ${BOOST_LIBS} -lboost_thread${BOOST_LIBSUFFIX}" + AC_TRY_LINK([#include ], + [struct TBody{ void operator()(){} }; boost::thread(TBody())], + boost_binaries_ok=yes, + boost_binaries_ok=no) + if test "x${boost_binaries_ok}" = "xno" ; then + BOOST_LIBSUFFIX="" + LIBS="${LIBS_old} ${BOOST_LIBS} -lboost_thread${BOOST_LIBSUFFIX}" + AC_TRY_LINK([#include ], + [struct TBody{ void operator()(){} }; boost::thread(TBody())], + boost_binaries_ok=yes, + boost_binaries_ok=no) + fi + fi +fi + +if test "x${boost_binaries_ok}" = "xno" ; then + BOOST_LIBS="BOOST_LIBS_NOT_FOUND" + BOOST_LIBSUFFIX="-not-defined" +else + AC_MSG_RESULT(\$BOOST_LIBSUFFIX = ${BOOST_LIBSUFFIX}) + AC_MSG_RESULT(\$BOOST_LIBS = ${BOOST_LIBS}) +fi +AC_MSG_RESULT(for boost binaries: $boost_binaries_ok) + +CPPFLAGS="${CPPFLAGS_old}" +LIBS="${LIBS_old}" + +if test "x${boost_headers_ok}" = "xyes" ; then + if test "x${boost_binaries_ok}" = "xyes" ; then + boost_ok=yes + fi +fi + +AC_MSG_RESULT(for boost: $boost_ok) + +AC_SUBST(BOOST_CPPFLAGS) +AC_SUBST(BOOST_LIBSUFFIX) +AC_SUBST(BOOST_LIBS) + +AC_LANG_RESTORE + +])dnl + + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_cas.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_cas.m4 new file mode 100644 index 000000000..ab2ba319d --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_cas.m4 @@ -0,0 +1,238 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +AC_DEFUN([CHECK_CAS],[ +AC_REQUIRE([AC_PROG_CXX])dnl +AC_REQUIRE([AC_PROG_CXXCPP])dnl + +AC_CHECKING(for OpenCascade) + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +AC_SUBST(CAS_CPPFLAGS) +AC_SUBST(CAS_CXXFLAGS) +AC_SUBST(CAS_KERNEL) +AC_SUBST(CAS_MATH) +AC_SUBST(CAS_VIEWER) +AC_SUBST(CAS_TKTopAlgo) +AC_SUBST(CAS_MODELER) +AC_SUBST(CAS_OCAF) +AC_SUBST(CAS_OCAFVIS) +AC_SUBST(CAS_DATAEXCHANGE) +AC_SUBST(CAS_LDFLAGS) +AC_SUBST(CAS_LDPATH) +AC_SUBST(CAS_STDPLUGIN) + +CAS_CPPFLAGS="" +CAS_CXXFLAGS="" +CAS_LDFLAGS="" +occ_ok=no +config_h=no + +dnl libraries directory location +case $host_os in + linux*) + casdir=Linux + ;; + freebsd*) + casdir=Linux + ;; + irix5.*) + casdir=Linux + ;; + irix6.*) + casdir=Linux + ;; + osf*) + casdir=Linux + ;; + solaris2.*) + casdir=Linux + ;; + *) + casdir=Linux + ;; +esac + +AC_MSG_CHECKING(for OpenCascade directories) + +if test -z "$CASROOT"; then + AC_MSG_RESULT(CASROOT not defined) + for d in `echo $LD_LIBRARY_PATH | sed -e "s/:/ /g"` ; do + if test -f $d/libTKernel.so ; then + AC_MSG_RESULT(libTKernel.so detected in $d) + CASROOT=$d + CASROOT=`echo ${CASROOT} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + break + fi + done +fi + +if test -d ${CASROOT}/${casdir}/lib; then + CAS_LDPATH="-L$CASROOT/$casdir/lib " + AC_MSG_RESULT(yes) +else + if test -d ${CASROOT}/lib; then + CAS_LDPATH="-L$CASROOT/lib " + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi +fi + + +dnl were is OCC ? +if test -z "$CASROOT"; then + AC_MSG_WARN(You must provide CASROOT variable : see OCC installation manual) +else + occ_ok=yes + OCC_VERSION_MAJOR=0 + OCC_VERSION_MINOR=0 + OCC_VERSION_MAINTENANCE=0 + ff=$CASROOT/inc/Standard_Version.hxx + if test -f $ff ; then + grep "define OCC_VERSION_MAJOR" $ff > /dev/null + if test $? = 0 ; then + OCC_VERSION_MAJOR=`grep "define OCC_VERSION_MAJOR" $ff | awk '{i=3 ; print $i}'` + fi + grep "define OCC_VERSION_MINOR" $ff > /dev/null + if test $? = 0 ; then + OCC_VERSION_MINOR=`grep "define OCC_VERSION_MINOR" $ff | awk '{i=3 ; print $i}'` + fi + grep "define OCC_VERSION_MAINTENANCE" $ff > /dev/null + if test $? = 0 ; then + OCC_VERSION_MAINTENANCE=`grep "define OCC_VERSION_MAINTENANCE" $ff | awk '{i=3 ; print $i}'` + fi + fi +fi + +if test "x$occ_ok" = "xyes"; then + +dnl test c++ compiler flag for unsigned character + for opt in -funsigned-char -unsigned ; do + AC_CXX_OPTION($opt,CAS_CXXFLAGS,flag=yes,flag=no) + if test "$flag" = "yes"; then + break + fi + done + +dnl cascade headers + + CPPFLAGS_old="$CPPFLAGS" +case $host_os in + linux*) + CAS_CPPFLAGS="-DOCC_VERSION_MAJOR=$OCC_VERSION_MAJOR -DOCC_VERSION_MINOR=$OCC_VERSION_MINOR -DOCC_VERSION_MAINTENANCE=$OCC_VERSION_MAINTENANCE -DLIN -DLINTEL -DCSFDB -DNo_exception -DHAVE_CONFIG_H -DHAVE_LIMITS_H -DHAVE_WOK_CONFIG_H" + + OCC_VERSION_STRING="$OCC_VERSION_MAJOR.$OCC_VERSION_MINOR.$OCC_VERSION_MAINTENANCE" + case $OCC_VERSION_STRING in + [[0-5]].* | 6.0.* | 6.1.0) # catch versions < 6.1.1 + CAS_CPPFLAGS="$CAS_CPPFLAGS -DNO_CXX_EXCEPTION" + ;; + *) + CAS_CPPFLAGS="$CAS_CPPFLAGS -DOCC_CONVERT_SIGNALS" + ;; + esac + CAS_CPPFLAGS="$CAS_CPPFLAGS -I$CASROOT/inc" + ;; + osf*) + CAS_CPPFLAGS="-DOCC_VERSION_MAJOR=$OCC_VERSION_MAJOR -DOCC_VERSION_MINOR=$OCC_VERSION_MINOR -DOCC_VERSION_MAINTENANCE=$OCC_VERSION_MAINTENANCE -DLIN -DLINTEL -DCSFDB -DNo_exception -DHAVE_CONFIG_H -DHAVE_LIMITS_H -DHAVE_WOK_CONFIG_H -I$CASROOT/inc" + ;; +esac + CPPFLAGS="$CPPFLAGS $CAS_CPPFLAGS" + + echo + echo testing config.h + + AC_CHECK_HEADER(config.h, config_h=yes, [ + echo "config.h file not found!" + ]) + + if test "x$config_h" = xno ; then + AC_MSG_WARN(config.h file not found) + dnl There is no consequence for SALOME building because + dnl this file is not used. SALOME uses SALOMEconfig.h instead! + else + AC_MSG_RESULT(config.h file ok) + fi + + AC_CHECK_HEADER(Standard_Type.hxx,occ_ok=yes ,occ_ok=no) + +fi + +if test "x$occ_ok" = xyes ; then + + AC_MSG_CHECKING(for OpenCascade libraries) + + LIBS_old="$LIBS" + LIBS="$LIBS $CAS_LDPATH -lTKernel" + + AC_CACHE_VAL(salome_cv_lib_occ,[ + AC_TRY_LINK( +#include +, size_t size; + TCollection_AsciiString aStr ("toto"); + aStr.Capitalize();, + eval "salome_cv_lib_occ=yes",eval "salome_cv_lib_occ=no") + ]) + occ_ok="$salome_cv_lib_occ" + +fi +CPPFLAGS="$CPPFLAGS_old" +LIBS="$LIBS_old" + +if test "x$occ_ok" = xno ; then + AC_MSG_RESULT(no) + AC_MSG_WARN(Opencascade libraries not found) +else + AC_MSG_RESULT(yes) + CAS_KERNEL="$CAS_LDPATH -lTKernel" + CAS_MATH="$CAS_LDPATH -lTKMath" + + if test -f $CASROOT/$casdir/lib/libStdPlugin.so ; then + # this libraries are only for CASCADE 5.2.3 + CAS_STDPLUGIN="StdPlugin" + fi + + CAS_OCAF="$CAS_LDPATH -lPTKernel -lTKernel -lTKCDF -lTKLCAF -lTKPCAF -lTKStdSchema" + CAS_OCAFVIS="$CAS_LDPATH -lTKCAF -lStdPlugin -lStdLPlugin -lTKPLCAF -lTKPShape -lTKStdLSchema -lTKShapeSchema" + + CAS_TKV3d="$CAS_LDPATH -lTKV3d" + CAS_VIEWER="$CAS_TKV3d -lTKService" + + CAS_TKBRep="$CAS_LDPATH -lTKG2d -lTKG3d -lTKGeomBase -lTKBRep" + + CAS_TKTopAlgo="$CAS_TKBRep -lTKGeomAlgo -lTKTopAlgo" + CAS_TKPrim="$CAS_TKTopAlgo -lTKPrim" + + CAS_MODELER="$CAS_TKPrim -lTKBO -lTKBool -lTKHLR -lTKFillet -lTKOffset -lTKFeat" + + CAS_DATAEXCHANGE="$CAS_LDPATH -lTKIGES -lTKSTEP" + + CAS_LDFLAGS="$CAS_KERNEL $CAS_MATH $CAS_OCAF $CAS_OCAFVIS $CAS_VIEWER $CAS_MODELER $CAS_DATAEXCHANGE" + +fi + +AC_LANG_RESTORE + +])dnl + + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_corba.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_corba.m4 new file mode 100644 index 000000000..4bdda6df7 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_corba.m4 @@ -0,0 +1,69 @@ +# Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +AC_DEFUN([CHECK_CORBA],[ + +if test x"$DEFAULT_ORB" = x"omniORB" +then + + # Contient le nom de l'ORB + ORB=omniorb + + AC_MSG_RESULT(default orb : omniORB) + IDL=$OMNIORB_IDL + AC_SUBST(IDL) + + CORBA_ROOT=$OMNIORB_ROOT + CORBA_INCLUDES=$OMNIORB_INCLUDES + CORBA_CXXFLAGS=$OMNIORB_CXXFLAGS + CORBA_LIBS=$OMNIORB_LIBS + IDLCXXFLAGS=$OMNIORB_IDLCXXFLAGS + IDLPYFLAGS=$OMNIORB_IDLPYFLAGS + + AC_SUBST(CORBA_ROOT) + AC_SUBST(CORBA_INCLUDES) + AC_SUBST(CORBA_CXXFLAGS) + AC_SUBST(CORBA_LIBS) + AC_SUBST(IDLCXXFLAGS) + AC_SUBST(IDLPYFLAGS) + + IDL_CLN_H=$OMNIORB_IDL_CLN_H + IDL_CLN_CXX=$OMNIORB_IDL_CLN_CXX + IDL_CLN_OBJ=$OMNIORB_IDL_CLN_OBJ + + AC_SUBST(IDL_CLN_H) + AC_SUBST(IDL_CLN_CXX) + AC_SUBST(IDL_CLN_OBJ) + + IDL_SRV_H=$OMNIORB_IDL_SRV_H + IDL_SRV_CXX=$OMNIORB_IDL_SRV_CXX + IDL_SRV_OBJ=$OMNIORB_IDL_SRV_OBJ + + AC_SUBST(IDL_SRV_H) + AC_SUBST(IDL_SRV_CXX) + AC_SUBST(IDL_SRV_OBJ) + +else + AC_MSG_RESULT($DEFAULT_ORB unknown orb) + +fi + +])dnl +dnl diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_hdf5.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_hdf5.m4 new file mode 100644 index 000000000..b20db13ac --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_hdf5.m4 @@ -0,0 +1,88 @@ +# Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +AC_DEFUN([CHECK_HDF5],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl + +AC_CHECKING(for HDF5) + +AC_ARG_WITH(hdf5, + [ --with-hdf5=DIR root directory path to hdf5 installation ], + [HDF5HOME="$withval" + AC_MSG_RESULT("select $withval as path to hdf5") + ]) + +AC_SUBST(HDF5_INCLUDES) +AC_SUBST(HDF5_LIBS) +AC_SUBST(HDF5_MT_LIBS) + +HDF5_INCLUDES="" +HDF5_LIBS="" +HDF5_MT_LIBS="" + +hdf5_ok=no + +LOCAL_INCLUDES="" +LOCAL_LIBS="" + +if test -z $HDF5HOME +then + AC_MSG_WARN(undefined HDF5HOME variable which specify hdf5 installation directory) +else + LOCAL_INCLUDES="-I$HDF5HOME/include" + if test "x$HDF5HOME" = "x/usr" + then + LOCAL_LIBS="" + else + LOCAL_LIBS="-L$HDF5HOME/lib" + fi +fi + +dnl hdf5 headers + +CPPFLAGS_old="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $LOCAL_INCLUDES" +AC_CHECK_HEADER(hdf5.h,hdf5_ok=yes ,hdf5_ok=no) +CPPFLAGS="$CPPFLAGS_old" + + +if test "x$hdf5_ok" = "xyes" +then + +dnl hdf5 library + + LIBS_old="$LIBS" + LIBS="$LIBS $LOCAL_LIBS" + AC_CHECK_LIB(hdf5,H5open,hdf5_ok=yes,hdf5_ok=no) + LIBS="$LIBS_old" + +fi + +if test "x$hdf5_ok" = "xyes" +then + HDF5_INCLUDES="$LOCAL_INCLUDES" + HDF5_LIBS="$LOCAL_LIBS -lhdf5" + HDF5_MT_LIBS="$LOCAL_LIBS -lhdf5" +fi + +AC_MSG_RESULT(for hdf5: $hdf5_ok) + +])dnl diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_med2.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_med2.m4 new file mode 100644 index 000000000..c13888195 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_med2.m4 @@ -0,0 +1,96 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl + +AC_DEFUN([CHECK_MED2],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([CHECK_HDF5])dnl +AC_REQUIRE([AC_DEPEND_FLAG])dnl + +AC_CHECKING(for MED2) + +AC_ARG_WITH(med2, + [ --with-med2=DIR root directory path to med2 installation ], + [MED2HOME="$withval" + AC_MSG_RESULT("select $withval as path to med2") + ]) + +AC_SUBST(MED2_INCLUDES) +AC_SUBST(MED2_LIBS) +AC_SUBST(MED2_MT_LIBS) + +MED2_INCLUDES="" +MED2_LIBS="" +MED2_MT_LIBS="" + +LOCAL_INCLUDES="" +LOCAL_LIBS="" + +med2_ok=no + +dnl check, if there is MED library +if test -z $MED2HOME +then + AC_MSG_WARN(undefined MED2HOME variable which specify med2 installation directory) + AC_PATH_PROG(MDUMP, mdump) + if test "xMDUMP" != "x" ; then + MED2HOME=$MDUMP + MED2HOME=`echo ${MED2HOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + MED2HOME=`echo ${MED2HOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + fi +fi +if test ! -z $MED2HOME +then + LOCAL_INCLUDES="$HDF5_INCLUDES -I$MED2HOME/include" + if test "x$MED2HOME" = "x/usr" + then + LOCAL_LIBS="-lmed $HDF5_LIBS" + else + LOCAL_LIBS="-L$MED2HOME/lib -lmed $HDF5_LIBS" + fi +fi + +dnl check med2 header +CPPFLAGS_old="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS -D$MACHINE $LOCAL_INCLUDES" +AC_CHECK_HEADER(med.h,med2_ok=yes ,med2_ok=no) +CPPFLAGS="$CPPFLAGS_old" + +dnl check med2 library +if test "x$med2_ok" = "xyes" +then + LIBS_old="$LIBS" + LIBS="$LIBS $LOCAL_LIBS" + AC_CHECK_LIB(med,MEDouvrir,med2_ok=yes,med2_ok=no) + LIBS="$LIBS_old" +fi + +if test "x$med2_ok" = "xyes" +then + MED2_INCLUDES="-D$MACHINE $LOCAL_INCLUDES" + MED2_LIBS="$LOCAL_LIBS" + MED2_MT_LIBS="$LOCAL_LIBS" +fi + +AC_MSG_RESULT(for med2: $med2_ok) + +])dnl diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_msg2qm.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_msg2qm.m4 new file mode 100755 index 000000000..8d0c5474f --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_msg2qm.m4 @@ -0,0 +1,57 @@ +# Check availability of Qt's msg2qm tool binary distribution +# +# Author : Jerome Roy (CEA, 2003) +# + +AC_DEFUN([CHECK_MSG2QM],[ + +AC_CHECKING(for msg2qm) + +msg2qm_ok=no + +AC_ARG_WITH(msg2qm, + [ --with-msg2qm=DIR root directory path of MSG2QM installation], + MSG2QM_DIR="$withval",MSG2QM_DIR="") + +if test "x$MSG2QM_DIR" == "x" ; then + +# no --with-MSG2QM-dir option used + + if test "x$MSG2QM_ROOT" != "x" ; then + + # MSG2QM_ROOT environment variable defined + MSG2QM_DIR=$MSG2QM_ROOT + + else + + # search MSG2QM binaries in PATH variable + AC_PATH_PROG(TEMP, msg2qm) + if test "x$TEMP" != "x" ; then + MSG2QM_DIR=`dirname $TEMP` + fi + + fi +# +fi + +# look for msg2qm in ${MSG2QM_DIR} directory +if test -f ${MSG2QM_DIR}/msg2qm ; then + msg2qm_ok=yes + MSG2QM="${MSG2QM_DIR}/msg2qm" + AC_MSG_RESULT(Using MSG2QM executable in ${MSG2QM_DIR}) +else + # if not found, look for msg2qm in ${MSG2QM_DIR}/bin directory + if test -f ${MSG2QM_DIR}/bin/msg2qm ; then + msg2qm_ok=yes + MSG2QM="${MSG2QM_DIR}/bin/msg2qm" + AC_MSG_RESULT(Using MSG2QM executable in ${MSG2QM_DIR}/bin) + else + AC_MSG_WARN("Cannot find MSG2QM executable") + fi +fi + +AC_SUBST(MSG2QM) +AC_MSG_RESULT(for MSG2QM: $msg2qm_ok) + +])dnl + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_omniorb.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_omniorb.m4 new file mode 100644 index 000000000..6b92c8289 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/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) + + ENABLE_PTHREADS + + 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= + + 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/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_opengl.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_opengl.m4 new file mode 100644 index 000000000..8a56e0f54 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_opengl.m4 @@ -0,0 +1,195 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +AC_DEFUN([CHECK_OPENGL],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([AC_LINKER_OPTIONS])dnl + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +AC_ARG_WITH(opengl, + [AC_HELP_STRING([--with-opengl=DIR],[root directory path of OpenGL installation])], + [opengl_dir="$withval"], + [dirs="/usr/lib${LIB_LOCATION_SUFFIX} /usr/local/lib${LIB_LOCATION_SUFFIX} /opt/graphics/OpenGL/lib${LIB_LOCATION_SUFFIX} /usr/openwin/lib${LIB_LOCATION_SUFFIX} /usr/X11R6/lib${LIB_LOCATION_SUFFIX}"])dnl + +AC_CHECKING(for OpenGL) +AC_CHECKING(for OpenGL headers) + +OGL_INCLUDES="" +OGL_LIBS="" + +GL_LIB_PATH="" +GLU_LIB_PATH="" + +OpenGL_ok=no +OpenGL_libs_ok=no +OpenGL_headers_ok=no + +dnl openGL headers +# by default +if test "x${opengl_dir}" != "x" ; then + AC_MSG_RESULT(for opengl_dir: $opengl_dir) + AC_CHECK_HEADER([${opengl_dir}/include/GL/gl.h], + [OpenGL_headers_ok=yes; OGL_INCLUDES="-I${opengl_dir}/include"], + [OpenGL_headers_ok=no]) + if test "x${OpenGL_headers_ok}" = "xyes" ; then + AC_CHECKING(for default OpenGL library) + if test "x${opengl_dir}" = "x/usr" ; then + OGL_LIBS="" + else + OGL_LIBS="-L${opengl_dir}/lib" + fi + LDFLAGS_old="$LDFLAGS" + LDFLAGS="$LDFLAGS $OGL_LIBS" + AC_CHECK_LIB([GL], + [glBegin], + [OpenGL_libs_ok=yes], + [OpenGL_libs_ok=no]) + if test "x${OpenGL_libs_ok}" = "xyes" ; then + AC_TRY_LINK([], + [], + [OpenGL_libs_ok=yes ; OpenGL_ok=yes; OGL_LIBS="$OGL_LIBS -lGL"], + [OpenGL_libs_ok=no]) + fi + LDFLAGS="$LDFLAGS_old" + fi +fi + +if test "x${OpenGL_headers_ok}" = "xno" ; then + AC_CHECK_HEADER(GL/gl.h, + [OpenGL_headers_ok=yes], + [OpenGL_headers_ok=no]) +fi + +# under SunOS ? +if test "x${OpenGL_headers_ok}" = "xno" ; then + AC_CHECK_HEADERS(/usr/openwin/share/include/GL/glxmd.h, + [OpenGL_headers_ok=yes; OGL_INCLUDES="-I/usr/openwin/share/include/"], + [OpenGL_headers_ok=no]) +fi + +# under IRIX ? +if test "x${OpenGL_headers_ok}" = "xno" ; then + AC_CHECK_HEADERS(/opt/graphics/OpenGL/include/GL/glxmd.h, + [OpenGL_headers_ok=yes; OGL_INCLUDES="-I/opt/graphics/OpenGL/include"], + [OpenGL_headers_ok=no]) +fi + +# some linux OpenGL servers hide the includes in /usr/X11R6/include/GL +if test "x${OpenGL_headers_ok}" = "xno" ; then + AC_CHECK_HEADERS(/usr/X11R6/include/GL/gl.h, + [OpenGL_headers_ok=yes; OGL_INCLUDES="-I/usr/X11R6/include"], + [OpenGL_headers_ok=no]) +fi + +if test "x${OpenGL_headers_ok}" = "xyes" ; then + AC_CHECKING(for OpenGL library) + for idir in $dirs; do + if test -r "${idir}/libGL.so"; then + AC_MSG_RESULT(in ${idir}) + if test "x${idir}" = "x/usr/lib${LIB_LOCATION_SUFFIX}" ; then + GL_LIB_PATH="" + else + GL_LIB_PATH="-L${idir}" + fi + break + fi + # under IRIX ? + if test -r "${idir}/libGL.sl"; then + AC_MSG_RESULT(in ${idir}) + if test "x${idir}" = "x/usr/lib${LIB_LOCATION_SUFFIX}" ; then + GL_LIB_PATH="" + else + GL_LIB_PATH="-L${idir}" + fi + break + fi + done + LDFLAGS_old="${LDFLAGS}" + LDFLAGS="${LDFLAGS} ${GL_LIB_PATH}" + AC_CHECK_LIB([GL], + [glBegin], + [OpenGL_libs_ok=yes], + [OpenGL_libs_ok=no]) + if test "x${OpenGL_libs_ok}" = "xyes" ; then + AC_TRY_LINK([], + [], + [OpenGL_libs_ok=yes ; OGL_LIBS="${OGL_LIBS} ${GL_LIB_PATH} -lGL"], + [OpenGL_libs_ok=no]) + fi + LDFLAGS="$LDFLAGS_old" +fi + +if test "x${OpenGL_libs_ok}" = "xyes" ; then + for idir in $dirs; do + if test -r "${idir}/libGLU.so"; then + AC_MSG_RESULT(in ${idir}) + if test "x${idir}" = "x/usr/lib${LIB_LOCATION_SUFFIX}" ; then + GLU_LIB_PATH="" + else + GLU_LIB_PATH="-L${idir}" + fi + break + fi + # under IRIX ? + if test -r "${idir}/libGLU.sl"; then + AC_MSG_RESULT(in ${idir}) + if test "x${idir}" = "x/usr/lib${LIB_LOCATION_SUFFIX}" ; then + GLU_LIB_PATH="" + else + GLU_LIB_PATH="-L${idir}" + fi + break + fi + done + LDFLAGS_old="${LDFLAGS}" + LDFLAGS="${LDFLAGS} ${OGL_LIBS} ${GLU_LIB_PATH}" + AC_CHECK_LIB([GLU], + [gluBeginSurface], + [OpenGL_libs_ok=yes], + [OpenGL_libs_ok=no]) + if test "x${OpenGL_libs_ok}" = "xyes" ; then + AC_TRY_LINK([], + [], + [OpenGL_libs_ok=yes ; OGL_LIBS="${OGL_LIBS} ${GLU_LIB_PATH} -lGLU"], + [OpenGL_libs_ok=no]) + fi + LDFLAGS="$LDFLAGS_old" +fi + +if test "x${OpenGL_headers_ok}" = "xyes" ; then + if test "x${OpenGL_libs_ok}" = "xyes" ; then + OpenGL_ok=yes + fi +fi + +AC_MSG_RESULT(for OpenGL_headers_ok: $OpenGL_headers_ok) +AC_MSG_RESULT(for OpenGL_libs_ok: $OpenGL_libs_ok) +AC_MSG_RESULT(for OpenGL_ok: $OpenGL_ok) + +AC_SUBST(OGL_INCLUDES) +AC_SUBST(OGL_LIBS) + +AC_LANG_RESTORE + +])dnl diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_pthreads.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_pthreads.m4 new file mode 100644 index 000000000..eb511eca3 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_pthreads.m4 @@ -0,0 +1,56 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +#@synonpsis CHECK_PTHREADS +dnl check for pthreads system interfaces. +dnl set CFLAGS_PTHREADS, CXXFLAGS_PTHREADS and LIBS_PTHREADS to +dnl flags to compiler flags for multithread program compilation (if exists), +dnl and library, if one required. +dnl +dnl@author (C) Ruslan Shevchenko , 1998 +dnl@id $Id$ +dnl ---------------------------------------------------------------- +dnl CHECK_PTHREADS +AC_DEFUN([CHECK_PTHREADS],[ +AC_CXX_OPTION(-pthread,CPPFLAGS,flag=yes,flag=no) + +if test $flag = no; then + AC_REQUIRE([AC_CANONICAL_SYSTEM])dnl + AC_CHECK_HEADER(pthread.h,AC_DEFINE(HAVE_PTHREAD_H)) + AC_CHECK_LIB(posix4,nanosleep, LIBS_PTHREADS="-lposix4",LIBS_PTHREADS="") + AC_CHECK_LIB(pthread,pthread_mutex_lock, + LIBS_PTHREADS="-lpthread $LIBS_PTHREADS",LIBS_PTHREADS="") +else + case $host_os in + osf*) + LIBS_PTHREADS="-lpthread $LIBS_PTHREADS" + ;; + esac +fi + +if test $flag = no && test x$LIBS_PTHREADS = x; then + threads_ok=no +else + threads_ok=yes +fi +])dnl +dnl +dnl diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_python.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_python.m4 new file mode 100644 index 000000000..0f3e0cf84 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_python.m4 @@ -0,0 +1,171 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +## ------------------------ +## Python file handling +## From Andrew Dalke +## Modified by Marc Tajchman (06/2001) +## ------------------------ + +dnl CHECK_PYTHON([module, classes]) +dnl +dnl Adds support for distributing Python modules or classes. +dnl Python library files distributed as a `module' are installed +dnl under PYTHON_SITE_PACKAGE (eg, ./python1.5/site-package/package-name) +dnl while those distributed as `classes' are installed under PYTHON_SITE +dnl (eg, ./python1.5/site-packages). The default is to install as +dnl a `module'. + +AC_DEFUN([CHECK_PYTHON], + [ + python_ok=yes + + AC_ARG_WITH(python, + [AC_HELP_STRING([--with-python=DIR],[root directory path of python installation])], + [PYTHON="$withval/bin/python" + AC_MSG_RESULT("select python distribution in $withval") + ], [ + AC_PATH_PROG(PYTHON, python) + ]) + + AC_CHECKING([local Python configuration]) + + AC_REQUIRE([AC_LINKER_OPTIONS])dnl + + PYTHON_PREFIX=`echo $PYTHON | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + PYTHON_PREFIX=`echo $PYTHON_PREFIX | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + PYTHONHOME=$PYTHON_PREFIX + + AC_SUBST(PYTHON_PREFIX) + AC_SUBST(PYTHONHOME) + + changequote(<<, >>)dnl + PYTHON_VERSION=`$PYTHON -c "import sys; print sys.version[:3]"` + changequote([, ])dnl + AC_SUBST(PYTHON_VERSION) + + PY_MAKEFILE=${PYTHON_PREFIX}/lib${LIB_LOCATION_SUFFIX}/python$PYTHON_VERSION/config/Makefile + if test ! -f "$PY_MAKEFILE"; then + AC_MSG_WARN([*** Couldn't find ${PY_MAKEFILE}. Maybe you are +*** missing the development portion of the python installation]) + python_ok=no + fi + + AC_SUBST(PYTHON_INCLUDES) + AC_SUBST(PYTHON_LIBS) + + PYTHON_INCLUDES=-I$PYTHON_PREFIX/include/python$PYTHON_VERSION + PYTHON_LIBS="-L${PYTHON_PREFIX}/lib${LIB_LOCATION_SUFFIX}/python${PYTHON_VERSION}/config -lpython${PYTHON_VERSION}" + PYTHON_LIB=$PYTHON_LIBS + PYTHON_LIBA=${PYTHON_PREFIX}/lib${LIB_LOCATION_SUFFIX}/python$PYTHON_VERSION/config/libpython$PYTHON_VERSION.a + + dnl At times (like when building shared libraries) you may want + dnl to know which OS Python thinks this is. + + AC_SUBST(PYTHON_PLATFORM) + PYTHON_PLATFORM=`$PYTHON -c "import sys; print sys.platform"` + + AC_SUBST(PYTHON_SITE) + AC_ARG_WITH(python-site, + [AC_HELP_STRING([--with-python-site=DIR], + [Use DIR for installing platform independent Python site-packages])], + +dnl modification : by default, we install python script in salome root tree + +dnl [PYTHON_SITE="$withval" +dnl python_site_given=yes], +dnl [PYTHON_SITE=$PYTHON_PREFIX"/lib/python"$PYTHON_VERSION/site-packages +dnl python_site_given=no] + + [PYTHON_SITE="$withval" + python_site_given=yes], + [PYTHON_SITE=${prefix}"/lib${LIB_LOCATION_SUFFIX}/python"${PYTHON_VERSION}/site-packages + python_site_given=no]) + + AC_SUBST(PYTHON_SITE_PACKAGE) + PYTHON_SITE_PACKAGE=$PYTHON_SITE/$PACKAGE + + + dnl Get PYTHON_SITE from --with-python-site-exec or from + dnl --with-python-site or from running Python + + AC_SUBST(PYTHON_SITE_EXEC) + AC_ARG_WITH(python-site-exec, + [AC_HELP_STRING([--with-python-site-exec=DIR], + [Use DIR for installing platform dependent Python site-packages])], + [PYTHON_SITE_EXEC="$withval"], + [if test "$python_site_given" = yes; then + PYTHON_SITE_EXEC=$PYTHON_SITE + else + PYTHON_SITE_EXEC=${PYTHON_EXEC_PREFIX}"/lib${LIB_LOCATION_SUFFIX}/python"${PYTHON_VERSION}/site-packages + fi]) + + dnl Set up the install directory + ifelse($1, classes, +[PYTHON_SITE_INSTALL=$PYTHON_SITE], +[PYTHON_SITE_INSTALL=$PYTHON_SITE_PACKAGE]) + AC_SUBST(PYTHON_SITE_INSTALL) + + dnl Also lets automake think PYTHON means something. + + pythondir=${PYTHON_PREFIX}"/lib${LIB_LOCATION_SUFFIX}/python"${PYTHON_VERSION}/ + AC_SUBST(pythondir) + + AC_MSG_CHECKING([if we need libdb]) + PY_NEEDOPENDB=`nm $PYTHON_LIBA | grep dbopen | grep U` + if test "x$PY_NEEDOPENDB" != "x"; then + AC_MSG_RESULT(yes) + AC_CHECK_LIB(db,dbopen,PYTHON_LIBS="$PYTHON_LIBS -ldb",db_ok=no) + else + AC_MSG_RESULT(no) + fi + + AC_MSG_CHECKING([if we need libdl]) + PY_NEEDOPENDL=`nm $PYTHON_LIBA | grep dlopen | grep U` + if test "x$PY_NEEDOPENDL" != "x"; then + AC_MSG_RESULT(yes) + AC_CHECK_LIB(dl,dlopen,PYTHON_LIBS="$PYTHON_LIBS -ldl",dl_ok=no) + else + AC_MSG_RESULT(no) + fi + + AC_MSG_CHECKING([if we need libutil]) + PY_NEEDOPENPTY=`nm $PYTHON_LIBA | grep openpty | grep U` + if test "x$PY_NEEDOPENPTY" != "x"; then + AC_MSG_RESULT(yes) + AC_CHECK_LIB(util,openpty,PYTHON_LIBS="$PYTHON_LIBS -lutil",openpty_ok=no) + else + AC_MSG_RESULT(no) + fi + + AC_MSG_CHECKING([if we need tcltk]) + PY_NEEDTCLTK=`nm $PYTHON_LIBA | grep Tcl_Init | grep U` + if test "x$PY_NEEDTCLTK" != "x"; then + AC_MSG_RESULT(yes) + AC_CHECK_LIB(tcl,Tcl_Init,PYTHON_LIBS="$PYTHON_LIBS -ltcl -ltk",tclinit_ok=no) + else + AC_MSG_RESULT(no) + fi + + if test "$python_ok" == "yes"; then + AC_MSG_RESULT(looks good) + fi +]) diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_qt.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_qt.m4 new file mode 100644 index 000000000..ab5348319 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/check_qt.m4 @@ -0,0 +1,182 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl + +AC_DEFUN([CHECK_QT],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CXX])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([AC_PROG_CXXCPP])dnl +AC_REQUIRE([CHECK_OPENGL])dnl +AC_REQUIRE([AC_LINKER_OPTIONS])dnl + +AC_CHECKING(for Qt) + +if test "x$OpenGL_ok" != "xyes" ; then + AC_MSG_WARN(Qt needs OpenGL correct configuration, check configure output) +fi + +qt_ok=yes + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +if test "x$QTDIR" = "x" +then + AC_MSG_RESULT(please define QTDIR variable) + qt_ok=no +else + AC_MSG_RESULT(QTDIR is $QTDIR) + qt_inc_ok=no + QTINC="" + AC_CHECK_FILE(${QTDIR}/include/qt3/qglobal.h,QTINC="/qt3",QTINC="") + QT_VERS=`grep "QT_VERSION_STR" ${QTDIR}/include${QTINC}/qglobal.h | sed -e 's%^#define QT_VERSION_STR\([[:space:]]*\)%%g' -e 's%\"%%g'` + AC_MSG_RESULT(Qt version is $QT_VERS) + QT_VERS="Qt_"`echo $QT_VERS | sed -e 's%\"%%g' -e 's%\.%_%g'` +fi + +if test "x$qt_ok" = "xyes" +then + if test -f ${QTDIR}/bin/moc + then + MOC=${QTDIR}/bin/moc + else + AC_PATH_PROG(MOC, moc) + fi + if test "x$MOC" = "x" + then + qt_ok=no + AC_MSG_RESULT(moc qt-compiler not in PATH variable) + else + qt_ok=yes + AC_MSG_RESULT(moc found) + fi +fi + +if test "x$qt_ok" = "xyes" +then + if test -f ${QTDIR}/bin/uic + then + UIC=${QTDIR}/bin/uic + else + AC_PATH_PROG(UIC, uic) + fi + if test "x$UIC" = "x" + then + qt_ok=no + AC_MSG_RESULT(uic qt-interface compiler not in PATH variable) + else + qt_ok=yes + AC_MSG_RESULT(uic found) + fi +fi + +AC_SUBST(QTDIR) +QT_ROOT=$QTDIR + +if test "x$qt_ok" = "xyes" +then + CPPFLAGS_old=$CPPFLAGS + CPPFLAGS="$CPPFLAGS -I$QTDIR/include${QTINC}" + + AC_LANG_CPLUSPLUS + AC_CHECK_HEADER(qaction.h,qt_ok=yes ,qt_ok=no) + + CPPFLAGS=$CPPFLAGS_old + + AC_MSG_CHECKING(include of qt headers) + + if test "x$qt_ok" = "xno" + then + AC_MSG_RESULT(qt headers not found, or too old qt version, in $QTDIR/include) + AC_MSG_RESULT(QTDIR environment variable may be wrong) + else + AC_MSG_RESULT(yes) + QT_INCLUDES="-I${QT_ROOT}/include${QTINC} -DQT_THREAD_SUPPORT -DQT_CLEAN_NAMESPACE" + QT_MT_INCLUDES="-I${QT_ROOT}/include${QTINC} -DQT_THREAD_SUPPORT -DQT_CLEAN_NAMESPACE" + fi +fi + +if test "x$qt_ok" = "xyes" +then + AC_MSG_CHECKING(linking qt library) + LIBS_old=$LIBS + if test "x$QTDIR" = "x/usr" + then + LIBS="$LIBS -lqt-mt $OGL_LIBS" + else + LIBS="$LIBS -L$QTDIR/lib${LIB_LOCATION_SUFFIX} -lqt-mt $OGL_LIBS" + fi + + CXXFLAGS_old=$CXXFLAGS + CXXFLAGS="$CXXFLAGS $QT_INCLUDES" + + AC_CACHE_VAL(salome_cv_lib_qt,[ + AC_TRY_LINK( +#include +, int n; + char **s; + QApplication a(n, s); + a.exec();, + eval "salome_cv_lib_qt=yes",eval "salome_cv_lib_qt=no") + ]) + qt_ok="$salome_cv_lib_qt" + + if test "x$qt_ok" = "xno" + then + AC_MSG_RESULT(unable to link with qt library) + AC_MSG_RESULT(QTDIR environment variable may be wrong) + else + AC_MSG_RESULT(yes) + if test "x$QTDIR" = "x/usr" + then + QT_LIBS=" -lqt-mt" + QT_MT_LIBS=" -lqt-mt" + else + QT_LIBS="-L$QTDIR/lib${LIB_LOCATION_SUFFIX} -lqt-mt" + QT_MT_LIBS="-L$QTDIR/lib${LIB_LOCATION_SUFFIX} -lqt-mt" + fi + fi + + LIBS=$LIBS_old + CXXFLAGS=$CXXFLAGS_old + +fi + +AC_SUBST(MOC) +AC_SUBST(UIC) + +AC_SUBST(QT_ROOT) +AC_SUBST(QT_INCLUDES) +AC_SUBST(QT_MT_INCLUDES) +AC_SUBST(QT_LIBS) +AC_SUBST(QT_MT_LIBS) +AC_SUBST(QT_VERS) + +AC_LANG_RESTORE + +AC_MSG_RESULT(for Qt: $qt_ok) + +# Save cache +AC_CACHE_SAVE + +])dnl +dnl diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/enable_pthreads.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/enable_pthreads.m4 new file mode 100644 index 000000000..45652fbb5 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/enable_pthreads.m4 @@ -0,0 +1,41 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl@synopsis ENABLE_PTHREADS +dnl +dnl modify CFLAGS, CXXFLAGS and LIBS for compiling pthread-based programs. +dnl +dnl@author (C) Ruslan Shevchenko , 1998, 2000 +dnl@id $Id$ +dnl +dnl +AC_DEFUN([ENABLE_PTHREADS],[ +AC_REQUIRE([CHECK_PTHREADS]) + +if test -z "$enable_pthreads_done" +then + CFLAGS="$CFLAGS $CFLAGS_PTHREADS" + CXXFLAGS="$CXXFLAGS $CXXFLAGS_PTHREADS" + LIBS="$LIBS $LIBS_PTHREADS" +fi +enable_pthreads_done=yes +])dnl +dnl diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/production.m4 b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/production.m4 new file mode 100644 index 000000000..8157d677d --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/config_files/production.m4 @@ -0,0 +1,106 @@ +dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl +dnl +dnl +dnl define macros : +dnl AC_ENABLE_PRODUCTION AC_DISABLE_PRODUCTION +dnl and +dnl AC_ENABLE_DEBUG AC_DISABLE_DEBUG +dnl +dnl version $Id$ +dnl author Patrick GOLDBRONN +dnl + +# AC_ENABLE_PRODUCTION +AC_DEFUN([AC_ENABLE_PRODUCTION], [dnl +define([AC_ENABLE_PRODUCTION_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(production, +changequote(<<, >>)dnl +<< --enable-production[=PKGS] build without debug information [default=>>AC_ENABLE_PRODUCTION_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_production=yes ;; +no) enable_production=no ;; +*) + enable_production=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_production=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_production=AC_ENABLE_PRODUCTION_DEFAULT)dnl + +AC_CXX_OPTION(-Wno-deprecated,CXXFLAGS) +AC_CXX_OPTION(-Wparentheses,CXXFLAGS) +AC_CXX_OPTION(-Wreturn-type,CXXFLAGS) +AC_CXX_OPTION(-Wmissing-declarations,CXXFLAGS) +AC_CXX_OPTION(-fmessage-length=0,CXXFLAGS) +AC_CXX_OPTION(-Wunused,CXXFLAGS) +AC_CXX_OPTION(-pipe,CXXFLAGS) + +if test "X$enable_production" = "Xyes"; then + CFLAGS="$CFLAGS -O" + AC_CXX_OPTION(-Wuninitialized,CXXFLAGS) + CXXFLAGS="$CXXFLAGS -O " +fi +]) + +# AC_DISABLE_PRODUCTION - set the default flag to --disable-production +AC_DEFUN([AC_DISABLE_PRODUCTION], [AC_ENABLE_PRODUCTION(no)]) + +# AC_ENABLE_DEBUG +AC_DEFUN([AC_ENABLE_DEBUG], [dnl +define([AC_ENABLE_DEBUG_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(debug, +changequote(<<, >>)dnl +<< --enable-debug[=PKGS] build without debug information [default=>>AC_ENABLE_DEBUG_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_debug=yes ;; +no) enable_debug=no ;; +*) + enable_debug=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_debug=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_debug=AC_ENABLE_DEBUG_DEFAULT)dnl + +if test "X$enable_debug" = "Xyes"; then + CFLAGS="$CFLAGS -g -D_DEBUG_ " + CXXFLAGS="$CXXFLAGS -g -D_DEBUG_ " +fi +]) + +# AC_DISABLE_DEBUG - set the default flag to --disable-debug +AC_DEFUN([AC_DISABLE_DEBUG], [AC_ENABLE_DEBUG(no)]) \ No newline at end of file diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_begin.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_begin.am new file mode 100755 index 000000000..eeec91183 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_begin.am @@ -0,0 +1,2 @@ + +EXTRA_DIST = $(wildcard $(srcdir)/*.hxx) $(wildcard $(srcdir)/*.h) diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_common_starter.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_common_starter.am new file mode 100644 index 000000000..ae08dbd56 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_common_starter.am @@ -0,0 +1,30 @@ +# +# ============================================================ +# This file defines the common definitions used in several +# Makefile. This file must be included, if needed, by the file +# Makefile.am. +# ============================================================ +# + +# Standard directory for installation +salomeincludedir = $(includedir)/@PACKAGE@ +libdir = $(prefix)/lib@LIB_LOCATION_SUFFIX@/@PACKAGE@ +bindir = $(prefix)/bin/@PACKAGE@ +salomescriptdir = $(bindir) + +# Directory for installing idl files +salomeidldir = $(prefix)/idl/@PACKAGE@ + +# Directory for installing resource files +salomeresdir = $(prefix)/share/@PACKAGE@/resources + +# Directories for installing admin files +salomeadmdir = $(prefix)/adm_local +salomeadmuxdir = $(salomeadmdir)/unix +salomem4dir = $(salomeadmdir)/unix/config_files + +# Shared modules installation directory +sharedpkgpythondir =$(pkgpythondir)/shared_modules + +# Documentation directory +docdir = $(datadir)/doc/@PACKAGE@ diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_end.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_end.am new file mode 100755 index 000000000..f489128d8 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/make_end.am @@ -0,0 +1,24 @@ + +SUFFIXES = + +# -------------------------------------------- +# *.i --> *wrap.cxx +# -------------------------------------------- + +SUFFIXES += .i WRAP.cxx .idl .hh SK.cc _idl.py + +%WRAP.cxx : %.i + $(SWIG) $(SWIG_PYTHON_OPT) $(SWIG_PYTHON_INCLUDES) -o $@ $< + + +%.hh %SK.cc: %.idl + $(OMNIORB_IDL) $(OMNIORB_IDLCXXFLAGS) -bcxx $< + +%.hh %SK.cc: ${KERNEL_ROOT_DIR}/idl/salome/%.idl + $(OMNIORB_IDL) $(OMNIORB_IDLCXXFLAGS) -bcxx $< + +%.hh %SK.cc: ${MED_ROOT_DIR}/idl/salome/%.idl + $(OMNIORB_IDL) $(OMNIORB_IDLCXXFLAGS) -bcxx $< + +%_idl.py: %.idl + $(OMNIORB_IDL) $(OMNIORB_IDLPYFLAGS) -bpython $< diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/py-compile b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/py-compile new file mode 100755 index 000000000..f5d4fdc58 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/adm_local/unix/py-compile @@ -0,0 +1,113 @@ +#!/bin/sh +# py-compile - Compile a Python program + +scriptversion=2004-01-12.23 + +# Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +if [ -z "$PYTHON" ]; then + PYTHON=python +fi + +basedir= + +case "$1" in + --basedir) + basedir=$2 + if test -z "$basedir"; then + echo "$0: Missing argument to --basedir." 1>&2 + exit 1 + fi + shift 2 + ;; + -h|--h*) + cat <<\EOF +Usage: py-compile [--help] [--version] [--basedir DIR] FILES..." + +Byte compile some python scripts FILES. This should be performed +after they have been moved to the final installation location + +Report bugs to . +EOF + exit 0 + ;; + -v|--v*) + echo "py-compile $scriptversion" + exit 0 + ;; +esac + +if [ $# = 0 ]; then + echo "$0: No files given. Try \`$0 --help' for more information." 1>&2 + exit 1 +fi + +# if basedir was given, then it should be prepended to filenames before +# byte compilation. +if [ -z "$basedir" ]; then + trans="path = file" +else + trans="path = os.path.join('$basedir', file)" +fi + +$PYTHON -c " +import sys, os, string, py_compile + +files = '''$*''' +print 'Byte-compiling python modules...' +for file in string.split(files): + $trans + if not os.path.exists(path) or not (len(path) >= 3 and path[-3:] == '.py'): + continue + print file, + sys.stdout.flush() + py_compile.compile(path) +print" || exit $? + +# this will fail for python < 1.5, but that doesn't matter ... +$PYTHON -O -c " +import sys, os, string, py_compile + +files = '''$*''' +print 'Byte-compiling python modules (optimized versions) ...' +for file in string.split(files): + $trans + if not os.path.exists(path) or not (len(path) >= 3 and path[-3:] == '.py'): + continue + print file, + sys.stdout.flush() + py_compile.compile(path) +print" 2>/dev/null || : + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/Makefile.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/Makefile.am new file mode 100644 index 000000000..e69de29bb diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/VERSION b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/VERSION new file mode 100755 index 000000000..1c4649487 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/VERSION @@ -0,0 +1,2 @@ +SALOME 2 EXEMPLE MODULE C++ : HXX2SALOME_GENERIC_CLASS_NAME +This module works with KERNEL 1.2.1 diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runAppli.in b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runAppli.in new file mode 100755 index 000000000..38d2d74d1 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runAppli.in @@ -0,0 +1,8 @@ +#!/bin/sh + +export KERNEL_ROOT_DIR=@KERNEL_ROOT_DIR@ +export PYHXX2SALOME_GENERIC_CLASS_NAME_ROOT_DIR=@prefix@ + +python -i $HXX2SALOME_GENERIC_CLASS_NAME_ROOT_DIR/bin/salome/runSalome.py --modules=HXX2SALOME_GENERIC_CLASS_NAME --xterm --containers=cpp,python --killall + + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runSalome.py b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runSalome.py new file mode 100755 index 000000000..d270554f7 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/bin/runSalome.py @@ -0,0 +1,506 @@ +#!/usr/bin/env python + +usage="""USAGE: runSalome.py [options] + +[command line options] : +--help : affichage de l'aide +--gui : lancement du GUI +--logger : redirection des messages dans un fichier +--xterm : les serveurs ouvrent une fenêtre xterm et les messages sont affichés dans cette fenêtre +--modules=module1,module2,... : où modulen est le nom d'un module Salome à charger dans le catalogue +--containers=cpp,python,superv: lancement des containers cpp, python et de supervision +--killall : arrêt des serveurs de salome + + La variable d'environnement _ROOT_DIR doit etre préalablement + positionnée (modulen doit etre en majuscule). + KERNEL_ROOT_DIR est obligatoire. +""" + +# ----------------------------------------------------------------------------- +# +# Fonction d'arrêt de salome +# + +def killSalome(): + print "arret des serveurs SALOME" + for pid, cmd in process_id.items(): + print "arret du process %s : %s"% (pid, cmd[0]) + try: + os.kill(pid,signal.SIGKILL) + except: + print " ------------------ process %s : %s inexistant"% (pid, cmd[0]) + print "arret du naming service" + os.system("killall -9 omniNames") + +# ----------------------------------------------------------------------------- +# +# Fonction message +# + +def message(code, msg=''): + if msg: print msg + sys.exit(code) + +import sys,os,string,glob,time,signal,pickle,getopt + +init_time=os.times() +opts, args=getopt.getopt(sys.argv[1:], 'hmglxck:', ['help','modules=','gui','logger','xterm','containers=','killall']) +modules_root_dir={} +process_id={} +liste_modules={} +liste_containers={} +with_gui=0 +with_logger=0 +with_xterm=0 + +with_container_cpp=0 +with_container_python=0 +with_container_superv=0 + +try: + for o, a in opts: + if o in ('-h', '--help'): + print usage + sys.exit(1) + elif o in ('-g', '--gui'): + with_gui=1 + elif o in ('-l', '--logger'): + with_logger=1 + elif o in ('-x', '--xterm'): + with_xterm=1 + elif o in ('-m', '--modules'): + liste_modules = [x.upper() for x in a.split(',')] + elif o in ('-c', '--containers'): + liste_containers = [x.lower() for x in a.split(',')] + for r in liste_containers: + if r not in ('cpp', 'python', 'superv'): + message(1, 'Invalid -c/--containers option: %s' % a) + if 'cpp' in liste_containers: + with_container_cpp=1 + else: + with_container_cpp=0 + if 'python' in liste_containers: + with_container_python=1 + else: + with_container_python=0 + if 'superv' in liste_containers: + with_container_superv=1 + else: + with_container_superv=0 + elif o in ('-k', '--killall'): + filedict='/tmp/'+os.getenv('USER')+'_SALOME_pidict' + #filedict='/tmp/'+os.getlogin()+'_SALOME_pidict' + found = 0 + try: + fpid=open(filedict, 'r') + found = 1 + except: + print "le fichier %s des process SALOME n'est pas accessible"% filedict + + if found: + process_id=pickle.load(fpid) + fpid.close() + killSalome() + process_id={} + os.remove(filedict) + +except getopt.error, msg: + print usage + sys.exit(1) + +# ----------------------------------------------------------------------------- +# +# Vérification des variables d'environnement +# +try: + kernel_root_dir=os.environ["KERNEL_ROOT_DIR"] + modules_root_dir["KERNEL"]=kernel_root_dir +except: + print usage + sys.exit(1) + +for module in liste_modules : + try: + module=module.upper() + module_root_dir=os.environ[module +"_ROOT_DIR"] + modules_root_dir[module]=module_root_dir + except: + print usage + sys.exit(1) + +# il faut KERNEL en premier dans la liste des modules +# - l'ordre des modules dans le catalogue sera identique +# - la liste des modules presents dans le catalogue est exploitée pour charger les modules CORBA python, +# il faut charger les modules python du KERNEL en premier + +if "KERNEL" in liste_modules:liste_modules.remove("KERNEL") +liste_modules[:0]=["KERNEL"] +#print liste_modules +#print modules_root_dir + +os.environ["SALOMEPATH"]=":".join(modules_root_dir.values()) +if "SUPERV" in liste_modules:with_container_superv=1 + + +# ----------------------------------------------------------------------------- +# +# Définition des classes d'objets pour le lancement des Server CORBA +# + +class Server: + CMD=[] + if with_xterm: + ARGS=['xterm', '-iconic', '-sb', '-sl', '500', '-e'] + else: + ARGS=[] + + def run(self): + args = self.ARGS+self.CMD + #print "args = ", args + pid = os.spawnvp(os.P_NOWAIT, args[0], args) + process_id[pid]=self.CMD + +class CatalogServer(Server): + SCMD1=['SALOME_ModuleCatalog_Server','-common'] + SCMD2=['-personal','${HOME}/Salome/resources/CatalogModulePersonnel.xml'] + + def setpath(self,liste_modules): + cata_path=[] + for module in liste_modules: + module_root_dir=modules_root_dir[module] + module_cata=module+"Catalog.xml" + print " ", module_cata + cata_path.extend(glob.glob(os.path.join(module_root_dir,"share","salome","resources",module_cata))) + self.CMD=self.SCMD1 + [string.join(cata_path,':')] + self.SCMD2 + +class SalomeDSServer(Server): + CMD=['SALOMEDS_Server'] + +class RegistryServer(Server): + CMD=['SALOME_Registry_Server', '--salome_session','theSession'] + +class ContainerCPPServer(Server): + CMD=['SALOME_Container','FactoryServer','-ORBInitRef','NameService=corbaname::localhost'] + +class ContainerPYServer(Server): + CMD=['SALOME_ContainerPy.py','FactoryServerPy','-ORBInitRef','NameService=corbaname::localhost'] + +class ContainerSUPERVServer(Server): + CMD=['SALOME_Container','SuperVisionContainer','-ORBInitRef','NameService=corbaname::localhost'] + +class LoggerServer(Server): + CMD=['SALOME_Logger_Server', 'logger.log'] + +class SessionLoader(Server): + CMD=['SALOME_Session_Loader'] + if with_container_cpp: + CMD=CMD+['CPP'] + if with_container_python: + CMD=CMD+['PY'] + if with_container_superv: + CMD=CMD+['SUPERV'] + if with_gui: + CMD=CMD+['GUI'] + +class SessionServer(Server): + CMD=['SALOME_Session_Server'] + +class NotifyServer(Server): + CMD=['notifd','-c','${KERNEL_ROOT_DIR}/share/salome/resources/channel.cfg -DFactoryIORFileName=/tmp/${LOGNAME}_rdifact.ior -DChannelIORFileName=/tmp/${LOGNAME}_rdichan.ior'] + +# ----------------------------------------------------------------------------- +# +# Fonction de test +# + +def test(clt): + """ + Test function that creates an instance of HXX2SALOME_GENERIC_CLASS_NAME component + usage : hello=test(clt) + """ + # create an LifeCycleCORBA instance + import LifeCycleCORBA + lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb) + import HXX2SALOME_GENERIC_CLASS_NAME_ORB + hello = lcc.FindOrLoadComponent("FactoryServer", "HXX2SALOME_GENERIC_CLASS_NAME") + return hello + +# ----------------------------------------------------------------------------- +# +# Fonctions helper pour ajouter des variables d'environnement +# + +def add_path(directory): + os.environ["PATH"]=directory + ":" + os.environ["PATH"] + +def add_ld_library_path(directory): + os.environ["LD_LIBRARY_PATH"]=directory + ":" + os.environ["LD_LIBRARY_PATH"] + +def add_python_path(directory): + os.environ["PYTHONPATH"]=directory + ":" + os.environ["PYTHONPATH"] + sys.path[:0]=[directory] + +# ----------------------------------------------------------------------------- +# +# initialisation des variables d'environnement +# + +python_version="python%d.%d" % sys.version_info[0:2] + +# +# Ajout du chemin d'acces aux executables de KERNEL dans le PATH +# + +add_path(os.path.join(kernel_root_dir,"bin","salome")) +#print "PATH=",os.environ["PATH"] + +# +# Ajout des modules dans le LD_LIBRARY_PATH +# +for module in liste_modules: + module_root_dir=modules_root_dir[module] + add_ld_library_path(os.path.join(module_root_dir,"lib","salome")) +#print "LD_LIBRARY_PATH=",os.environ["LD_LIBRARY_PATH"] + +# +# Ajout des modules dans le PYTHONPATH (KERNEL prioritaire, donc en dernier) +# + +liste_modules_reverse=liste_modules[:] +liste_modules_reverse.reverse() +#print liste_modules +#print liste_modules_reverse +for module in liste_modules_reverse: + module_root_dir=modules_root_dir[module] + add_python_path(os.path.join(module_root_dir,"bin","salome")) + add_python_path(os.path.join(module_root_dir,"lib",python_version,"site-packages","salome")) + add_python_path(os.path.join(module_root_dir,"lib","salome")) + add_python_path(os.path.join(module_root_dir,"lib",python_version,"site-packages","salome","shared_modules")) + +#print "PYTHONPATH=",sys.path + +import orbmodule + +# +# ----------------------------------------------------------------------------- +# + +def startGUI(): + import SALOME + session=clt.waitNS("/Kernel/Session",SALOME.Session) + + # + # Activation du GUI de Session Server + # + + session.GetInterface() + +# +# ----------------------------------------------------------------------------- +# + +def startSalome(): + + # + # Lancement Session Loader + # + SessionLoader().run() + + # + # Initialisation ORB et Naming Service + # + clt=orbmodule.client() + + # (non obligatoire) Lancement Logger Server et attente de sa + # disponibilite dans le naming service + # + if with_logger: + LoggerServer().run() + clt.waitLogger("Logger") + + # + # Lancement Registry Server + # + RegistryServer().run() + + # + # Attente de la disponibilité du Registry dans le Naming Service + # + clt.waitNS("/Registry") + + # + # Lancement Catalog Server + # + cataServer=CatalogServer() + cataServer.setpath(liste_modules) + cataServer.run() + + # + # Attente de la disponibilité du Catalog Server dans le Naming Service + # + import SALOME_ModuleCatalog + clt.waitNS("/Kernel/ModulCatalog",SALOME_ModuleCatalog.ModuleCatalog) + + # + # Lancement SalomeDS Server + # + os.environ["CSF_PluginDefaults"]=os.path.join(kernel_root_dir,"share","salome","resources") + os.environ["CSF_SALOMEDS_ResourcesDefaults"]=os.path.join(kernel_root_dir,"share","salome","resources") + SalomeDSServer().run() + + if "GEOM" in liste_modules: + print "GEOM OCAF Resources" + os.environ["CSF_GEOMDS_ResourcesDefaults"]=os.path.join(modules_root_dir["GEOM"],"share","salome","resources") + + + # + # Attente de la disponibilité du SalomeDS dans le Naming Service + # + clt.waitNS("/myStudyManager") + + # + # Lancement Session Server + # + SessionServer().run() + + # + # Attente de la disponibilité du Session Server dans le Naming Service + # + import SALOME + session=clt.waitNS("/Kernel/Session",SALOME.Session) + + # + # Lancement containers + # + theComputer = os.getenv("HOSTNAME") + theComputer = theComputer.split('.')[0] + + # + # Lancement Container C++ local + # + if with_container_cpp: + ContainerCPPServer().run() + # + # Attente de la disponibilité du Container C++ local + # dans le Naming Service + # + clt.waitNS("/Containers/" + theComputer + "/FactoryServer") + # + # Lancement Container Python local + # + if with_container_python: + ContainerPYServer().run() + # + # Attente de la disponibilité du Container Python local + # dans le Naming Service + # + clt.waitNS("/Containers/" + theComputer + "/FactoryServerPy") + + if with_container_superv: + # + # Lancement Container Supervision local + # + ContainerSUPERVServer().run() + # + # Attente de la disponibilité du Container Supervision local + # dans le Naming Service + # + clt.waitNS("/Containers/" + theComputer + "/SuperVisionContainer") + # + # Activation du GUI de Session Server + # + #session.GetInterface() + + end_time = os.times() + print + print "Start SALOME, elpased time : %5.1f seconds"% (end_time[4] - init_time[4]) + + return clt + +# +# ----------------------------------------------------------------------------- +# + +if __name__ == "__main__": + clt=None + try: + clt = startSalome() + except: + print + print + print "--- erreur au lancement Salome ---" + + #print process_id + + + filedict='/tmp/'+os.getenv('USER')+'_SALOME_pidict' + #filedict='/tmp/'+os.getlogin()+'_SALOME_pidict' + + fpid=open(filedict, 'w') + pickle.dump(process_id,fpid) + fpid.close() + + print """ + +Sauvegarde du dictionnaire des process dans , %s +Pour tuer les process SALOME, executer : python killSalome.py depuis +une console, ou bien killSalome() depuis le present interpreteur, +s'il n'est pas fermé. + +runSalome, avec l'option --killall, commence par tuer les process restants +d'une execution précédente. + +Pour lancer uniquement le GUI, executer startGUI() depuis le present interpreteur, +s'il n'est pas fermé. + +""" % filedict + + # + # Impression arborescence Naming Service + # + + if clt != None: + print + print " --- registered objects tree in Naming Service ---" + clt.showNS() + session=clt.waitNS("/Kernel/Session") + catalog=clt.waitNS("/Kernel/ModulCatalog") + import socket + container = clt.waitNS("/Containers/" + socket.gethostname().split('.')[0] + "/FactoryServerPy") + + if os.path.isfile("~/.salome/pystartup"): + f=open(os.path.expanduser("~/.salome/pystartup"),'w') + PYTHONSTARTUP=f.read() + f.close() + else: + PYTHONSTARTUP=""" +# Add auto-completion and a stored history file of commands to your Python +# interactive interpreter. Requires Python 2.0+, readline. Autocomplete is +# bound to the TAB key by default (you can change it - see readline docs). +# +# Store the history in ~/.salome/pyhistory, +# +import atexit +import os +import readline +import rlcompleter +readline.parse_and_bind('tab: complete') + +historyPath = os.path.expanduser("~/.salome/pyhistory") + +def save_history(historyPath=historyPath): + import readline + readline.write_history_file(historyPath) + +if os.path.exists(historyPath): + readline.read_history_file(historyPath) + +atexit.register(save_history) +del os, atexit, readline, rlcompleter, save_history, historyPath +""" + f=open(os.path.expanduser("~/.salome/pystartup"),'w') + f.write(PYTHONSTARTUP) + f.close() + + exec PYTHONSTARTUP in {} + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/build_configure b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/build_configure new file mode 100755 index 000000000..1adfbbe12 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/build_configure @@ -0,0 +1,63 @@ +#! /bin/sh + +# -- +# +PROJECT="HXX2SALOME_GENERIC_CLASS_NAMEComponent" + +# -- +# set VERSION from CVS_TAG_NAME + +CVS_TAG_NAME='$Name$' +VERSION=${CVS_TAG_NAME} +VERSION=`echo ${VERSION/'$Name:'/}` +VERSION=`echo ${VERSION/'$'/}` +if test X$VERSION = X ; then + VERSION=`date +"%F"` # -%H-%M +else + VERSION=`echo $VERSION | sed -e "s/V_//g"` + VERSION=`echo $VERSION | sed -e "s/_/./g"` +fi + +# -- +ORIG_DIR=`pwd` +run() { + local logfile=$ORIG_DIR/build_configure.log + printf "%-50s" "$1 ... " + echo $* > $logfile + eval $* >> $logfile 2>&1 + if test $? != 0 ; then + echo "[FAILED]" + echo "see file build_configure.log ..." + exit 1 + fi + echo "[ OK ]" +} + +# -- +# -- goto build_configure dir +CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` +cd ${CONF_DIR} +CONF_DIR=`pwd` + +# -- +# -- list all Makefile.am in Makefile.am.list +./rfind . Makefile.am > Makefile.am.list + +# -- +# -- configure.in construction +rm -f configure.in +touch configure.in +echo "AC_INIT($PROJECT, $VERSION)" >> configure.in +echo "RELEASE=$VERSION" >> configure.in +echo "PROJECT=$PROJECT" >> configure.in +sed -e "s?\${KERNEL_ROOT_DIR}?${KERNEL_ROOT_DIR}?" configure.in.base >> configure.in +echo "AC_OUTPUT([ \\" >> configure.in +sed -e 's,\.am, \\,' -e 's,\.\/,,' Makefile.am.list >> configure.in +echo " adm_local/unix/SALOMEconfig.h \\" >> configure.in +echo "])" >> configure.in + +# -- +run "libtoolize" +run "aclocal" "-I ${CONF_DIR}/adm_local/unix/config_files" "--verbose >& x" +run "autoconf" +run "automake" "--add-missing" "--copy" diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/configure.in.base b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/configure.in.base new file mode 100644 index 000000000..128f4335e --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/configure.in.base @@ -0,0 +1,289 @@ + +AM_INIT_AUTOMAKE +AC_CANONICAL_HOST + +PACKAGE=salome +AC_SUBST(PACKAGE) + +VERSION=1.2.1 +AC_SUBST(VERSION) + +dnl +dnl Initialize source and build root directories +dnl + +ROOT_BUILDDIR=`pwd` +ROOT_SRCDIR=`echo $0 | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` +cd $ROOT_SRCDIR +ROOT_SRCDIR=`pwd` +cd $ROOT_BUILDDIR + +AC_SUBST(ROOT_SRCDIR) +AC_SUBST(ROOT_BUILDDIR) + +echo +echo Source root directory : $ROOT_SRCDIR +echo Build root directory : $ROOT_BUILDDIR +echo +echo + +if test -z "$AR"; then + AC_CHECK_PROGS(AR,ar xar,:,$PATH) +fi +AC_SUBST(AR) + +dnl Export the AR macro so that it will be placed in the libtool file +dnl correctly. +export AR + +echo +echo --------------------------------------------- +echo testing make +echo --------------------------------------------- +echo + +AC_PROG_MAKE_SET +AC_PROG_INSTALL +dnl +dnl libtool macro check for CC, LD, NM, LN_S, RANLIB, STRIP + for shared libraries + +AC_ENABLE_DEBUG(yes) +AC_DISABLE_PRODUCTION + +echo --------------------------------------------- +echo testing libtool +echo --------------------------------------------- + +dnl first, we set static to no! +dnl if we want it, use --enable-static +AC_ENABLE_STATIC(no) + +AC_LIBTOOL_DLOPEN +AC_PROG_LIBTOOL + +dnl Fix up the INSTALL macro if it s a relative path. We want the +dnl full-path to the binary instead. +case "$INSTALL" in + *install-sh*) + INSTALL='\${KERNEL_ROOT_DIR}'/salome_adm/unix/config_files/install-sh + ;; +esac + +echo +echo --------------------------------------------- +echo testing C/C++ +echo --------------------------------------------- +echo + +cc_ok=no +dnl inutil car libtool +dnl AC_PROG_CC +AC_PROG_CXX +AC_CXX_WARNINGS +AC_CXX_TEMPLATE_OPTIONS +AC_CXX_HAVE_SSTREAM +AC_DEPEND_FLAG +# AC_CC_WARNINGS([ansi]) +cc_ok=yes + +dnl Library libdl : +AC_CHECK_LIB(dl,dlopen) + +dnl Library librt : for alpha/osf +AC_CHECK_LIB(rt,nanosleep) + +dnl add library libm : +AC_CHECK_LIB(m,ceil) + +AC_CXX_USE_STD_IOSTREAM +AC_CXX_HAVE_SSTREAM + +dnl +dnl --------------------------------------------- +dnl testing linker +dnl --------------------------------------------- +dnl + +AC_LINKER_OPTIONS + +echo +echo --------------------------------------------- +echo testing threads +echo --------------------------------------------- +echo + +ENABLE_PTHREADS + +echo +echo --------------------------------------------- +echo BOOST Library +echo --------------------------------------------- +echo + +CHECK_BOOST + +echo +echo --------------------------------------------- +echo testing python +echo --------------------------------------------- +echo + +CHECK_PYTHON + +echo +echo --------------------------------------------- +echo testing QT +echo --------------------------------------------- +echo + +CHECK_QT + +echo +echo --------------------------------------------- +echo testing msg2qm +echo --------------------------------------------- +echo + +CHECK_MSG2QM + +echo +echo --------------------------------------------- +echo Testing OpenCascade +echo --------------------------------------------- +echo + +CHECK_CAS + +echo +echo --------------------------------------------- +echo testing omniORB +echo --------------------------------------------- +echo + +CHECK_OMNIORB + +echo +echo --------------------------------------------- +echo default ORB : omniORB +echo --------------------------------------------- +echo + +DEFAULT_ORB=omniORB +CHECK_CORBA + +AC_SUBST_FILE(CORBA) +corba=make_$ORB +CORBA=adm_local/unix/$corba + +echo +echo --------------------------------------------- +echo Testing Kernel +echo --------------------------------------------- +echo + +CHECK_KERNEL +AM_CONDITIONAL([SALOME_KERNEL], [test "x$KERNEL_ROOT_DIR" != "x"]) + +echo +echo --------------------------------------------- +echo Testing GUI +echo --------------------------------------------- +echo + +CHECK_SALOME_GUI +AM_CONDITIONAL([SALOME_GUI], [test "x$GUI_ROOT_DIR" != "x"]) + +echo +echo --------------------------------------------- +echo testing HDF5 +echo --------------------------------------------- +echo + +CHECK_HDF5 + +echo +echo --------------------------------------------- +echo testing MED AND MED2 +echo --------------------------------------------- +echo + +CHECK_MED +CHECK_MED2 + +echo +echo --------------------------------------------- +echo testing Component Evironment +echo --------------------------------------------- +echo + +CHECK_COMPONENT_ENV + +echo +echo --------------------------------------------- +echo Summary +echo --------------------------------------------- +echo + +echo Configure +variables="cc_ok threads_ok boost_ok python_ok omniORB_ok qt_ok msg2qm_ok Kernel_ok SalomeGUI_ok Med_ok med2_ok hdf5_ok Comp_Env_ok" + +for var in $variables +do + printf " %10s : " `echo \$var | sed -e "s,_ok,,"` + eval echo \$$var +done + +echo +echo "Default ORB : $DEFAULT_ORB" +echo + +dnl generals files which could be included in every makefile + +dnl We don t need to say when we re entering directories if we re using +dnl GNU make becuase make does it for us. +if test "X$GMAKE" = "Xyes"; then + AC_SUBST(SETX) SETX=":" +else + AC_SUBST(SETX) SETX="set -x" +fi + +# make other build directories +for rep in adm_local doc bin/salome include/salome lib/salome share/salome/resources share/salome/doc idl +do + $INSTALL -d $rep +done + +echo +echo --------------------------------------------- +echo copying resource files, shell scripts, and +echo xml files +echo --------------------------------------------- +echo + +dnl copy shells and utilities contained in the bin directory +dnl excluding .in files (treated in AC-OUTPUT below) and CVS +dnl directory + +cd bin +for i in $ROOT_SRCDIR/bin/* +do + local_bin=`echo $i | sed -e "s,$ROOT_SRCDIR,.,"` + case "$local_bin" in + *.in | *~) ;; + ./bin/CVS) ;; + *) ln -fs $i; echo $local_bin ;; + esac +done +cd $ROOT_BUILDDIR + +echo +echo --------------------------------------------- +echo generating Makefiles and configure files +echo --------------------------------------------- +echo + +AC_OUTPUT_COMMANDS([ \ + chmod +x ./bin/* \ +]) + +## do not delete this line diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/Makefile.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/Makefile.am new file mode 100644 index 000000000..87e8d7bc9 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/Makefile.am @@ -0,0 +1,15 @@ +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +SUBDIRS = + +doc_DATA = + +EXTRA_DIST=$(doc_DATA) + +STYLESHEET=$(srcdir)/rst.css + +usr_docs: + (cd salome && $(MAKE) $(AM_MAKEFLAGS) usr_docs) + +dev_docs: + (cd salome && $(MAKE) $(AM_MAKEFLAGS) dev_docs) diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/dev_guide.txt b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/dev_guide.txt new file mode 100644 index 000000000..64d2d0368 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/dev_guide.txt @@ -0,0 +1,103 @@ +Code Wrapping into SALOME with hxx2salome +========================================= + + +1 Context +--------- + +Assuming you want to integrate the component "COMP" into SALOME, you may use the hxx2salome command. + +If you are able to read this document, it is assumed that you succeeded running hxx2salome command. +The command you typed looks like: + + hxx2salome -g -s sh ${COMP_CPP_ROOT_DIR} COMP.hxx libCOMPCXX.so ${COMP_ROOT_DIR} + + where: + ${COMP_CPP_ROOT_DIR} : is the directory (absolute path) where the component to be integrated lies + something as /export/home/john/COMP/COMP_CPP_INSTALL + + COMP.hxx : is the header file describing the methods to be wrapped (must lie in one + unique occurence in ${COMP_CPP_ROOT_DIR} tree) + + libCOMPCXX.so : is the library file containing the implemented methods of the component + (must lie in one unique occurence in ${COMP_CPP_ROOT_DIR} tree) + + ${COMP_BUILD_ROOT_DIR} : is the directory (absolute path) where the component building tree has to + be installed something as /usr/local/salome_3.x.x/COMPONENTS + + -g : is an hxx2salome option asking for the GUI part of the component + + -s sh : is an hxx2salome option asking to use a sh-style environment file + +The present file is ${COMP_ROOT_DIR}/COMP/COMP_SRC/doc/dev_guide.txt + + +2 Implementing your wrapper +--------------------------- + +In the ${COMP_BUILD_ROOT_DIR}/COMP/COMP_SRC/src/COMP directory you will find a COMP_i.hxx file describing +all wrapped methods from your component. + +2.1 Implementation for testing component from console + +In the same ${COMP_BUILD_ROOT_DIR}/COMP/COMP_SRC/src/COMP directory you will find a COMP_test.py file. Edit it +to add (at bottom part) some calls to your component methods. They will look like: my_COMP.method(...). + +2.2 Implementation for testing component from SALOME GUI + +If you used option -g, you will find another directory named ${COMP_BUILD_ROOT_DIR}/COMP/COMP_SRC/src/COMPGUI. +You have to edit the following files: + +COMPGUI.h : Mainly changing the class fields that are only preferences-oriented in the template +COMPGUI.cxx : - Constructor to fit your needs, + - initialize to define your menus, toolbars, dialogs and preferences as shown in template + - OnMyNewItem, OnCallAction and equivalent own call-back routine names (template includes + examples in OnCallAction to retrieve user preferences values). Here are included the + calls to component library. They will look like: COMPgen->method( arg1, arg2, ... ); + - createPreferences to define your own user preferences data entries + - preferencesChanged to get prepared for automatic SALOME call-back +COMP_msg_en.po: Resources file with all English text strings used in the source code COMPGUI.cxx +COMP_msg_xx.po: Resources file with all strings translated in language xx (for instance fr) + + +3 Building your component +------------------------- + +When your implementation is ready, the SALOME client side of the component is built the regular way: + + check definition of environment variables (COMP_SRC_DIR, COMP_BUILD_DIR, COMP_ROOT_DIR) in + file ${COMP_BUILD_ROOT_DIR}/COMP/COMP_SRC/env_COMP.sh and source it + cd ${COMP_SRC_DIR} + ./build_configure + mkdir -p ${COMP_BUILD_DIR} + cd ${COMP_BUILD_DIR} + ${COMP_SRC_DIR}/configure --prefix=${COMP_ROOT_DIR} + make + make install + +4 Using your component +---------------------- + +To be done once: + edit your configuration file ~/.SalomeApprc.3.x.x: + Somewhere between and add: +
+ + +
+
+ +
+ In launch section add reference to COMP +
+ +
+ +To be done at login: + source the Salome environment + source the component environment file (${COMP_BUILD_ROOT_DIR}/COMP/COMP_SRC/env_COMP.sh) + +To be done at execution: + run Salome (runSalome command) + kill any still runing process if necessary (killSalome.py command) + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/rst.css b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/rst.css new file mode 100644 index 000000000..38bd7dcab --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/doc/rst.css @@ -0,0 +1,288 @@ +/* +:Authors: David Goodger, David Abrahams +:Contact: goodger@users.sourceforge.net, dave@boost-consulting.com +:date: $Date$ +:version: $Revision$ +:copyright: This stylesheet has been placed in the public domain. + +This stylesheet is for the use of ReStructuredText in a Boost context. +It is basically an agglomeration of boost.css and the default.css that +comes from docutils. + + */ + +.first { + margin-top: 0 } + +.last { + margin-bottom: 0 } + +a.toc-backref { + text-decoration: none ; + color: #00008B } + +dd { + margin-bottom: 0.5em } + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.attention, div.caution, div.danger, div.error, div.hint, +div.important, div.note, div.tip, div.warning, div.admonition { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +div.hint p.admonition-title, div.important p.admonition-title, +div.note p.admonition-title, div.tip p.admonition-title, +div.admonition p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.figure { + margin-left: 2em } + +div.footer, div.header { + font-size: smaller } + +div.sidebar { + margin-left: 1em ; + border: medium outset ; + padding: 0em 1em ; + background-color: #ffffee ; + width: 40% ; + float: right ; + clear: right } + +div.sidebar p.rubric { + font-family: sans-serif ; + font-size: medium } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +H1.title +{ + FONT-SIZE: 150%; + COLOR: #00008B; + text-align: center +} +H1 +{ + FONT-SIZE: 125%; +} +H2 +{ + FONT-SIZE: 108%; +} +h2.subtitle { + text-align: center } +H3 +{ + FONT-SIZE: 100%; +} +BODY +{ + FONT-SIZE: 100%; + BACKGROUND-COLOR: #ffffff; +} +PRE +{ + MARGIN-LEFT: 2em; + FONT-FAMILY: Courier; +} +CODE +{ + FONT-FAMILY: Courier; + white-space: pre; +} +.pre +{ + FONT-FAMILY: Courier; + white-space: pre; +} +.index +{ + TEXT-ALIGN: left; +} +.page-index +{ + TEXT-ALIGN: left; +} +.definition +{ + TEXT-ALIGN: left; +} +.footnote +{ + FONT-SIZE: 66%; + VERTICAL-ALIGN: super; + TEXT-DECORATION: none; +} +.function-semantics +{ + CLEAR: left; +} + +hr { + width: 75% } + +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + +p.attribution { + text-align: right ; + margin-left: 50% } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.rubric { + font-weight: bold ; + font-size: larger ; + color: maroon ; + text-align: center } + +p.sidebar-title { + font-family: sans-serif ; + font-weight: bold ; + font-size: larger } + +p.sidebar-subtitle { + font-family: sans-serif ; + font-weight: bold } + +p.topic-title { + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + +pre.line-block { + font-family: serif ; + font-size: 100% } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + font-size: 80%; + border: solid thin gray ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option { + white-space: nowrap } + +span.option-argument { + font-style: italic } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +table { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.citation { + border-left: solid thin gray ; + padding-left: 0.5ex } + +table.docinfo { + margin: 2em 4em } + +table.footnote { + border-left: solid thin black ; + padding-left: 0.5ex } + +td, th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +th.docinfo-name, th.field-name { + font-weight: bold ; + text-align: left ; + white-space: nowrap } + +/* + dwa 2003/7/29 -- commented out so that it wouldn't override earlier + styles from boost.css + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + font-size: 100% } +*/ + +ul.auto-toc { + list-style-type: none } diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/idl/HXX2SALOME_GENERIC_CLASS_NAME_Gen.idl b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/idl/HXX2SALOME_GENERIC_CLASS_NAME_Gen.idl new file mode 100644 index 000000000..e1a85b15c --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/idl/HXX2SALOME_GENERIC_CLASS_NAME_Gen.idl @@ -0,0 +1,26 @@ +#ifndef __HXX2SALOME_GENERIC_CLASS_NAME_GEN_hxx2salome__ +#define __HXX2SALOME_GENERIC_CLASS_NAME_GEN_hxx2salome__ + +#include "SALOME_Component.idl" +#include "SALOME_Exception.idl" + +#ifdef USE_MED + #include "MED.idl" +#else + // this include is not protected and already present in MED.idl + #include "SALOME_Comm.idl" +#endif + + +module HXX2SALOME_GENERIC_CLASS_NAME_ORB +{ + /*! \brief Interface of the %HXX2SALOME_GENERIC_CLASS_NAME component + */ + interface HXX2SALOME_GENERIC_CLASS_NAME_Gen : Engines::Component, SALOME::MultiCommClass + { +// HXX2SALOME_IDL_CODE + }; +}; + +#endif + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/idl/Makefile.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/idl/Makefile.am new file mode 100644 index 000000000..1d0c293cb --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/idl/Makefile.am @@ -0,0 +1,74 @@ + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + + +IDL_FILES = \ + SALOME_Component.idl \ + SALOME_Exception.idl \ + SALOME_Comm.idl \ + SALOME_GenericObj.idl \ + SALOMEDS.idl \ + SALOMEDS_Attributes.idl \ + ${dummy} + +IDL_SRC = \ + SALOME_ComponentSK.cc \ + SALOME_ExceptionSK.cc \ + SALOME_CommSK.cc \ + SALOME_GenericObjSK.cc \ + SALOMEDSSK.cc \ + SALOMEDS_AttributesSK.cc \ + ${dummy} + +USE_MED=0 + +IDL_FILES += \ + HXX2SALOME_GENERIC_CLASS_NAME_Gen.idl +IDL_SRC += \ + HXX2SALOME_GENERIC_CLASS_NAME_GenSK.cc + +lib_LIBRARIES = libHXX2SALOME_GENERIC_CLASS_NAMESK.a + +AM_CXXFLAGS = -fPIC -DPIC +libHXX2SALOME_GENERIC_CLASS_NAMESK_a_SOURCES = $(IDL_SRC) +libHXX2SALOME_GENERIC_CLASS_NAMESK_a_CPPFLAGS = \ + -I$(top_builddir)/adm_local/unix \ + -I$(top_builddir)/idl \ + @CORBA_CXXFLAGS@ @CORBA_INCLUDES@ + +salomeidl_DATA = compo1_Gen.idl + +# These variables defines the building process of CORBA files +OMNIORB_IDL = @OMNIORB_IDL@ +OMNIORB_IDLCXXFLAGS = @OMNIORB_IDLCXXFLAGS@ +IDLCXXFLAGS = -bcxx @IDLCXXFLAGS@ -I$(top_builddir)/salome/idl -I${srcdir} -I${KERNEL_ROOT_DIR}/idl/salome -DXXX + +%SK.cc %.hh: ${srcdir}/%.idl + $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $< + +%SK.cc %.hh: ${KERNEL_ROOT_DIR}/idl/salome/%.idl + $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $< + +%SK.cc %.hh: ${MED_ROOT_DIR}/idl/salome/%.idl + $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $< + +mostlyclean-local: + -rm -f *.hh *.cc .depidl + +# we use cpp to generate dependencies between idl files. +# option x c tells the preprocessor to consider idl as a c file. +# if an idl is modified, all idl dependencies are rebuilt + +.depidl: $(IDL_FILES) + @echo "" > $@ + @for dep in $^ dummy; do \ + if [ $$dep != "dummy" ]; then \ + echo Building dependencies for $$dep; \ + $(CPP) $(C_DEPEND_FLAG) -x c -I$(srcdir) -I${KERNEL_ROOT_DIR}/idl/salome $$dep 2>/dev/null | \ + sed 's/\.o/\SK.cc/' >>$@; \ + fi; \ + done ; + +-include .depidl + +# diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/py-compile b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/py-compile new file mode 100755 index 000000000..d6e900b30 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/py-compile @@ -0,0 +1,146 @@ +#!/bin/sh +# py-compile - Compile a Python program + +scriptversion=2005-05-14.22 + +# Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +if [ -z "$PYTHON" ]; then + PYTHON=python +fi + +basedir= +destdir= +files= +while test $# -ne 0; do + case "$1" in + --basedir) + basedir=$2 + if test -z "$basedir"; then + echo "$0: Missing argument to --basedir." 1>&2 + exit 1 + fi + shift + ;; + --destdir) + destdir=$2 + if test -z "$destdir"; then + echo "$0: Missing argument to --destdir." 1>&2 + exit 1 + fi + shift + ;; + -h|--h*) + cat <<\EOF +Usage: py-compile [--help] [--version] [--basedir DIR] [--destdir DIR] FILES..." + +Byte compile some python scripts FILES. Use --destdir to specify any +leading directory path to the FILES that you don't want to include in the +byte compiled file. Specify --basedir for any additional path information you +do want to be shown in the byte compiled file. + +Example: + py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py + +Report bugs to . +EOF + exit $? + ;; + -v|--v*) + echo "py-compile $scriptversion" + exit $? + ;; + *) + files="$files $1" + ;; + esac + shift +done + +if test -z "$files"; then + echo "$0: No files given. Try \`$0 --help' for more information." 1>&2 + exit 1 +fi + +# if basedir was given, then it should be prepended to filenames before +# byte compilation. +if [ -z "$basedir" ]; then + pathtrans="path = file" +else + pathtrans="path = os.path.join('$basedir', file)" +fi + +# if destdir was given, then it needs to be prepended to the filename to +# byte compile but not go into the compiled file. +if [ -z "$destdir" ]; then + filetrans="filepath = path" +else + filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)" +fi + +$PYTHON -c " +import sys, os, string, py_compile + +files = '''$files''' + +print 'Byte-compiling python modules...' +for file in string.split(files): + $pathtrans + $filetrans + if not os.path.exists(filepath) or not (len(filepath) >= 3 + and filepath[-3:] == '.py'): + continue + print file, + sys.stdout.flush() + py_compile.compile(filepath, filepath + 'c', path) +print" || exit $? + +# this will fail for python < 1.5, but that doesn't matter ... +$PYTHON -O -c " +import sys, os, string, py_compile + +files = '''$files''' +print 'Byte-compiling python modules (optimized versions) ...' +for file in string.split(files): + $pathtrans + $filetrans + if not os.path.exists(filepath) or not (len(filepath) >= 3 + and filepath[-3:] == '.py'): + continue + print file, + sys.stdout.flush() + py_compile.compile(filepath, filepath + 'o', path) +print" 2>/dev/null || : + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/ExecHXX2SALOME_GENERIC_CLASS_NAME.png b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/ExecHXX2SALOME_GENERIC_CLASS_NAME.png new file mode 100644 index 0000000000000000000000000000000000000000..16a20c116e8243a6b49ed862613d2cc49bdf4caa GIT binary patch literal 831 zcmV-F1Hk-=P)A+3!%gdoE?w?yY*XMamxaAW~()k6;QGVVf3ZPpQcy+38CrH3{Qk zoaxN-vWJ+OcH(Y#5qvHK|CitMf1CdUU;7AQ8zF4-#i736F~#EMso~pq*Ek7JMLa$}POH_T(b)M|f)>8t;^3f3 zKA)#ntMKyW+7Z-s>l6xWsZ53jrMAEC5{41RXe`Snj$`6DMr+Vop|xgsc$hE@Sz20V zb@eG)%b|Y+_m{*NND_%L1}POFH@MUObOdhQq^%&CMdWZvC2q+x@_Pg_JQ$DGG%bJbwIyVzG#2o#E=$@5yGf z#Bm5%IplY1BB@I((}Bdlpj1;;nAaqNZEDBWHP2)F0;K|LMcrchIBe@ z&Ye4p5H>e&{)pCc=qTd1Z_6|q4IIZIpUy{Fg7-dG2KQ=nb2l+s9A+3!%gdoE?w?yY*XMamxaAW~()k6;QGVVf3ZPpQcy+38CrH3{Qk zoaxN-vWJ+OcH(Y#5qvHK|CitMf1CdUU;7AQ8zF4-#i736F~#EMso~pq*Ek7JMLa$}POH_T(b)M|f)>8t;^3f3 zKA)#ntMKyW+7Z-s>l6xWsZ53jrMAEC5{41RXe`Snj$`6DMr+Vop|xgsc$hE@Sz20V zb@eG)%b|Y+_m{*NND_%L1}POFH@MUObOdhQq^%&CMdWZvC2q+x@_Pg_JQ$DGG%bJbwIyVzG#2o#E=$@5yGf z#Bm5%IplY1BB@I((}Bdlpj1;;nAaqNZEDBWHP2)F0;K|LMcrchIBe@ z&Ye4p5H>e&{)pCc=qTd1Z_6|q4IIZIpUy{Fg7-dG2KQ=nb2l+s9 - + statusdict /prefeed known { + statusdict exch /prefeed exch put + } { + pop + } ifelse +} bind def + +/deffont { + findfont exch scalefont def +} bind def + +/reencode_font { + findfont reencode 2 copy definefont pop def +} bind def + +% Function c-show (str => -) +% centers text only according to x axis. +/c-show { + dup stringwidth pop + 2 div neg 0 rmoveto + show +} bind def + +% Function l-show (str => -) +% prints texts so that it ends at currentpoint +/l-show { + dup stringwidth pop neg + 0 + rmoveto show +} bind def + +% center-fit show (str w => -) +% show centered, and scale currentfont so that the width is less than w +/cfshow { + exch dup stringwidth pop + % If the title is too big, try to make it smaller + 3 2 roll 2 copy + gt + { % if, i.e. too big + exch div + currentfont exch scalefont setfont + } { % ifelse + pop pop + } + ifelse + c-show % center title +} bind def + +% Return the y size of the current font +% - => fontsize +/currentfontsize { + currentfont /FontType get 0 eq { + currentfont /FontMatrix get 3 get + }{ + currentfont /FontMatrix get 3 get 1000 mul + } ifelse +} bind def + +% reencode the font +% -> +/reencode { %def + dup length 5 add dict begin + { %forall + 1 index /FID ne + { def }{ pop pop } ifelse + } forall + /Encoding exch def + + % Use the font's bounding box to determine the ascent, descent, + % and overall height; don't forget that these values have to be + % transformed using the font's matrix. + % We use `load' because sometimes BBox is executable, sometimes not. + % Since we need 4 numbers an not an array avoid BBox from being executed + /FontBBox load aload pop + FontMatrix transform /Ascent exch def pop + FontMatrix transform /Descent exch def pop + /FontHeight Ascent Descent sub def + + % Define these in case they're not in the FontInfo (also, here + % they're easier to get to. + /UnderlinePosition 1 def + /UnderlineThickness 1 def + + % Get the underline position and thickness if they're defined. + currentdict /FontInfo known { + FontInfo + + dup /UnderlinePosition known { + dup /UnderlinePosition get + 0 exch FontMatrix transform exch pop + /UnderlinePosition exch def + } if + + dup /UnderlineThickness known { + /UnderlineThickness get + 0 exch FontMatrix transform exch pop + /UnderlineThickness exch def + } if + + } if + currentdict + end +} bind def + +% composite fonts for ASCII-EUC mixed string +% Version 1.2 1/31/1990 +% Orignal Ken'ichi HANDA (handa@etl.go.jp) +% Modified Norio Katayama (katayama@rd.nacsis.ac.jp),1998 +% Extend & Fix Koji Nakamaru (maru@on.cs.keio.ac.jp), 1999 +% Anyone can freely copy, modify, distribute this program. + +/copyfont { % font-dic extra-entry-count copyfont font-dic + 1 index maxlength add dict begin + { 1 index /FID ne 2 index /UniqueID ne and + {def} {pop pop} ifelse + } forall + currentdict + end +} bind def + +/compositefont { % ASCIIFontName EUCFontName RomanScale RomanOffset Rot(T/F) compositefont font + /RomanRotation exch def + /RomanOffset exch def + /RomanScale exch def + userdict /fixeucfont_dict known not { + userdict begin + /fixeucfont_dict 2 dict begin + /UpperByteEncoding [ + 16#00 1 16#20 { pop 0 } for + 16#21 1 16#28 { 16#20 sub } for + 16#29 1 16#2F { pop 0 } for + 16#30 1 16#74 { 16#27 sub } for + 16#75 1 16#FF { pop 0 } for + ] def + /LowerByteEncoding [ + 16#00 1 16#A0 { pop /.notdef } for + 16#A1 1 16#FE { 16#80 sub 16 2 string cvrs + (cXX) dup 1 4 -1 roll + putinterval cvn } for + /.notdef + ] def + currentdict + end def + end + } if + findfont dup /FontType get 0 eq { + 14 dict begin + % + % 7+8 bit EUC font + % + 12 dict begin + /EUCFont exch def + /FontInfo (7+8 bit EUC font) readonly def + /PaintType 0 def + /FontType 0 def + /FontMatrix matrix def + % /FontName + /Encoding fixeucfont_dict /UpperByteEncoding get def + /FMapType 2 def + EUCFont /WMode known + { EUCFont /WMode get /WMode exch def } + { /WMode 0 def } ifelse + /FDepVector [ + EUCFont /FDepVector get 0 get + [ 16#21 1 16#28 {} for 16#30 1 16#74 {} for ] + { + 13 dict begin + /EUCFont EUCFont def + /UpperByte exch 16#80 add def + % /FontName + /FontInfo (EUC lower byte font) readonly def + /PaintType 0 def + /FontType 3 def + /FontMatrix matrix def + /FontBBox {0 0 0 0} def + /Encoding + fixeucfont_dict /LowerByteEncoding get def + % /UniqueID + % /WMode + /BuildChar { + gsave + exch dup /EUCFont get setfont + /UpperByte get + 2 string + dup 0 4 -1 roll put + dup 1 4 -1 roll put + dup stringwidth setcharwidth + 0 0 moveto show + grestore + } bind def + currentdict + end + /lowerbytefont exch definefont + } forall + ] def + currentdict + end + /eucfont exch definefont + exch + findfont 1 copyfont dup begin + RomanRotation { + /FontMatrix FontMatrix + [ 0 RomanScale neg RomanScale 0 RomanOffset neg 0 ] + matrix concatmatrix def + }{ + /FontMatrix FontMatrix + [ RomanScale 0 0 RomanScale 0 RomanOffset ] matrix concatmatrix + def + /CDevProc + {pop pop pop pop 0 exch -1000 exch 2 div 880} def + } ifelse + end + /asciifont exch definefont + exch + /FDepVector [ 4 2 roll ] def + /FontType 0 def + /WMode 0 def + /FMapType 4 def + /FontMatrix matrix def + /Encoding [0 1] def + /FontBBox {0 0 0 0} def +% /FontHeight 1.0 def % XXXX + /FontHeight RomanScale 1.0 ge { RomanScale }{ 1.0 } ifelse def + /Descent -0.3 def % XXXX + currentdict + end + /tmpfont exch definefont + pop + /tmpfont findfont + }{ + pop findfont 0 copyfont + } ifelse +} def + +/slantfont { % FontName slant-degree slantfont font' + exch findfont 1 copyfont begin + [ 1 0 4 -1 roll 1 0 0 ] FontMatrix exch matrix concatmatrix + /FontMatrix exch def + currentdict + end +} def + +% Function print line number ( # -) +/# { + gsave + sx cw mul neg 2 div 0 rmoveto + f# setfont + c-show + grestore +} bind def + +% -------- Some routines to enlight plain b/w printings --------- + +% Underline +% width -- +/dounderline { + currentpoint + gsave + moveto + 0 currentfont /Descent get currentfontsize mul rmoveto + 0 rlineto + stroke + grestore +} bind def + +% Underline a string +% string -- +/dounderlinestring { + stringwidth pop + dounderline +} bind def + +/UL { + /ul exch store +} bind def + +% Draw a box of WIDTH wrt current font +% width -- +/dobox { + currentpoint + gsave + newpath + moveto + 0 currentfont /Descent get currentfontsize mul rmoveto + dup 0 rlineto + 0 currentfont /FontHeight get currentfontsize mul rlineto + neg 0 rlineto + closepath + stroke + grestore +} bind def + +/BX { + /bx exch store +} bind def + +% Box a string +% string -- +/doboxstring { + stringwidth pop + dobox +} bind def + +% +% ------------- Color routines --------------- +% +/FG /setrgbcolor load def + +% Draw the background +% width -- +/dobackground { + currentpoint + gsave + newpath + moveto + 0 currentfont /Descent get currentfontsize mul rmoveto + dup 0 rlineto + 0 currentfont /FontHeight get currentfontsize mul rlineto + neg 0 rlineto + closepath + bgcolor aload pop setrgbcolor + fill + grestore +} bind def + +% Draw bg for a string +% string -- +/dobackgroundstring { + stringwidth pop + dobackground +} bind def + + +/BG { + dup /bg exch store + { mark 4 1 roll ] /bgcolor exch store } if +} bind def + + +/Show { + bg { dup dobackgroundstring } if + ul { dup dounderlinestring } if + bx { dup doboxstring } if + show +} bind def + +% Function T(ab), jumps to the n-th tabulation in the current line +/T { + cw mul x0 add + bg { dup currentpoint pop sub dobackground } if + ul { dup currentpoint pop sub dounderline } if + bx { dup currentpoint pop sub dobox } if + y0 moveto +} bind def + +% Function n: move to the next line +/n { + /y0 y0 bfs sub store + x0 y0 moveto +} bind def + +% Function N: show and move to the next line +/N { + Show + /y0 y0 bfs sub store + x0 y0 moveto +} bind def + +/S { + Show +} bind def + +%%BeginResource: procset a2ps-a2ps-hdr 2.0 2 +%%Copyright: (c) 1988, 89, 90, 91, 92, 93 Miguel Santana +%%Copyright: (c) 1995, 96, 97, 98 Akim Demaille, Miguel Santana +% Function title: prints page header. +% are passed as argument +/title { + % 1. Draw the background + x v get y v get moveto + gsave + 0 th 2 div neg rmoveto + th setlinewidth + 0.95 setgray + pw 0 rlineto stroke + grestore + % 2. Border it + gsave + 0.7 setlinewidth + pw 0 rlineto + 0 th neg rlineto + pw neg 0 rlineto + closepath stroke + grestore + % stk: ct rt lt + x v get y v get th sub 1 add moveto +%%IncludeResource: font Helvetica + fHelvetica fnfs 0.8 mul scalefont setfont + % 3. The left title + gsave + dup stringwidth pop fnfs 0.8 mul add exch % leave space took on stack + fnfs 0.8 mul hm rmoveto + show % left title + grestore + exch + % stk: ct ltw rt + % 4. the right title + gsave + dup stringwidth pop fnfs 0.8 mul add exch % leave space took on stack + dup + pw exch stringwidth pop fnfs 0.8 mul add sub + hm + rmoveto + show % right title + grestore + % stk: ct ltw rtw + % 5. the center title + gsave + pw 3 1 roll + % stk: ct pw ltw rtw + 3 copy + % Move to the center of the left room + sub add 2 div hm rmoveto + % What is the available space in here? + add sub fnfs 0.8 mul sub fnfs 0.8 mul sub + % stk: ct space_left +%%IncludeResource: font Helvetica-Bold + fHelvetica-Bold fnfs scalefont setfont + cfshow + grestore +} bind def + +% Function border: prints virtual page border +/border { %def + gsave % print four sides + 0 setgray + x v get y v get moveto + 0.7 setlinewidth % of the square + pw 0 rlineto + 0 ph neg rlineto + pw neg 0 rlineto + closepath stroke + grestore +} bind def + +% Function water: prints a water mark in background +/water { %def + gsave + scx scy moveto rotate +%%IncludeResource: font Times-Bold + fTimes-Bold 100 scalefont setfont + .97 setgray + dup stringwidth pop 2 div neg -50 rmoveto + show + grestore +} bind def + +% Function rhead: prints the right header +/rhead { %def + lx ly moveto + fHelvetica fnfs 0.8 mul scalefont setfont + l-show +} bind def + +% Function footer (cf rf lf -> -) +/footer { + fHelvetica fnfs 0.8 mul scalefont setfont + dx dy moveto + show + + snx sny moveto + l-show + + fnx fny moveto + c-show +} bind def +%%EndResource +%%BeginResource: procset a2ps-black+white-Prolog 2.0 1 + +% Function T(ab), jumps to the n-th tabulation in the current line +/T { + cw mul x0 add y0 moveto +} bind def + +% Function n: move to the next line +/n { %def + /y0 y0 bfs sub store + x0 y0 moveto +} bind def + +% Function N: show and move to the next line +/N { + Show + /y0 y0 bfs sub store + x0 y0 moveto +} bind def + +/S { + Show +} bind def + +/p { + false UL + false BX + fCourier bfs scalefont setfont + Show +} bind def + +/sy { + false UL + false BX + fSymbol bfs scalefont setfont + Show +} bind def + +/k { + false UL + false BX + fCourier-Oblique bfs scalefont setfont + Show +} bind def + +/K { + false UL + false BX + fCourier-Bold bfs scalefont setfont + Show +} bind def + +/c { + false UL + false BX + fCourier-Oblique bfs scalefont setfont + Show +} bind def + +/C { + false UL + false BX + fCourier-BoldOblique bfs scalefont setfont + Show +} bind def + +/l { + false UL + false BX + fHelvetica bfs scalefont setfont + Show +} bind def + +/L { + false UL + false BX + fHelvetica-Bold bfs scalefont setfont + Show +} bind def + +/str{ + false UL + false BX + fTimes-Roman bfs scalefont setfont + Show +} bind def + +/e{ + false UL + true BX + fHelvetica-Bold bfs scalefont setfont + Show +} bind def + +%%EndResource +%%EndProlog +%%BeginSetup +%%IncludeResource: font Courier +%%IncludeResource: font Courier-Oblique +%%IncludeResource: font Courier-Bold +%%IncludeResource: font Times-Roman +%%IncludeResource: font Symbol +%%IncludeResource: font Courier-BoldOblique +%%BeginResource: encoding ISO-8859-1Encoding +/ISO-8859-1Encoding [ +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright +/parenleft /parenright /asterisk /plus /comma /minus /period /slash +/zero /one /two /three /four /five /six /seven +/eight /nine /colon /semicolon /less /equal /greater /question +/at /A /B /C /D /E /F /G +/H /I /J /K /L /M /N /O +/P /Q /R /S /T /U /V /W +/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +/quoteleft /a /b /c /d /e /f /g +/h /i /j /k /l /m /n /o +/p /q /r /s /t /u /v /w +/x /y /z /braceleft /bar /braceright /asciitilde /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/space /exclamdown /cent /sterling /currency /yen /brokenbar /section +/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron +/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /bullet +/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown +/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla +/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis +/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply +/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls +/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla +/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis +/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide +/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis +] def +%%EndResource +% Initialize page description variables. +/sh 612 def +/sw 792 def +/llx 24 def +/urx 768 def +/ury 588 def +/lly 24 def +/#copies 1 def +/th 20.000000 def +/fnfs 15 def +/bfs 8.000000 def +/cw 4.800000 def + +% Dictionary for ISO-8859-1 support +/iso1dict 8 dict begin + /fCourier ISO-8859-1Encoding /Courier reencode_font + /fCourier-Bold ISO-8859-1Encoding /Courier-Bold reencode_font + /fCourier-BoldOblique ISO-8859-1Encoding /Courier-BoldOblique reencode_font + /fCourier-Oblique ISO-8859-1Encoding /Courier-Oblique reencode_font + /fHelvetica ISO-8859-1Encoding /Helvetica reencode_font + /fHelvetica-Bold ISO-8859-1Encoding /Helvetica-Bold reencode_font + /fTimes-Bold ISO-8859-1Encoding /Times-Bold reencode_font + /fTimes-Roman ISO-8859-1Encoding /Times-Roman reencode_font +currentdict end def +/bgcolor [ 0 0 0 ] def +/bg false def +/ul false def +/bx false def +% The font for line numbering +/f# /Helvetica findfont bfs .6 mul scalefont def +/fSymbol /Symbol findfont def +/hm fnfs 0.25 mul def +/pw + cw 154.400000 mul +def +/ph + 517.600000 th add +def +/pmw 0 def +/pmh 0 def +/v 0 def +/x [ + 0 +] def +/y [ + pmh ph add 0 mul ph add +] def +/scx sw 2 div def +/scy sh 2 div def +/snx urx def +/sny lly 2 add def +/dx llx def +/dy sny def +/fnx scx def +/fny dy def +/lx snx def +/ly ury fnfs 0.8 mul sub def +/sx 0 def +/tab 8 def +/x0 0 def +/y0 0 def +%%EndSetup + +%%Page: (1) 1 +%%BeginPageSetup +/pagesave save def +sh 0 translate 90 rotate +%%EndPageSetup +iso1dict begin +gsave +llx lly 12 add translate +/v 0 store +/x0 x v get 3.360000 add sx cw mul add store +/y0 y v get bfs th add sub store +x0 y0 moveto +() p n +() N +() N +() N +() N +() N +( ) N +( ) N +( ) N +() N +() N +() N +( ) N +() N +() N +() N +() N +(PYHXX2SALOME_GENERIC_CLASS_NAME_en.xml) (Page 1/1) (Oct 14, 03 10:41) title +border +grestore +(Printed by Nicolas CROUZET - SFME/LGLS) rhead +(PYHXX2SALOME_GENERIC_CLASS_NAME_en.xml) (1/1) (Tuesday November 04, 2003) footer +end % of iso1dict +pagesave restore +showpage + +%%Trailer +end +%%EOF diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_en.xml b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_en.xml new file mode 100644 index 000000000..5fe8b84e5 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_en.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_fr.xml b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_fr.xml new file mode 100644 index 000000000..500c5d2fc --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/HXX2SALOME_GENERIC_CLASS_NAME_fr.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/Makefile.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/Makefile.am new file mode 100644 index 000000000..5d396cb77 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/Makefile.am @@ -0,0 +1,23 @@ +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +# +# =============================================================== +# Files to be installed +# =============================================================== +# + +if SALOME_KERNEL +dist_salomeres_DATA=HXX2SALOME_GENERIC_CLASS_NAMECatalog.xml +else +dist_salomeres_DATA= +endif + +dist_salomeres_DATA += \ + config \ + ExecHXX2SALOME_GENERIC_CLASS_NAME.png \ + HXX2SALOME_GENERIC_CLASS_NAME_en.ps \ + HXX2SALOME_GENERIC_CLASS_NAME_en.xml \ + HXX2SALOME_GENERIC_CLASS_NAME_fr.xml \ + HXX2SALOME_GENERIC_CLASS_NAME.png \ + SalomeApp.xml \ + ${dummy} diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/SalomeApp.xml b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/SalomeApp.xml new file mode 100644 index 000000000..15fbf1c25 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/SalomeApp.xml @@ -0,0 +1,11 @@ + +
+ + + +
+
+ + +
+
diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/config b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/config new file mode 100644 index 000000000..e3471120d --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/resources/config @@ -0,0 +1 @@ +language=en diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/rfind b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/rfind new file mode 100755 index 000000000..e35b27b4d --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/rfind @@ -0,0 +1,52 @@ +#! /bin/sh +# -- +# Copyright (C) CEA, EDF +# Author : Erwan ADAM (CEA) +# -- + +# +# Usage : rfind dir suffix ... +# +# find all files *suffix in dir in a recursive way +# different of the usual command find ... +# + +if test $# != 2 ; then + echo "Usage : $0 dir suffix" + exit +fi + +local_find() { + # if the first argument is not a directory, returns + if test ! -d $1 ; then + # echo "$1 is not a directory" + return + fi + # dont look in the CVS directories + # dont look in the autom4te* directories + case "$1" in + */CVS) return ;; + */autom4te*) return ;; + */*_ROOT) return ;; + */*_SRC) return ;; + *) ;; + esac + # for each regular file contained in the directory + # test if it's a *"$2" file + for i in $1/* + do + if test -f $i ; then + case `basename $i` in + *$2) echo " "$i ;; + *) ;; + esac + fi + done + # for each subdirectory of the first argument, proceeds recursively + for i in $1/* + do + local_find $i $2 + done +} + +local_find $1 $2 diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/root_clean b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/root_clean new file mode 100755 index 000000000..9ad87c933 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/root_clean @@ -0,0 +1,26 @@ +#!/bin/sh + +CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` +cd ${CONF_DIR} + +TO_CLEAN= +TO_CLEAN=${TO_CLEAN}' build_configure.log' +TO_CLEAN=${TO_CLEAN}' Makefile.am.list' +TO_CLEAN=${TO_CLEAN}' aclocal.m4' +TO_CLEAN=${TO_CLEAN}' autom4te*' +TO_CLEAN=${TO_CLEAN}' configure' +TO_CLEAN=${TO_CLEAN}' configure.in' +TO_CLEAN=${TO_CLEAN}' missing' +TO_CLEAN=${TO_CLEAN}' install-sh' +TO_CLEAN=${TO_CLEAN}' config.guess' +TO_CLEAN=${TO_CLEAN}' config.sub' +TO_CLEAN=${TO_CLEAN}' depcomp' +TO_CLEAN=${TO_CLEAN}' ltmain.sh' + +rm -rf $TO_CLEAN > /dev/null + +l=`find . -name "Makefile.in" -or -name "*~"` + +if test X"$l" != X ; then + rm -f $l +fi diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.cxx b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.cxx new file mode 100644 index 000000000..ed549ea2b --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.cxx @@ -0,0 +1,221 @@ +#include "HXX2SALOME_GENERIC_CLASS_NAMEGUI.h" + +#include +#include +#include +#include +#include + +#include + +#define COMPONENT_NAME "HXX2SALOME_GENERIC_CLASS_NAME" + +using namespace std; + +// Constructor +HXX2SALOME_GENERIC_CLASS_NAMEGUI::HXX2SALOME_GENERIC_CLASS_NAMEGUI() : + SalomeApp_Module( COMPONENT_NAME ) // Module name +{ + // Initializations + default_bool = false; + default_int = 0; + default_spinInt = 0; + default_spinDbl = 0.; + default_selection = QString(""); + + // List for the selector + selector_strings.clear(); + selector_strings.append( tr( "PREF_LIST_TEXT_0" ) ); + selector_strings.append( tr( "PREF_LIST_TEXT_1" ) ); + selector_strings.append( tr( "PREF_LIST_TEXT_2" ) ); +} + +// Gets a reference to the module's engine +HXX2SALOME_GENERIC_CLASS_NAME_ORB::HXX2SALOME_GENERIC_CLASS_NAME_Gen_ptr HXX2SALOME_GENERIC_CLASS_NAMEGUI::InitHXX2SALOME_GENERIC_CLASS_NAMEGen( SalomeApp_Application* app ) +{ + Engines::Component_var comp = app->lcc()->FindOrLoad_Component( "FactoryServer",COMPONENT_NAME ); + HXX2SALOME_GENERIC_CLASS_NAME_ORB::HXX2SALOME_GENERIC_CLASS_NAME_Gen_ptr clr = HXX2SALOME_GENERIC_CLASS_NAME_ORB::HXX2SALOME_GENERIC_CLASS_NAME_Gen::_narrow(comp); + ASSERT(!CORBA::is_nil(clr)); + return clr; +} + +// Module's initialization +void HXX2SALOME_GENERIC_CLASS_NAMEGUI::initialize( CAM_Application* app ) +{ + // Get handle to Application, Desktop and Resource Manager + SalomeApp_Module::initialize( app ); + + InitHXX2SALOME_GENERIC_CLASS_NAMEGen( dynamic_cast( app ) ); + + QWidget* aParent = app->desktop(); + + SUIT_ResourceMgr* aResourceMgr = app->resourceMgr(); + + // GUI items + // --> Create actions: 190 is linked to item in "File" menu + // and 901 is linked to both specific menu and toolbar + createAction( 190, tr( "TLT_MY_NEW_ITEM" ), QIconSet(), tr( "MEN_MY_NEW_ITEM" ), tr( "STS_MY_NEW_ITEM" ), 0, aParent, false, + this, SLOT( OnMyNewItem() ) ); + + QPixmap aPixmap = aResourceMgr->loadPixmap( COMPONENT_NAME,tr( "ICON_HXX2SALOME_GENERIC_CLASS_NAME" ) ); + createAction( 901, tr( "TLT_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" ), QIconSet( aPixmap ), tr( "MEN_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" ), tr( "STS_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" ), 0, aParent, false, + this, SLOT( OnCallAction() ) ); + + // --> Create item in "File" menu + int aMenuId; + aMenuId = createMenu( tr( "MEN_FILE" ), -1, -1 ); + createMenu( separator(), aMenuId, -1, 10 ); + aMenuId = createMenu( tr( "MEN_FILE_HXX2SALOME_GENERIC_CLASS_NAME" ), aMenuId, -1, 10 ); + createMenu( 190, aMenuId ); + + // --> Create specific menu + aMenuId = createMenu( tr( "MEN_HXX2SALOME_GENERIC_CLASS_NAME" ), -1, -1, 30 ); + createMenu( 901, aMenuId, 10 ); + + // --> Create toolbar item + int aToolId = createTool ( tr( "TOOL_HXX2SALOME_GENERIC_CLASS_NAME" ) ); + createTool( 901, aToolId ); +} + +// Module's engine IOR +QString HXX2SALOME_GENERIC_CLASS_NAMEGUI::engineIOR() const +{ + CORBA::String_var anIOR = getApp()->orb()->object_to_string( InitHXX2SALOME_GENERIC_CLASS_NAMEGen( getApp() ) ); + return QString( anIOR.in() ); +} + +// Module's activation +bool HXX2SALOME_GENERIC_CLASS_NAMEGUI::activateModule( SUIT_Study* theStudy ) +{ + bool bOk = SalomeApp_Module::activateModule( theStudy ); + + setMenuShown( true ); + setToolShown( true ); + + return bOk; +} + +// Module's deactivation +bool HXX2SALOME_GENERIC_CLASS_NAMEGUI::deactivateModule( SUIT_Study* theStudy ) +{ + setMenuShown( false ); + setToolShown( false ); + + return SalomeApp_Module::deactivateModule( theStudy ); +} + +// Default windows +void HXX2SALOME_GENERIC_CLASS_NAMEGUI::windows( QMap& theMap ) const +{ + theMap.clear(); + theMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::DockLeft ); + theMap.insert( SalomeApp_Application::WT_PyConsole, Qt::DockBottom ); +} + +// Action slot: Launched with action 190 +void HXX2SALOME_GENERIC_CLASS_NAMEGUI::OnMyNewItem() +{ + SUIT_MessageBox::warn1( getApp()->desktop(),tr( "INF_HXX2SALOME_GENERIC_CLASS_NAME_TITLE" ), tr( "INF_HXX2SALOME_GENERIC_CLASS_NAME_TEXT" ), tr( "BUT_OK" ) ); +} + +// Action slot: Launched with action 901 +void HXX2SALOME_GENERIC_CLASS_NAMEGUI::OnCallAction() +{ + // Create a HXX2SALOME_GENERIC_CLASS_NAME component + HXX2SALOME_GENERIC_CLASS_NAME_ORB::HXX2SALOME_GENERIC_CLASS_NAME_Gen_ptr HXX2SALOME_GENERIC_CLASS_NAMEgen = HXX2SALOME_GENERIC_CLASS_NAMEGUI::InitHXX2SALOME_GENERIC_CLASS_NAMEGen( getApp() ); + + // Do the job... + // + // HXX2SALOME_GENERIC_CLASS_NAMEgen->method( arg1, arg2, ... ); + + // Open a dialog showing Preferences values (just to display something) + + // ****** Direct access to preferences: implementation at 12/12/05 ****** + // Comment out this section when "preferencesChanged" called back + SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr(); + + default_bool = mgr->booleanValue(COMPONENT_NAME, "default_bool", false); + + default_int = mgr->integerValue(COMPONENT_NAME, "default_integer", 3); + + default_spinInt = mgr->integerValue(COMPONENT_NAME, "default_spinint", 4); + + default_spinDbl = mgr->doubleValue(COMPONENT_NAME, "default_spindbl", 4.5); + + int selectorIndex = mgr->integerValue(COMPONENT_NAME, "default_selector"); + default_selection = (0<=selectorIndex && selectorIndex<=selector_strings.count() ? selector_strings[selectorIndex]: QString("None")); + // ****** End of section to be commented out ****** + + QString SUC = ( default_bool ? QString( tr ("INF_HXX2SALOME_GENERIC_CLASS_NAME_CHECK") ) : QString( tr("INF_HXX2SALOME_GENERIC_CLASS_NAME_UNCHECK") ) ) ; + + QString textResult = QString( tr( "RES_HXX2SALOME_GENERIC_CLASS_NAME_TEXT" ) ).arg(SUC).arg(default_int).arg(default_spinInt).arg(default_spinDbl).arg(default_selection); + SUIT_MessageBox::info1( getApp()->desktop(), tr( "RES_HXX2SALOME_GENERIC_CLASS_NAME_TITLE" ), textResult, tr( "BUT_OK" ) ); +} + +void HXX2SALOME_GENERIC_CLASS_NAMEGUI::createPreferences() +{ + // A sample preference dialog + + // One only tab + int genTab = addPreference( tr( "PREF_TAB_GENERAL" ) ); + + // One only group + int defaultsGroup = addPreference( tr( "PREF_GROUP_DEFAULTS" ), genTab ); + + // A checkbox + addPreference( tr( "PREF_DEFAULT_BOOL" ), defaultsGroup, LightApp_Preferences::Bool, COMPONENT_NAME, "default_bool" ); + + // An entry for integer + addPreference( tr( "PREF_DEFAULT_INTEGER" ), defaultsGroup, LightApp_Preferences::Integer, COMPONENT_NAME, "default_integer" ); + + // An integer changed by spinbox + int spinInt = addPreference( tr( "PREF_DEFAULT_SPININT" ), defaultsGroup, LightApp_Preferences::IntSpin, COMPONENT_NAME, "default_spinint" ); + setPreferenceProperty( spinInt, "min", 0 ); + setPreferenceProperty( spinInt, "max", 20 ); + setPreferenceProperty( spinInt, "step", 2 ); + + // A Double changed by spinbox + int spinDbl = addPreference( tr( "PREF_DEFAULT_SPINDBL" ), defaultsGroup, LightApp_Preferences::DblSpin, COMPONENT_NAME, "default_spindbl" ); + setPreferenceProperty( spinDbl, "min", 1 ); + setPreferenceProperty( spinDbl, "max", 10 ); + setPreferenceProperty( spinDbl, "step", 0.1 ); + + // A choice in a list + int options = addPreference( tr( "PREF_DEFAULT_SELECTOR" ), defaultsGroup, LightApp_Preferences::Selector, COMPONENT_NAME, "default_selector" ); + QValueList indices; + indices.append( 0 ); + indices.append( 1 ); + indices.append( 2 ); + setPreferenceProperty( options, "strings", selector_strings ); + setPreferenceProperty( options, "indexes", indices ); +} + +void HXX2SALOME_GENERIC_CLASS_NAMEGUI::preferencesChanged( const QString& sect, const QString& name ) +{ +// ****** This is normal way: Not yet called back at 12/12/05 ****** + SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr(); + if( sect==COMPONENT_NAME ) + { + if( name=="default_bool" ) + default_bool = mgr->booleanValue(COMPONENT_NAME, "default_bool", false); + if( name=="default_integer" ) + default_int = mgr->integerValue(COMPONENT_NAME, "default_integer", 3); + if( name=="default_spinint" ) + default_spinInt = mgr->integerValue(COMPONENT_NAME, "default_spinint", 4); + if( name=="default_spindbl" ) + default_spinDbl = mgr->doubleValue(COMPONENT_NAME, "default_spindbl", 4.5); + if( name=="default_selector" ) + { + int selectorIndex = mgr->integerValue(COMPONENT_NAME, "default_selector"); + default_selection = (0<=selectorIndex && selectorIndex<=selector_strings.count() ? selector_strings[selectorIndex]: QString("None")); + } + } +} + +// Export the module +extern "C" { + CAM_Module* createModule() + { + return new HXX2SALOME_GENERIC_CLASS_NAMEGUI(); + } +} diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.h b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.h new file mode 100644 index 000000000..ac1e50b1d --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAMEGUI.h @@ -0,0 +1,48 @@ +// HXX2SALOME_GENERIC_CLASS_NAMEGUI : HXX2SALOME_GENERIC_CLASS_NAME component GUI implemetation +// + +#ifndef _HXX2SALOME_GENERIC_CLASS_NAMEGUI_H_ +#define _HXX2SALOME_GENERIC_CLASS_NAMEGUI_H_ + +#include + +#include +#include CORBA_CLIENT_HEADER(HXX2SALOME_GENERIC_CLASS_NAME_Gen) + +class SalomeApp_Application; +class HXX2SALOME_GENERIC_CLASS_NAMEGUI: public SalomeApp_Module +{ + Q_OBJECT + +public: + HXX2SALOME_GENERIC_CLASS_NAMEGUI(); + + void initialize( CAM_Application* ); + QString engineIOR() const; + void windows( QMap& ) const; + + static HXX2SALOME_GENERIC_CLASS_NAME_ORB::HXX2SALOME_GENERIC_CLASS_NAME_Gen_ptr InitHXX2SALOME_GENERIC_CLASS_NAMEGen( SalomeApp_Application* ); + + virtual void createPreferences(); + virtual void preferencesChanged( const QString&, const QString& ); + +public slots: + bool deactivateModule( SUIT_Study* ); + bool activateModule( SUIT_Study* ); + +protected slots: + void OnMyNewItem(); + void OnCallAction(); + +private: + bool default_bool; + int default_int; + int default_spinInt; + double default_spinDbl; + QString default_selection; + + QStringList selector_strings; + +}; + +#endif diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_icons.po b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_icons.po new file mode 100644 index 000000000..a2f2c9a54 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_icons.po @@ -0,0 +1,14 @@ +# This is a Qt message file in .po format. Each msgid starts with +# a scope. This scope should *NOT* be translated - eg. "Foo::Bar" +# would be translated to "Pub", not "Foo::Pub". +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + +msgid "ICON_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "ExecHXX2SALOME_GENERIC_CLASS_NAME.png" + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_en.po b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_en.po new file mode 100644 index 000000000..ecb36b546 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_en.po @@ -0,0 +1,99 @@ +# This is a Qt message file in .po format. Each msgid starts with +# a scope. This scope should *NOT* be translated - eg. translating +# from French to English, "Foo::Bar" would be translated to "Pub", +# not "Foo::Pub". +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2003-11-19 03:10:19 PM CET\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::BUT_OK" +msgstr "OK" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::BUT_CANCEL" +msgstr "Cancel" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_TITLE" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME Information" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_TEXT" +msgstr "This is just a test" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_CHECK" +msgstr "Checked" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_UNCHECK" +msgstr "Unchecked" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::RES_HXX2SALOME_GENERIC_CLASS_NAME_TITLE" +msgstr "Sample HXX2SALOME_GENERIC_CLASS_NAME dialog" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::RES_HXX2SALOME_GENERIC_CLASS_NAME_TEXT" +msgstr "Preferences are: \n\tCheckbox: %1\n\tInteger: %2\n\tInteger2: %3\n\tDouble: %4\n\tText: %5" + +msgid "TLT_MY_NEW_ITEM" +msgstr "A HXX2SALOME_GENERIC_CLASS_NAME owned menu item" + +msgid "MEN_MY_NEW_ITEM" +msgstr "My menu" + +msgid "STS_MY_NEW_ITEM" +msgstr "Display a simple dialog" + +msgid "TLT_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" +msgstr "Open HXX2SALOME_GENERIC_CLASS_NAME dialog" + +msgid "MEN_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME dialog" + +msgid "STS_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" +msgstr "Open HXX2SALOME_GENERIC_CLASS_NAME dialog" + +msgid "MEN_FILE" +msgstr "&File" + +msgid "MEN_FILE_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME menu" + +msgid "MEN_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "TOOL_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME" + +#------------------------------------------------------------------------- +# PREFEERENCES +#------------------------------------------------------------------------- + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_TAB_GENERAL" +msgstr "General" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_GROUP_DEFAULTS" +msgstr "Default Values" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_BOOL" +msgstr "Check me" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_INTEGER" +msgstr "Type in integer:" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_SPININT" +msgstr "Click arrows (integer) :" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_SPINDBL" +msgstr "Click arrows (double) :" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_SELECTOR" +msgstr "Select an option" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_LIST_TEXT_0" +msgstr "First option" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_LIST_TEXT_1" +msgstr "Second option" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_LIST_TEXT_2" +msgstr "Third option" diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_fr.po b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_fr.po new file mode 100644 index 000000000..8ba648d45 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/HXX2SALOME_GENERIC_CLASS_NAME_msg_fr.po @@ -0,0 +1,99 @@ +# This is a Qt message file in .po format. Each msgid starts with +# a scope. This scope should *NOT* be translated - eg. translating +# from French to English, "Foo::Bar" would be translated to "Pub", +# not "Foo::Pub". +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2003-11-19 03:10:25 PM CET\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::BUT_OK" +msgstr "OK" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::BUT_CANCEL" +msgstr "Annuler" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_TITLE" +msgstr "Information HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_TEXT" +msgstr "Ceci est un simple test" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_CHECK" +msgstr "Cochée" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::INF_HXX2SALOME_GENERIC_CLASS_NAME_UNCHECK" +msgstr "Décochée" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::RES_HXX2SALOME_GENERIC_CLASS_NAME_TITLE" +msgstr "Dialogue example de HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::RES_HXX2SALOME_GENERIC_CLASS_NAME_TEXT" +msgstr "Les préférences sont : \n\tCase à cocher : %1\n\tEntier : %2\n\tEntier2 : %3\n\tDouble : %4\n\tTexte : %5" + +msgid "TLT_MY_NEW_ITEM" +msgstr "Un article de menu propre à HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "MEN_MY_NEW_ITEM" +msgstr "Mon menu" + +msgid "STS_MY_NEW_ITEM" +msgstr "Affiche une boîte de dialogue simple" + +msgid "TLT_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" +msgstr "Ouvre la boîte de dialogue de HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "MEN_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" +msgstr "Boîte de dialogue de HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "STS_HXX2SALOME_GENERIC_CLASS_NAME_ACTION" +msgstr "Ouvre la boîte de dialogue de HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "MEN_FILE" +msgstr "&File" + +msgid "MEN_FILE_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "Menu de HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "MEN_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME" + +msgid "TOOL_HXX2SALOME_GENERIC_CLASS_NAME" +msgstr "HXX2SALOME_GENERIC_CLASS_NAME" + +#------------------------------------------------------------------------- +# PREFEERENCES +#------------------------------------------------------------------------- + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_TAB_GENERAL" +msgstr "Général" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_GROUP_DEFAULTS" +msgstr "Valeurs par défaut" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_BOOL" +msgstr "Cochez-moi" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_INTEGER" +msgstr "Entrez un entier :" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_SPININT" +msgstr "Cliquez sur les flèches (entier) :" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_SPINDBL" +msgstr "Cliquez sur les flèches (double) :" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_DEFAULT_SELECTOR" +msgstr "Choisissez une option" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_LIST_TEXT_0" +msgstr "Première option" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_LIST_TEXT_1" +msgstr "Seconde option" + +msgid "HXX2SALOME_GENERIC_CLASS_NAMEGUI::PREF_LIST_TEXT_2" +msgstr "Troisième option" diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/Makefile.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAMEGUI/Makefile.am new file mode 100644 index 000000000..e69de29bb diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_CPP/Makefile.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_CPP/Makefile.am new file mode 100644 index 000000000..2bc010f0c --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_CPP/Makefile.am @@ -0,0 +1,12 @@ +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +USE_MED=0 + +AM_CXXFLAGS = -DXXX HXX2SALOME_INCLUDE -I${YACS_ROOT_DIR}/include/salome + +lib_LTLIBRARIES=libHXX2SALOME_GENERIC_CLASS_NAMELocal.la +libHXX2SALOME_GENERIC_CLASS_NAMELocal_la_SOURCES=HXX2SALOME_GENERIC_CLASS_NAME_CPP.cxx +libHXX2SALOME_GENERIC_CLASS_NAMELocal_la_LIBADD=HXX2SALOME_LIB + + + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/HXX2SALOME_GENERIC_CLASS_NAME_TEST.py b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/HXX2SALOME_GENERIC_CLASS_NAME_TEST.py new file mode 100755 index 000000000..2fb01b79d --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/HXX2SALOME_GENERIC_CLASS_NAME_TEST.py @@ -0,0 +1,7 @@ +mport salome +import HXX2SALOME_GENERIC_CLASS_NAME_ORB +myHXX2SALOME_GENERIC_CLASS_NAME = salome.lcc.FindOrLoadComponent("FactoryServer", "HXX2SALOME_GENERIC_CLASS_NAME") +# +# +print "Hello HXX2SALOME_GENERIC_CLASS_NAME" +# Test here some of HXX2SALOME_GENERIC_CLASS_NAME methods ... diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/HXX2SALOME_GENERIC_CLASS_NAME_i.cxx b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/HXX2SALOME_GENERIC_CLASS_NAME_i.cxx new file mode 100755 index 000000000..6c62f9447 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/HXX2SALOME_GENERIC_CLASS_NAME_i.cxx @@ -0,0 +1,59 @@ +#include "HXX2SALOME_GENERIC_CLASS_NAME_i.hxx" +// HXX2SALOME_CPP_INCLUDE +using namespace std; +#include + +#ifdef USE_MED +#include "FIELDClient.hxx" +#include "MESHClient.hxx" +#include "MEDMEM_Support_i.hxx" +#include "MEDMEM_Mesh_i.hxx" +#include "MEDMEM_FieldTemplate_i.hxx" +#endif + +#include "SenderFactory.hxx" +#include "MultiCommException.hxx" +#include "ReceiverFactory.hxx" +#include "SALOME_Matrix_i.hxx" +#include "MatrixClient.hxx" + +//============================================================================= +/*! + * standard constructor + */ +//============================================================================= +HXX2SALOME_GENERIC_CLASS_NAME_i::HXX2SALOME_GENERIC_CLASS_NAME_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName) : + Engines_Component_i(orb, poa, contId, instanceName, interfaceName),cppCompo_(new HXX2SALOME_GENERIC_CLASS_NAME) +{ + MESSAGE("activate object"); + _thisObj = this ; + _id = _poa->activate_object(_thisObj); +} + +HXX2SALOME_GENERIC_CLASS_NAME_i::~HXX2SALOME_GENERIC_CLASS_NAME_i() +{ +} + +// HXX2SALOME_CXX_CODE + + +extern "C" +{ + PortableServer::ObjectId * HXX2SALOME_GENERIC_CLASS_NAMEEngine_factory( + CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName) + { + MESSAGE("PortableServer::ObjectId * HXX2SALOME_GENERIC_CLASS_NAMEEngine_factory()"); + SCRUTE(interfaceName); + HXX2SALOME_GENERIC_CLASS_NAME_i * myHXX2SALOME_GENERIC_CLASS_NAME + = new HXX2SALOME_GENERIC_CLASS_NAME_i(orb, poa, contId, instanceName, interfaceName); + return myHXX2SALOME_GENERIC_CLASS_NAME->getId() ; + } +} diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/HXX2SALOME_GENERIC_CLASS_NAME_i.hxx b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/HXX2SALOME_GENERIC_CLASS_NAME_i.hxx new file mode 100644 index 000000000..7edb53449 --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/HXX2SALOME_GENERIC_CLASS_NAME_i.hxx @@ -0,0 +1,46 @@ +#ifndef __HXX2SALOME_GENERIC_CLASS_NAME_HXX_hxx2salome__ +#define __HXX2SALOME_GENERIC_CLASS_NAME_HXX_hxx2salome__ + +#include +#include CORBA_SERVER_HEADER(HXX2SALOME_GENERIC_CLASS_NAME_Gen) + +#ifdef USE_MED +#include CORBA_CLIENT_HEADER(MED) +#endif + +#include "SALOME_Component_i.hxx" +#include "SALOMEMultiComm.hxx" +class HXX2SALOME_GENERIC_CLASS_NAME; // forward declaration + +class HXX2SALOME_GENERIC_CLASS_NAME_i: + public POA_HXX2SALOME_GENERIC_CLASS_NAME_ORB::HXX2SALOME_GENERIC_CLASS_NAME_Gen, + public Engines_Component_i, + public SALOMEMultiComm +{ + +public: + HXX2SALOME_GENERIC_CLASS_NAME_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName); + virtual ~HXX2SALOME_GENERIC_CLASS_NAME_i(); + +// HXX2SALOME_HXX_CODE + +private: + std::auto_ptr cppCompo_; + +}; + + +extern "C" + PortableServer::ObjectId * HXX2SALOME_GENERIC_CLASS_NAMEEngine_factory( + CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName); + + +#endif diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/Makefile.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/Makefile.am new file mode 100644 index 000000000..66d149dda --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_I/Makefile.am @@ -0,0 +1,10 @@ +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +USE_MED=0 + +AM_CXXFLAGS = -fPIC @OMNIORB_INCLUDES@ @OMNIORB_CXXFLAGS@ -DXXX -I${top_builddir}/idl -I${top_builddir}/adm_local/unix -I ${KERNEL_ROOT_DIR}/include/salome HXX2SALOME_INCLUDE + +lib_LTLIBRARIES=libHXX2SALOME_GENERIC_CLASS_NAMEEngine.la +libHXX2SALOME_GENERIC_CLASS_NAMEEngine_la_SOURCES=HXX2SALOME_GENERIC_CLASS_NAME_i.cxx +libHXX2SALOME_GENERIC_CLASS_NAMEEngine_la_LIBADD=-L${top_builddir}/idl -lHXX2SALOME_GENERIC_CLASS_NAMESK HXX2SALOME_LIB + diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_SWIG/Makefile.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/HXX2SALOME_GENERIC_CLASS_NAME_SWIG/Makefile.am new file mode 100644 index 000000000..e69de29bb diff --git a/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/Makefile.am b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/Makefile.am new file mode 100644 index 000000000..490d134ee --- /dev/null +++ b/src/wrappergen/src/HXX2SALOME_GENERIC_CLASS_NAME_SRC/src/Makefile.am @@ -0,0 +1,29 @@ +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +if SALOME_KERNEL + SUBDIRS=idl + DIST_SUBDIRS=idl +else + SUBDIRS= + DIST_SUBDIRS= +endif + +SUBDIRS += adm_local src doc bin resources +DIST_SUBDIRS += adm_local src doc bin resources + +DISTCLEANFILES = a.out + +install-exec-local: + cp ${srcdir}/env_HXX2SALOME_GENERIC_CLASS_NAME.sh ${prefix} + +dist-hook: + rm -rf `find $(distdir) -name CVS` + +usr_docs: + (cd doc && $(MAKE) $(AM_MAKEFLAGS) usr_docs) + +docs:usr_docs + +dev_docs: + (cd doc && $(MAKE) $(AM_MAKEFLAGS) dev_docs) + diff --git a/src/wrappergen/src/Makefile.am b/src/wrappergen/src/Makefile.am new file mode 100644 index 000000000..cbb844717 --- /dev/null +++ b/src/wrappergen/src/Makefile.am @@ -0,0 +1,33 @@ +bindir=${prefix}/bin/HXX2SALOME_Test + +ENV_SH=${bindir}/env_HXX2SALOME.sh +ENV_CSH=${bindir}/env_HXX2SALOME.csh + +bin_SCRIPTS= hxx2salome hxx2salome_check hxx2salome_cpp hxx2salome_corba \ + parse01.awk \ + parse0.awk \ + parse1.awk \ + parse2.awk \ + parse30.awk \ + parse3.awk \ + parse4.awk \ + parse5.awk \ + renameSalomeModule \ + runIDLparser \ + compile_HXX2SALOME_GENERIC_CLASS_NAME.sh + + +install-exec-hook: install_sh install_csh + \cp -rf ${srcdir}/HXX2SALOME_GENERIC_CLASS_NAME_SRC ${bindir} + +install_sh: + echo "#------ HXX2SALOME ------" > ${ENV_SH} + echo "export HXX2SALOME_ROOT_DIR=${bindir}" >> ${ENV_SH} + echo "export PATH=\$${HXX2SALOME_ROOT_DIR}:\$${PATH}" >> ${ENV_SH} + echo "##" >> ${ENV_SH} + +install_csh: + echo "#------ HXX2SALOME ------" > ${ENV_CSH} + echo "setenv HXX2SALOME_ROOT_DIR ${bindir}" >> ${ENV_CSH} + echo "setenv PATH \$${HXX2SALOME_ROOT_DIR}:\$${PATH}" >> ${ENV_CSH} + echo "##" >> ${ENV_CSH} diff --git a/src/wrappergen/src/compile_HXX2SALOME_GENERIC_CLASS_NAME.sh b/src/wrappergen/src/compile_HXX2SALOME_GENERIC_CLASS_NAME.sh new file mode 100644 index 000000000..ca5df9e59 --- /dev/null +++ b/src/wrappergen/src/compile_HXX2SALOME_GENERIC_CLASS_NAME.sh @@ -0,0 +1,35 @@ +#! /bin/bash + +export BASE=PREFIX/tests +export COMP_NAME=HXX2SALOME_GENERIC_CLASS_NAME +export COMP_BASE=${BASE}/${COMP_NAME} + +cd ${COMP_BASE} +export HXX2SALOME_ROOT_DIR=PREFIX/bin/HXX2SALOME_Test + +if [ ! -d ${COMP_NAME}_SRC ] ; then + ${HXX2SALOME_ROOT_DIR}/hxx2salome -q -q \ + ${BASE} \ + ${COMP_NAME}.hxx \ + lib${COMP_NAME}.so \ + ${BASE} +fi + +cd ${COMP_BASE} +if [ ! -f ${COMP_NAME}_SRC/configure ] ; then + cd ${COMP_NAME}_SRC && ./build_configure +fi + +cd ${COMP_BASE} +source ${COMP_NAME}_SRC/env_${COMP_NAME}.sh + +if [ ! -f ${COMP_NAME}_BUILD/config.log ] ; then + cd ${COMP_NAME}_BUILD && \ + ../${COMP_NAME}_SRC/configure \ + --prefix=${COMP_BASE}/${COMP_NAME}_INSTALL +fi + +cd ${COMP_BASE}/${COMP_NAME}_BUILD +make && make install + + diff --git a/src/wrappergen/src/hxx2salome b/src/wrappergen/src/hxx2salome new file mode 100755 index 000000000..d509aabae --- /dev/null +++ b/src/wrappergen/src/hxx2salome @@ -0,0 +1,457 @@ +#! /bin/bash +# +# +BE_QUIET=0 +# salome2 environment file (.bash or .sh) - can also be specified with -e option +ENVIRON_FILE= +# if present, hxx2salome will try to compile new module, by sourcing ENVIRON_FILE file, and executing +# build_configure, configure, make & make install +# remark : hxx2salome has to be lanched with clean PATH, LD_LIBRARY_PATH & PYTHONPATH variables! +# +# options you want to pass to configure +CONFIGURE_OPTION= +# +# which wrappers to generate +declare -a GEN + +iCPP=0 +iCORBA=1 +iPython=2 + +GEN[${iCPP}]="no" +GEN[${iCORBA}]="no" +GEN[${iPython}]="no" + + +# +usage() +{ + echo -e "\n Usage :\n" + echo -e " Set HXX2SALOME_ROOT_DIR variable" + echo -e " ${HXX2SALOME_ROOT_DIR}/hxx2salome [options] " + echo -e " cppComponent_root_dir cppComponent.hxx" + echo -e " libcppComponent.so salomeComponentRoot\n" + echo -e " - cppComponent_root_dir : install directory (absolute path)" + echo -e " of the c++ component\n" + echo -e " - cppComponent.hxx : header of the component" + echo -e " - libcppComponent.so : library\n" + echo -e " (cppComponent.hxx and libcppComponent.so have to be found" + echo -e " in cppComponent_root_dir)\n" + echo -e " - salomeComponentRoot : directory of the source/build/install" + echo -e " of the Salome component\n" + echo -e " Options :" + echo -e " -h : this help" + echo + echo -e " -q : be quiet" + echo + echo -e " -x Lang : generate a wrapper to use the component" + echo -e " from language Lang where Lang can be " + echo -e " any of CORBA,C++,python" + echo -e " (several -x options can be specified)" + echo -e " default : generate all wrappers" + echo + + echo -e " -e environment_script : to specify the name of a environment file" + echo -e " that will be updated with new necessary commands" + echo -e " (this file is also used for sourcing environment" + echo -e " before compilation if it has sh or bash syntax," + echo -e " if the syntax is csh, it is not sourced and for" + echo -e " compiling (-c option) environment must be set up" + echo -e " before)" + echo + echo -e " -s script_extension : to use if your environment file name doesn't" + echo -e " have extension" + echo + echo -e " -g : to create a gui part in your component" + echo -e " building tree" + echo + echo -e " -c : to compile after generation" + echo -e " (use this option only if you don't have" + echo -e " dependencies in your header or libraries" + echo -e " if it is the case, you'll have to adapt" + echo -e " your Makefile.am" + echo + echo -e " -l : to launch salome " + exit +} +# +welcome() +{ + echo -e "\n\n" + echo "----------------------------------------------------------------------------" + echo + echo " hxx2salome" + echo + echo " Automatic generation of a Salome2 component from a C++ component" + echo + echo "----------------------------------------------------------------------------" + echo + echo + echo +} + +if [ "x$HXX2SALOME_ROOT_DIR" == "x" ] +then + usage +fi + +source ${HXX2SALOME_ROOT_DIR}/hxx2salome_check +source ${HXX2SALOME_ROOT_DIR}/hxx2salome_corba +source ${HXX2SALOME_ROOT_DIR}/hxx2salome_cpp + + +# retrieve python test file ending up with _test.py +get_python_test_file() +{ + cd ${CPP_ROOT_DIR} + for file in `find . -name "*_test.py"` + do + cp $file ${tmp_dir}/${CLASS_NAME}_SRC/src/${CLASS_NAME} + python_test_file=${python_test_file}" "`basename $file` + done + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\nList of exported python file test : $python_test_file \n" + fi + cd - +} + +create_component_tree() +{ + INSTALL_DIR=${salomeComponentRoot}/${CLASS_NAME} + + export NEW_COMPONENT_SRC_DIR=${INSTALL_DIR}/${CLASS_NAME}_SRC + export NEW_COMPONENT_BUILD_DIR=${INSTALL_DIR}/${CLASS_NAME}_BUILD + export NEW_COMPONENT_ROOT_DIR=${INSTALL_DIR}/${CLASS_NAME}_INSTALL + + \rm -rf ${NEW_COMPONENT_SRC_DIR} + mkdir -p ${NEW_COMPONENT_SRC_DIR} +} + + +get_info_makefile() +{ + makefile_lib="-L\${${CLASS_NAME}CPP_ROOT_DIR}${lib_dir#${CPP_ROOT_DIR}} -l${lib_file}" + makefile_include="-I\${${CLASS_NAME}CPP_ROOT_DIR}${hxx_dir#${CPP_ROOT_DIR}}" + + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\nlinking option : $makefile_lib" + echo -e "include option : $makefile_include" + fi +} + + +generate_module_source() +{ + +# +# go in temporary directory to work on code generation + cd ${tmp_dir} +# +# +# ------------------------- parse hxx file : generic part --------------------------------------- +# + cat ${hxx_file} | \ + awk -f ${gene_dir}/parse01.awk | \ + awk -f ${gene_dir}/parse1.awk | \ + awk -f ${gene_dir}/parse2.awk \ + > temp + sed -e "/${CLASS_NAME}/d" < temp > ${CLASS_NAME}_public_functions + + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n-> Extract public functions\n" + fi + if [ ! -s ${CLASS_NAME}_public_functions ] + then + echo -e "\nError:" + echo -e " Sorry - No compatible function was found!" + echo -e " Please check your header file\n" + exit + fi + + echo -e "\n\n-> Compatibility function\n" + cat ${CLASS_NAME}_public_functions | \ + awk -v class_name=${CLASS_NAME} -f ${gene_dir}/parse30.awk + + \rm -f hxx2salome_journal && touch hxx2salome_journal + + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n-> Duplicate template module" | tee ../hxx2salome_journal + fi + cp -rf ${gene_dir}/HXX2SALOME_GENERIC_CLASS_NAME_SRC ${CLASS_NAME}_SRC + cp -f ${gene_dir}/compile_HXX2SALOME_GENERIC_CLASS_NAME.sh compile_${CLASS_NAME}.sh + ${gene_dir}/renameSalomeModule -i HXX2SALOME_GENERIC_CLASS_NAME \ + ${CLASS_NAME} ${CLASS_NAME}_SRC >> ../hxx2salome_journal + + GEN=( `validate_generation_choices ${GEN[${iCPP}]} ${GEN[${iCORBA}]} ${GEN[${iPython}]}` ) + echo "-> Wrappers generation : " C++ : ${GEN[${iCPP}]} CORBA : ${GEN[${iCORBA}]} Python : ${GEN[${iPython}]} + + if [ "x${GEN[${iCORBA}]}" == "xyes" ] ; then + generate_corba_module_source + else + clean_corba_module_source + fi + + if [ "x${GEN[${iCPP}]}" == "xyes" ] ; then + generate_cpp_module_source + else + clean_cpp_module_source + fi +} + +compile() +{ + echo "----------------- Configure -------------------" + + echo "----------------- Compile ---------------------" + make + if [ $? -eq 0 ] + then + # compilation succeeded : we make install + echo + echo "----------------- Install ---------------------" + make install + else + exit 1 + fi +} + +update_environment() +{ + if [ -z ${ENVIRON_FILE} ] + then + ENVIRON_FILE="${NEW_COMPONENT_SRC_DIR}/env_${CLASS_NAME}.${SHELL_EXT}" + fi + + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\nEnvironment file : " $ENVIRON_FILE + fi + if [ -e ${ENVIRON_FILE} ] + then + cp ${ENVIRON_FILE} ${ENVIRON_FILE}.old + fi + touch ${ENVIRON_FILE} + + if [ "${SHELL_EXT}" == "csh" ] + then + grep -q " ${CLASS_NAME}_SRC_DIR" ${ENVIRON_FILE} + res=$? + if [ $res == 1 ] + then + echo -e "###\n#------ ${CLASS_NAME}-Src ------" >> ${ENVIRON_FILE} + echo -e "setenv ${CLASS_NAME}_BASE ${INSTALL_DIR}" >> ${ENVIRON_FILE} + echo -e "setenv ${CLASS_NAME}_SRC_DIR \${${CLASS_NAME}_BASE}/${CLASS_NAME}_SRC\n" >> ${ENVIRON_FILE} + fi + + grep -q " ${CLASS_NAME}_ROOT_DIR" ${ENVIRON_FILE} + res=$? + if [ $res == 1 ] + then + echo -e "###\n#------ ${CLASS_NAME}-Bin ------" >> ${ENVIRON_FILE} + echo -e "setenv ${CLASS_NAME}_ROOT_DIR \${${CLASS_NAME}_BASE}/${CLASS_NAME}_INSTALL" >> ${ENVIRON_FILE} + echo -e "setenv ${CLASS_NAME}CPP_ROOT_DIR ${CPP_ROOT_DIR}" >> ${ENVIRON_FILE} + echo -e "setenv LD_LIBRARY_PATH \${${CLASS_NAME}CPP_ROOT_DIR}${lib_dir#${CPP_ROOT_DIR}}:\${LD_LIBRARY_PATH}" >> ${ENVIRON_FILE} + fi + fi + if [ "${SHELL_EXT}" == "sh" ] + then + grep -q " ${CLASS_NAME}_SRC_DIR=" ${ENVIRON_FILE} + res=$? + if [ $res == 1 ] + then + echo -e "###\n#------ ${CLASS_NAME}-Src ------" >> ${ENVIRON_FILE} + echo -e "export ${CLASS_NAME}_BASE=${INSTALL_DIR}" >> ${ENVIRON_FILE} + echo -e "export ${CLASS_NAME}_SRC_DIR=\${${CLASS_NAME}_BASE}/${CLASS_NAME}_SRC\n" >> ${ENVIRON_FILE} + fi + + grep -q " ${CLASS_NAME}_ROOT_DIR=" ${ENVIRON_FILE} + res=$? + if [ $res == 1 ] + then + echo -e "###\n#------ ${CLASS_NAME}-Bin ------" >> ${ENVIRON_FILE} + echo -e "export ${CLASS_NAME}_ROOT_DIR=\${${CLASS_NAME}_BASE}/${CLASS_NAME}_INSTALL" >> ${ENVIRON_FILE} + echo -e "export ${CLASS_NAME}CPP_ROOT_DIR=${CPP_ROOT_DIR}" >> ${ENVIRON_FILE} + echo -e "export LD_LIBRARY_PATH=\${${CLASS_NAME}CPP_ROOT_DIR}${lib_dir#${CPP_ROOT_DIR}}:\${LD_LIBRARY_PATH}" \ + >> ${ENVIRON_FILE} + fi + + fi +} + +copy_component_source() +{ + mv ${tmp_dir}/${CLASS_NAME}_SRC/* ${NEW_COMPONENT_SRC_DIR} + mkdir -p ${NEW_COMPONENT_BUILD_DIR} + mkdir -p ${NEW_COMPONENT_ROOT_DIR} +} + +good_bye() +{ + + if [ ${BE_QUIET} -gt 0 ] ; then + return + fi + echo -e "\n\nModule was created in ${NEW_COMPONENT_SRC_DIR}" +} + + +# +# +# ------------------------------------------------------------------------ +# --------------------------- MAIN PROGRAM ------------------------------- +# ------------------------------------------------------------------------ +# +CPP_ROOT_DIR= +NEW_COMPONENT_ROOT_DIR= +NEW_COMPONENT_SRC_DIR= +NEW_COMPONENT_BUILD_DIR= +SHELL_EXT=sh +do_compile=0 +do_launch=0 + +make_gui=0 + +# +welcome # print some welcome info +# +while getopts "qcs:e:h:lgx:" Option +do + case $Option in + h) usage + exit;; + q) BE_QUIET=$[ ${BE_QUIET}+1 ] ;; + e) ENVIRON_FILE=$OPTARG;; + s) case $OPTARG in + bash) SHELL_EXT=sh;; + csh) SHELL_EXT=csh;; + *) SHELL_EXT=sh;; + esac;; + g) make_gui=1;; + c) do_compile=1;; + l) do_launch=1;; + x) case $OPTARG in + CORBA) GEN[$iCORBA]="yes" ;; + python) GEN[$iPython]="yes" ;; + C++) GEN[${iCPP}]="yes";; + *) ;; + esac;; + *) echo "Unimplemented option chosen : $Option." + usage + exit;; # DEFAULT + esac +done + +shift $(($OPTIND - 1)) + +# default behaviour is to generate all wrappers +# +if [ "x${GEN[${iCPP}]}${GEN[${iCORBA}]}${GEN[${iPython}]}" == "xnonono" ] ; then + for i in ${iCPP} ${iCORBA} ${iPython} + do + GEN[$i]="yes" + done +fi +echo "-> Wrappers generation : " C++ : ${GEN[${iCPP}]} CORBA : ${GEN[${iCORBA}]} Python : ${GEN[${iPython}]} +echo +echo + +# check number of other arguments +# +if [ $# -ne 4 ] +then + echo -e "\nBad number of arguments\n\n" + usage + exit +fi + +check_arguments $1 $2 $3 $4 +# +# if there is a sh compatible environment file, source it +if [[ -n ${ENVIRON_FILE} && -f ${ENVIRON_FILE} ]] +then + # analyse extension of environment file + case ${ENVIRON_FILE##*\.} in + bash) SHELL_EXT=sh;; + ksh) SHELL_EXT=sh;; + csh) SHELL_EXT=csh;; + sh) SHELL_EXT=sh;; + esac +fi + +# Environment policy : +# - an existing sh file was specified : we source environment file +# - else (no file or csh syntax) : we don't source environment file, and do compile +# only if KERNEL_ROOT_DIR and MED_ROOT_DIR are defined +if [ "${SHELL_EXT}" == "sh" ] && [ ${ENVIRON_FILE} ] && [ -f ${ENVIRON_FILE} ] +then + echo -e "\n Environment file with sh syntax specified => we source ${ENVIRON_FILE}" + source ${ENVIRON_FILE} +fi + +# +if [ ${HXX2SALOME_ROOT_DIR} ] && [ -d ${HXX2SALOME_ROOT_DIR} ] +then + gene_dir=${HXX2SALOME_ROOT_DIR} +else + gene_dir=`pwd` # case where hxx2salome was launched from HXX2SALOME directory +fi +OLD_DIR=`pwd` +cd $gene_dir +gene_dir=`pwd` +cd $OLD_DIR + +if [ ${BE_QUIET} -lt 1 ] ; then + echo " hxx2salome directory : $gene_dir" +fi +if [ ! -f ${gene_dir}/parse1.awk -o ! -f ${gene_dir}/parse2.awk ] # check if script are found +then + echo -e "\nError : Variable HXX2SALOME_ROOT_DIR shoud be set, or hxx2salome should be launched localy from bin directory" + usage +fi +# +# get class name +# +CLASS_NAME=`awk '$1 == "class" && $0 !~ /;/ {print $2}' ${hxx_file}|awk -F: '{print $1}'` +echo " Name of class :" $CLASS_NAME +if [ ! $CLASS_NAME ] +then + echo -e "\nError:\n Sorry - No class definition was found!\n Please check your header file\n" + exit +fi + +# +# create temporary working directory +# +tmp_dir="/tmp/${USER}/${CLASS_NAME}" +if [ -d ${tmp_dir} ] +then + rm -rf ${tmp_dir}/* +else + mkdir -p ${tmp_dir} +fi + +# +# --------------------- Generation of module source from template ------------------------------------------ +# +get_info_makefile +generate_module_source + +# +# ---------------------- Installation of new module sources ------------------------------------------------ +# +create_component_tree + +# +# ---------------------- Modification of Salome environment file ------------------------------------------- +# +update_environment +export `echo ${CLASS_NAME}`_ROOT_DIR=${NEW_COMPONENT_ROOT_DIR} # to avoid resource env for compiling and launching salome +export `echo ${CLASS_NAME}`CPP_ROOT_DIR=${CPP_ROOT_DIR} # idem +# +# ---------------------- Copy the generated source from temp dir ------------------------------------------- +# +copy_component_source + +good_bye + + +echo -e "\nGeneration done\n" diff --git a/src/wrappergen/src/hxx2salome_check b/src/wrappergen/src/hxx2salome_check new file mode 100644 index 000000000..390f675f4 --- /dev/null +++ b/src/wrappergen/src/hxx2salome_check @@ -0,0 +1,96 @@ +check_arguments() +{ + # check if $1 is a directory + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "-> check arguments\n" + fi + if [ ! -d $1 ] + then + echo -e "Error : directory $1 does not exist!\n" + usage + fi + CPP_ROOT_DIR=${1%%/} # remove trailing slash if present + OLD_DIR=`pwd` + cd $CPP_ROOT_DIR + CPP_ROOT_DIR=`pwd` + cd $OLD_DIR + if [ ${BE_QUIET} -lt 2 ] ; then + echo " C++ Component directory : ${CPP_ROOT_DIR}" + fi + + # look for include file $2 - check number of files found and extension + nb=`find ${CPP_ROOT_DIR} -name $2 | wc -l` # number of files found, should be equal to 1 + extension=${2##*\.} + if [ $nb -eq 0 ] + then + echo -e "\n Error:\n Include file $2 not found in $1 directory!\n" + usage + elif [ $nb -ge 2 ] + then + echo -e "\n Error:\n More than one file named $2 was found in $1!\n Include file should be unique!" + usage + elif [ $extension != "hxx" -a $extension != "hh" -a $extension != "h" ] + then + echo -e "\n Error:\n Extension=$extension\n Include file $2 should have extension .hxx .hh or .h !\n" + usage + fi + hxx_file=`find ${CPP_ROOT_DIR} -name $2` # name of c++ header we will parse to generate salome module + hxx=$2 + if [ ${BE_QUIET} -lt 2 ] ; then + echo " C++ Component header : ${hxx_file}" + fi + hxx_dir=`dirname ${hxx_file}` + + # look for library $3 + nb=`find ${CPP_ROOT_DIR} -name $3 | wc -l` # number of files found, should be equal to 1 + if [ $nb -eq 0 ] + then + echo -e "\n Error:\n Library file $3 not found in $1 directory!\n" + usage + elif [ $nb -ge 2 ] + then + echo -e "\n Error:\n More than one file named $3 was found in $1!\n Library file should be unique!" + usage + fi + so_file=`find ${CPP_ROOT_DIR} -name $3` # absolute path of library containing c++ module + if [ ${BE_QUIET} -lt 2 ] ; then + echo " C++ Component library : ${so_file}" + fi + lib_dir=`dirname ${so_file}` + lib_file=${3%.so} # name without .so + lib_file=${lib_file#lib} # name of library without lib and .so (needed by makefile) + + # installation directory + if [[ ! -d $4 ]] + then + mkdir -p $4 + fi + salomeComponentRoot=${4%%/} # remove trailing slash + OLD_DIR=`pwd` + cd $salomeComponentRoot + salomeComponentRoot=`pwd` + cd $OLD_DIR + if [ ${BE_QUIET} -lt 2 ] ; then + echo " Salome Component directory : ${salomeComponentRoot}" + fi +} + +validate_generation_choices() +{ + declare -a arr + arr=( `echo "$@"` ) + + echo "$@" + if [ x${arr[$iCORBA]} == "xyes" ] + then + if [ "x${KERNEL_ROOT_DIR}" == "x" ] + then + arr[$iCORBA]="no" + else + if [ ! -f ${KERNEL_ROOT_DIR}/idl/salome/SALOME_Component.idl ] + then + arr[$iCORBA]="no" + fi + fi + fi +} diff --git a/src/wrappergen/src/hxx2salome_corba b/src/wrappergen/src/hxx2salome_corba new file mode 100644 index 000000000..b33cdd791 --- /dev/null +++ b/src/wrappergen/src/hxx2salome_corba @@ -0,0 +1,134 @@ +generate_corba_module_source() +{ + cd ${tmp_dir} + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n\n\tCorba wrapper generation" + fi +# +# ------------------------- Corba generation ------------------------------------------------------ + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n\n-> Generate Salome2 Corba files\n" + fi + cat ${CLASS_NAME}_public_functions |\ + awk -v class_name=${CLASS_NAME} -f ${gene_dir}/parse3.awk + + if [ `grep -c MEDMEM:: ${CLASS_NAME}_public_functions` -gt 0 ] + then + USE_MED=1 + else + USE_MED=0 + fi + +# outputs + + cat parse_result >> hxx2salome_journal + echo -e "\n----------------- IDL file ------------------\n" >> hxx2salome_journal + cat code_idl >> hxx2salome_journal + echo -e "\n----------------- hxx file ------------------\n" >> hxx2salome_journal + cat code_hxx >> hxx2salome_journal + echo -e "\n----------------- cxx file ------------------\n" >> hxx2salome_journal + cat code_cxx >> hxx2salome_journal + + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n IDL file:" + cat code_idl + echo + fi + + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n-> Substitute generated code in idl file" + fi + echo "// this idl file was generated by hxx2salome" > tmpfile + cat ${CLASS_NAME}_SRC/idl/${CLASS_NAME}_Gen.idl |awk \ + '$0 ~ "HXX2SALOME_IDL_CODE" {system("cat code_idl >> tmpfile")} + $0 != "HXX2SALOME_IDL_CODE" { print $0 >> "tmpfile" }' + mv tmpfile ${CLASS_NAME}_SRC/idl/${CLASS_NAME}_Gen.idl +# + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n-> Substitute generated code in hxx file" + fi + echo "// this hxx file was generated by hxx2salome" > tmpfile + cat ${CLASS_NAME}_SRC/src/${CLASS_NAME}_I/${CLASS_NAME}_i.hxx |awk ' + $0 ~ "HXX2SALOME_HXX_CODE" {system("cat code_hxx >> tmpfile")} + $0 !~ "HXX2SALOME" { print $0 >> "tmpfile" }' + mv tmpfile ${CLASS_NAME}_SRC/src/${CLASS_NAME}_I/${CLASS_NAME}_i.hxx +# + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n-> Substitute generated code in cxx file" + fi + echo "// this cxx file was generated by hxx2salome" > tmpfile + cat ${CLASS_NAME}_SRC/src/${CLASS_NAME}_I/${CLASS_NAME}_i.cxx |awk -v cpp_include=$hxx ' + $0 ~ "HXX2SALOME_CXX_CODE" {system("cat code_cxx >> tmpfile")} + $0 ~ "HXX2SALOME_CPP_INCLUDE" { printf "#include \"%s\"\n",cpp_include >> "tmpfile" } + $0 !~ "HXX2SALOME" { print $0 >> "tmpfile" }' + mv tmpfile ${CLASS_NAME}_SRC/src/${CLASS_NAME}_I/${CLASS_NAME}_i.cxx + + get_info_makefile + + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n-> Substitute flags in Makefile.am files" + fi + +# Root Makefile.am + sed -e "s/SUBDIRS = /SUBDIRS = ${CLASS_NAME}_I/" \ + < ${CLASS_NAME}_SRC/src/Makefile.am \ + > ${CLASS_NAME}_SRC/src/Makefile.am_new + \mv -f ${CLASS_NAME}_SRC/src/Makefile.am_new \ + ${CLASS_NAME}_SRC/src/Makefile.am + +# IDL Makefile.am + if [ ${USE_MED} == 1 ] + then + sed "s?USE_MED=0?USE_MED=1\nIDL_FILES += MED.idl\nIDL_SRC += MEDSK.cc?" ${CLASS_NAME}_SRC/idl/Makefile.am > tmpfile + sed "s?XXX?XXX -DUSE_MED -I\${MED_ROOT_DIR}/idl/salome?" tmpfile > tmp2file + mv tmp2file ${CLASS_NAME}_SRC/idl/Makefile.am + fi + +# C++ implementation Makefile.am + sed "s?HXX2SALOME_INCLUDE?${makefile_include}?g + s?HXX2SALOME_PYTHON_FILE?${python_test_file}?g + s?HXX2SALOME_LIB?${makefile_lib}?g + " ${CLASS_NAME}_SRC/src/${CLASS_NAME}_I/Makefile.am > tmpfile + sed "s?XXX?XXX -I$hxx_dir?" tmpfile > tmp2file + if [ ${BE_QUIET} -lt 1 ] ; then + cat ${CLASS_NAME}_public_functions + fi + if [ ${USE_MED} == 1 ] + then + sed "/AM_CXXFLAGS/s?\$? -DUSE_MED \${MED2_INCLUDES} -I\${MED_ROOT_DIR}/include/salome?" tmp2file > tmpfile + sed "s?USE_MED=0?USE_MED=1?" tmpfile > tmp2file + fi + mv tmp2file ${CLASS_NAME}_SRC/src/${CLASS_NAME}_I/Makefile.am + \rm -f tmpfile tmp2file +# +# generate component catalog + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n-> Generate component catalog" | tee hxx2salome_journal + fi + if [ -f ${KERNEL_ROOT_DIR}/bin/salome/runIDLparser ] + then + idlparser=${KERNEL_ROOT_DIR}/bin/salome/runIDLparser + else + idlparser=${gene_dir}/runIDLparser + fi + if [ ${USE_MED} == 1 ] + then + idlparser="${idlparser} -DUSE_MED=1 -I${MED_ROOT_DIR}/idl/salome" + fi + + cd ${CLASS_NAME}_SRC/resources + VER=`cat ${KERNEL_ROOT_DIR}/bin/salome/VERSION | awk ' { print $NF }'` # extract number of version + ${idlparser} -Wbcatalog=tmp.xml,icon=${CLASS_NAME}.png,version=${VER} -I${KERNEL_ROOT_DIR}/idl/salome ../idl/${CLASS_NAME}_Gen.idl >& /dev/null | tee hxx2salome_journal + cat tmp.xml | sed 's/_Gen//g' > ${CLASS_NAME}Catalog.xml + \rm -f tmp.xml + +} + +clean_corba_module_source() +{ + \rm -rf ${CLASS_NAME}_SRC/src/${CLASS_NAME}_I + \rm -rf ${CLASS_NAME}_SRC/idl/* + touch ${CLASS_NAME}_SRC/idl/Makefile.am + sed -e "s/^CHECK_OMNIORB/dnl CHECK_OMNIORB/" -e "/CORBA/s/^/dnl /" ${CLASS_NAME}_SRC/configure.in.base > ${CLASS_NAME}_SRC/configure.in.temp + mv ${CLASS_NAME}_SRC/configure.in.temp ${CLASS_NAME}_SRC/configure.in.base +} diff --git a/src/wrappergen/src/hxx2salome_cpp b/src/wrappergen/src/hxx2salome_cpp new file mode 100644 index 000000000..c71a94a2e --- /dev/null +++ b/src/wrappergen/src/hxx2salome_cpp @@ -0,0 +1,56 @@ +generate_cpp_module_source() +{ + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n\n\tC++ wrapper generation" + fi + cd ${tmp_dir} +# +# ------------------------- C++ generation ------------------------------------------------------ + sed -e "s/SUBDIRS = /SUBDIRS = ${CLASS_NAME}_CPP /" < ${CLASS_NAME}_SRC/src/Makefile.am > ${CLASS_NAME}_SRC/src/tmpfile + \mv -f ${CLASS_NAME}_SRC/src/tmpfile ${CLASS_NAME}_SRC/src/Makefile.am + + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n\n-> Generate Salome2 C++ files\n" + fi + cat ${CLASS_NAME}_public_functions |\ + awk -v class_name=${CLASS_NAME} -f ${gene_dir}/parse4.awk + echo "#include \""`basename ${hxx_file}`"\"" > ${CLASS_NAME}_SRC/src/${CLASS_NAME}_CPP/${CLASS_NAME}_CPP.cxx + echo >> ${CLASS_NAME}_SRC/src/${CLASS_NAME}_CPP/${CLASS_NAME}_CPP.cxx + + cat code_dispatch >> ${CLASS_NAME}_SRC/src/${CLASS_NAME}_CPP/${CLASS_NAME}_CPP.cxx + get_info_makefile + + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n-> Substitute flags in Makefile.am" + fi + sed "s?HXX2SALOME_INCLUDE?${makefile_include}?g + s?HXX2SALOME_PYTHON_FILE?${python_test_file}?g + s?HXX2SALOME_LIB?${makefile_lib}?g + " ${CLASS_NAME}_SRC/src/${CLASS_NAME}_CPP/Makefile.am > tmpfile + sed "s?XXX?XXX -I$hxx_dir?" tmpfile > tmp2file + + if [ "x${USE_MED}" == "x1" ] + then + sed "/AM_CXXFLAGS/s?\$? -DMED_WITHOUT_KERNEL -DUSE_MED \${MED2_INCLUDES} -I\${MED_ROOT_DIR}/include/salome?" tmp2file > tmpfile + sed "s?USE_MED=0?USE_MED=1?" tmpfile > tmp2file + fi + mv tmp2file ${CLASS_NAME}_SRC/src/${CLASS_NAME}_CPP/Makefile.am + \rm -f tmpfile tmp2file + + if [ ${BE_QUIET} -lt 1 ] ; then + echo -e "\n-> XML Catalog generation" + fi + cat ${CLASS_NAME}_public_functions | awk -v class_name=${CLASS_NAME} -f ${gene_dir}/parse5.awk + mv catalog.xml ${CLASS_NAME}_SRC/resources/${CLASS_NAME}Catalog.xml + + echo "" >> ${CLASS_NAME}_SRC/resources/Makefile.am + echo "${CLASS_NAME}Catalog.xml: \${srcdir}/${CLASS_NAME}Catalog.xml" >> ${CLASS_NAME}_SRC/resources/Makefile.am + echo " cp \$^ \$@" >> ${CLASS_NAME}_SRC/resources/Makefile.am + +} + +clean_cpp_module_source() +{ + \rm -rf ${CLASS_NAME}_SRC/src/${CLASS_NAME}_CPP +} + diff --git a/src/wrappergen/src/parse0.awk b/src/wrappergen/src/parse0.awk new file mode 100755 index 000000000..ae194f4e7 --- /dev/null +++ b/src/wrappergen/src/parse0.awk @@ -0,0 +1,8 @@ +# This awk program suppresses inline functions - but it doen't work if there is no inline function... Not used yet. +BEGIN { RS="\f"} + +{ gsub(/{[^{}]*}[ \t]*;?/,";");print } + +#{ gsub(/[ \t]+&/,"\\& ") +# gsub(/[ \t]+\*/,"* ") +# print $0 } diff --git a/src/wrappergen/src/parse01.awk b/src/wrappergen/src/parse01.awk new file mode 100755 index 000000000..8bec01785 --- /dev/null +++ b/src/wrappergen/src/parse01.awk @@ -0,0 +1,20 @@ +# This awk program deletes C like comments '*/ ... /*' +{ + if (t = index($0, "/*")) { + if (t > 1) + tmp = substr($0, 1, t - 1) + else + tmp = "" + u = index(substr($0, t + 2), "*/") + while (u == 0) { + getline + t = -1 + u = index($0, "*/") + } + if (u <= length($0) - 2) + $0 = tmp substr($0, t + u + 3) + else + $0 = tmp + } + print $0 +} diff --git a/src/wrappergen/src/parse1.awk b/src/wrappergen/src/parse1.awk new file mode 100755 index 000000000..8d688d25f --- /dev/null +++ b/src/wrappergen/src/parse1.awk @@ -0,0 +1,24 @@ +# This awk program extract public functions of the class definition present in hxx interface + +BEGIN { public=0 } + +# we want to extract each function that is public and that does'nt contain +# the patterns : public, protected, private, // (comments), { and } +public == 1 && +$1 !~ /public/ && +$1 !~ /protected/ && +$1 !~ /private/ && +$1 !~ /\/\/*/ && +$1 !~ /{|}/ { + for (i=1; i<=NF; i++) + printf "%s ", $i +# change line if last field contains ";" -> one function per line in output + if ( $NF ~ /;/ ) + printf "\n" +} + +$1 == "class" && $0 !~ /;/ {public=1} # we test matching against /;/ to get rid of forward declaration +$1 ~ /public/ {public=1} +$1 ~ /protected/ {public=0} +$1 ~ /private/ {public=0} +$1 ~ /}/ {public=0} diff --git a/src/wrappergen/src/parse2.awk b/src/wrappergen/src/parse2.awk new file mode 100755 index 000000000..2ecc2c785 --- /dev/null +++ b/src/wrappergen/src/parse2.awk @@ -0,0 +1,4 @@ +# suppress blanks between type and indirection or reference operators (* and &) +{ gsub(/[ \t]+&/,"\\& ") + gsub(/[ \t]+\*/,"* ") + print $0 } diff --git a/src/wrappergen/src/parse3.awk b/src/wrappergen/src/parse3.awk new file mode 100755 index 000000000..f167d3582 --- /dev/null +++ b/src/wrappergen/src/parse3.awk @@ -0,0 +1,373 @@ +# This awk program contains the type mapping tables - and the treatments +# for code generation +# +BEGIN { +# +# file name generation + idl_file="code_idl" + hxx_file="code_hxx" + cxx_file="code_cxx" + class_i=class_name"_i" + print "\t// generated part" > idl_file + printf " // generated part\n" > hxx_file + printf "//\n// generated part\n//\n" > cxx_file + print "Functions parsing (for debug)" > "parse_result" +# +# +# type mapping from c++ component to idl +# + idl_arg_type["int"]="in long" + idl_arg_type["double"]="in double" + idl_arg_type["float"]="in float" + idl_arg_type["long"]="in long" + idl_arg_type["short"]="in short" + idl_arg_type["unsigned"]="in unsigned long" + idl_arg_type["const char*"]="in string" + idl_arg_type["const std::string&"]="in string" + idl_arg_type["int&"]="out long" + idl_arg_type["double&"]="out double" + idl_arg_type["float&"]="out float" + idl_arg_type["long&"]="out long" + idl_arg_type["short&"]="out short" + idl_arg_type["unsigned&"]="out unsigned long" + idl_arg_type["std::string&"]="out string" + idl_arg_type["const MEDMEM::MESH&"]="in SALOME_MED::MESH" + idl_arg_type["const MEDMEM::MESH*"]="in SALOME_MED::MESH" + idl_arg_type["const MEDMEM::FIELD*"]="in SALOME_MED::FIELDDOUBLE" + idl_arg_type["const MEDMEM::FIELD&"]="in SALOME_MED::FIELDDOUBLE" + idl_arg_type["MEDMEM::FIELD*&"]="out SALOME_MED::FIELDDOUBLE" + idl_arg_type["const std::vector&"]="in SALOME::SenderDouble" + idl_arg_type["const std::vector >&"]="in SALOME::Matrix" + idl_arg_type["std::vector*&"]="out SALOME::SenderDouble" + idl_arg_type["const MEDMEM::FIELD*"]="in SALOME_MED::FIELDINT" + idl_arg_type["const MEDMEM::FIELD&"]="in SALOME_MED::FIELDINT" + idl_arg_type["MEDMEM::FIELD*&"]="out SALOME_MED::FIELDINT" + idl_arg_type["const std::vector&"]="in SALOME::SenderInt" + idl_arg_type["std::vector*&"]="out SALOME::SenderInt" +# +# +# mapping for returned types +# + idl_rtn_type["void"]="void" + idl_rtn_type["int"]="long" + idl_rtn_type["double"]="double" + idl_rtn_type["float"]="float" + idl_rtn_type["long"]="long" + idl_rtn_type["short"]="short" + idl_rtn_type["unsigned"]="unsigned long" + idl_rtn_type["const char*"]="string" + idl_rtn_type["char*"]="string" + idl_rtn_type["std::string"]="string" + idl_rtn_type["const MEDMEM::MESH&"]="SALOME_MED::MESH" + idl_rtn_type["MEDMEM::MESH&"]="SALOME_MED::MESH" + idl_rtn_type["MEDMEM::MESH*"]="SALOME_MED::MESH" + idl_rtn_type["const MEDMEM::MESH*"]="SALOME_MED::MESH" + idl_rtn_type["const MEDMEM::FIELD*"]="SALOME_MED::FIELDDOUBLE" + idl_rtn_type["MEDMEM::FIELD*"]="SALOME_MED::FIELDDOUBLE" + idl_rtn_type["MEDMEM::FIELD&"]="SALOME_MED::FIELDDOUBLE" + idl_rtn_type["const MEDMEM::FIELD&"]="SALOME_MED::FIELDDOUBLE" + idl_rtn_type["std::vector*"]="SALOME::SenderDouble" + idl_rtn_type["std::vector >*"]="SALOME::Matrix" + idl_rtn_type["const MEDMEM::FIELD*"]="SALOME_MED::FIELDINT" + idl_rtn_type["MEDMEM::FIELD*"]="SALOME_MED::FIELDINT" + idl_rtn_type["MEDMEM::FIELD&"]="SALOME_MED::FIELDINT" + idl_rtn_type["const MEDMEM::FIELD&"]="SALOME_MED::FIELDINT" + idl_rtn_type["std::vector*"]="SALOME::SenderInt" +# +# +# Corba mapping table (for argument's types and returned types) +# + idl_impl_hxx["in long"]="CORBA::Long" + idl_impl_hxx["in double"]="CORBA::Double" + idl_impl_hxx["in float"]="CORBA::Float" + idl_impl_hxx["in short"]="CORBA::Short" + idl_impl_hxx["in unsigned long"]="CORBA::ULong" + idl_impl_hxx["in string"]="const char*" + idl_impl_hxx["out long"]="CORBA::Long_out" + idl_impl_hxx["out double"]="CORBA::Double_out" + idl_impl_hxx["out float"]="CORBA::Float_out" + idl_impl_hxx["out short"]="CORBA::Short_out" + idl_impl_hxx["out unsigned long"]="CORBA::ULong_out" + idl_impl_hxx["out string"]="CORBA::String_out" + idl_impl_hxx["in SALOME_MED::MESH"]="SALOME_MED::MESH_ptr" + idl_impl_hxx["in SALOME_MED::FIELDDOUBLE"]="SALOME_MED::FIELDDOUBLE_ptr" + idl_impl_hxx["out SALOME_MED::FIELDDOUBLE"]="SALOME_MED::FIELDDOUBLE_out" + idl_impl_hxx["in SALOME::SenderDouble"]="SALOME::SenderDouble_ptr" + idl_impl_hxx["out SALOME::SenderDouble"]="SALOME::SenderDouble_out" + idl_impl_hxx["in SALOME::Matrix"]="SALOME::Matrix_ptr" + idl_impl_hxx["in SALOME_MED::FIELDINT"]="SALOME_MED::FIELDINT_ptr" + idl_impl_hxx["out SALOME_MED::FIELDINT"]="SALOME_MED::FIELDINT_out" + idl_impl_hxx["in SALOME::SenderInt"]="SALOME::SenderInt_ptr" + idl_impl_hxx["out SALOME::SenderInt"]="SALOME::SenderInt_out" + idl_impl_hxx["void"]="void" + idl_impl_hxx["long"]="CORBA::Long" + idl_impl_hxx["double"]="CORBA::Double" + idl_impl_hxx["unsigned long"]="CORBA::ULong" + idl_impl_hxx["string"]="char*" + idl_impl_hxx["SALOME_MED::MESH"]="SALOME_MED::MESH_ptr" + idl_impl_hxx["SALOME_MED::FIELDDOUBLE"]="SALOME_MED::FIELDDOUBLE_ptr" + idl_impl_hxx["SALOME::SenderDouble"]="SALOME::SenderDouble_ptr" + idl_impl_hxx["SALOME::Matrix"]="SALOME::Matrix_ptr" + idl_impl_hxx["SALOME_MED::FIELDINT"]="SALOME_MED::FIELDINT_ptr" + idl_impl_hxx["SALOME::SenderInt"]="SALOME::SenderInt_ptr" +# +# +# table for c++ code generation : argument's processing +# + cpp_impl_a["int"]="\tint _%s(%s);\n" + cpp_impl_a["double"]="\tdouble _%s(%s);\n" + cpp_impl_a["float"]="\tfloat _%s(%s);\n" + cpp_impl_a["long"]="\tlong _%s(%s);\n" + cpp_impl_a["short"]="\tshort _%s(%s);\n" + cpp_impl_a["unsigned"]="\tunsigned _%s(%s);\n" + cpp_impl_a["const char*"]="\tconst char* _%s(%s);\n" + cpp_impl_a["const std::string&"]="\tconst std::string _%s(%s);\n" + cpp_impl_a["int&"]="\tint _%s;\n" + cpp_impl_a["double&"]="\tdouble _%s;\n" + cpp_impl_a["float&"]="\tfloat _%s;\n" + cpp_impl_a["long&"]="\tlong _%s;\n" + cpp_impl_a["short&"]="\tshort _%s;\n" + cpp_impl_a["unsigned&"]="\tunsigned _%s;\n" + cpp_impl_a["std::string&"]="std::string _%s;\n" + cpp_impl_a["const MEDMEM::MESH&"]="\tMEDMEM::MESHClient* _%s = new MEDMEM::MESHClient(%s);\n" # MESHClient cannot be created on the stack (private constructor), so we create it on the heap and dereference it later (in treatment 4) + cpp_impl_a["const MEDMEM::MESH*"]="\tMEDMEM::MESHClient* _%s = new MEDMEM::MESHClient(%s);\n" + cpp_impl_a["MEDMEM::FIELD*&"]="\tMEDMEM::FIELD* _%s;\n" + cpp_impl_a["const MEDMEM::FIELD*"]="\tstd::auto_ptr > _%s ( new MEDMEM::FIELDClient(%s) );\n" + cpp_impl_a["const MEDMEM::FIELD&"]="\tMEDMEM::FIELDClient _%s(%s);\n" + cpp_impl_a["const std::vector&"]="\tlong _%s_size;\n\tdouble *_%s_value = ReceiverFactory::getValue(%s,_%s_size);\n"\ + "\tstd::vector _%s(_%s_value,_%s_value+_%s_size);\n\tdelete [] _%s_value;" + cpp_impl_a["std::vector*&"]="\tstd::vector* _%s;\n" + cpp_impl_a["const std::vector >&"]="\tMatrixClient _%s_client;\n\tint _%s_nbRow;\n\tint _%s_nbCol;\n"\ + "\tdouble* _%s_tab = _%s_client.getValue(%s,_%s_nbCol,_%s_nbRow);\n\tstd::vector > _%s(_%s_nbRow);\n"\ + "\tfor (int i=0; i!=_%s_nbRow; ++i)\n\t{\n\t _%s.reserve(_%s_nbCol);\n"\ + "\t std::copy(_%s_tab+_%s_nbCol*i,_%s_tab+_%s_nbCol*(i+1), _%s[i].begin());\n\t}\n\tdelete [] _%s_tab;\n" + cpp_impl_a["MEDMEM::FIELD*&"]="\tMEDMEM::FIELD* _%s;\n" + cpp_impl_a["const MEDMEM::FIELD*"]="\tstd::auto_ptr > _%s ( new MEDMEM::FIELDClient(%s) );\n" + cpp_impl_a["const MEDMEM::FIELD&"]="\tMEDMEM::FIELDClient _%s(%s);\n" + cpp_impl_a["const std::vector&"]="\tlong _%s_size;\n\tint *_%s_value = ReceiverFactory::getValue(%s,_%s_size);\n"\ + "\tstd::vector _%s(_%s_value,_%s_value+_%s_size);\n\tdelete [] _%s_value;" + cpp_impl_a["std::vector*&"]="\tstd::vector* _%s;\n" + +# +# +# table for c++ code generation : returned value processing +# + cpp_impl_b["void"]="" + cpp_impl_b["int"]="\tCORBA::Long _rtn_ior(_rtn_cpp);\n" + cpp_impl_b["double"]="\tCORBA::Double _rtn_ior(_rtn_cpp);\n" + cpp_impl_b["float"]="\tCORBA::Float _rtn_ior(_rtn_cpp);\n" + cpp_impl_b["long"]="\tCORBA::Long _rtn_ior(_rtn_cpp);\n" + cpp_impl_b["short"]="\tCORBA::Short _rtn_ior(_rtn_cpp);\n" + cpp_impl_b["unsigned"]="\tCORBA::ULong _rtn_ior(_rtn_cpp);\n" + cpp_impl_b["const char*"]="\tchar* _rtn_ior = CORBA::string_dup(_rtn_cpp);\n" + cpp_impl_b["char*"]="\tchar* _rtn_ior(_rtn_cpp);\n" + cpp_impl_b["std::string"]="\tchar* _rtn_ior=CORBA::string_dup(_rtn_cpp.c_str());\n" + "\tstd::copy(_rtn_cpp.begin(),_rtn_cpp.end(),_rtn_ior);\n" + cpp_impl_b["const MEDMEM::MESH&"]=\ + "\tMEDMEM::MESH_i * _rtn_mesh_i = new MEDMEM::MESH_i(const_cast(&_rtn_cpp));\n"\ + "\tSALOME_MED::MESH_ptr _rtn_ior = _rtn_mesh_i->_this();\n" + cpp_impl_b["MEDMEM::MESH&"]=\ + "\tMEDMEM::MESH_i * _rtn_mesh_i = new MEDMEM::MESH_i(&_rtn_cpp);\n"\ + "\tSALOME_MED::MESH_ptr _rtn_ior = _rtn_mesh_i->_this();\n" + cpp_impl_b["MEDMEM::MESH*"]=\ + "\tMEDMEM::MESH_i * _rtn_mesh_i = new MEDMEM::MESH_i(_rtn_cpp);\n"\ + "\tSALOME_MED::MESH_ptr _rtn_ior = _rtn_mesh_i->_this();\n" + cpp_impl_b["const MEDMEM::MESH*"]=\ + "\tMEDMEM::MESH_i * _rtn_mesh_i = new MEDMEM::MESH_i(const_cast(_rtn_cpp));\n"\ + "\tSALOME_MED::MESH_ptr _rtn_ior = _rtn_mesh_i->_this();\n" + cpp_impl_b["const MEDMEM::FIELD*"]=\ + "\tMEDMEM::FIELDTEMPLATE_I * _rtn_field_i = new MEDMEM::FIELDTEMPLATE_I(const_cast*>(_rtn_cpp),false);\n"\ + "\tSALOME_MED::FIELDDOUBLE_ptr _rtn_ior = _rtn_field_i->_this();\n" + cpp_impl_b["MEDMEM::FIELD*"]=\ + "\tMEDMEM::FIELDTEMPLATE_I * _rtn_field_i = new MEDMEM::FIELDTEMPLATE_I(_rtn_cpp,true);\n"\ + "\tSALOME_MED::FIELDDOUBLE_ptr _rtn_ior = _rtn_field_i->_this();\n" + cpp_impl_b["MEDMEM::FIELD&"]=\ + "\tMEDMEM::FIELDTEMPLATE_I * _rtn_field_i = new MEDMEM::FIELDTEMPLATE_I(&_rtn_cpp,false);\n"\ + "\tSALOME_MED::FIELDDOUBLE_ptr _rtn_ior = _rtn_field_i->_this();\n" + cpp_impl_b["const MEDMEM::FIELD&"]=\ + "\tMEDMEM::FIELDTEMPLATE_I * _rtn_field_i = new MEDMEM::FIELDTEMPLATE_I(const_cast*>(&_rtn_cpp),false);\n"\ + "\tSALOME_MED::FIELDDOUBLE_ptr _rtn_ior = _rtn_field_i->_this();\n" + cpp_impl_b["std::vector*"]=\ + "\tSALOME::SenderDouble_ptr _rtn_ior = SenderFactory::buildSender(*this,&(*_rtn_cpp)[0],(*_rtn_cpp).size(),true);\n" + cpp_impl_b["std::vector >*"]=\ + "\tint _rtn_cpp_i=(*_rtn_cpp).size();\n\tint _rtn_cpp_j=(*_rtn_cpp)[0].size();\n"\ + "\tdouble* _rtn_tab = new double[_rtn_cpp_i*_rtn_cpp_j];\n"\ + "\tfor (int i=0; i!=_rtn_cpp_i; ++i)\n\t std::copy((*_rtn_cpp)[i].begin(),(*_rtn_cpp)[i].end(),_rtn_tab+i*_rtn_cpp_j);\n"\ + "\tSALOME_Matrix_i* _rtn_matrix_i = new SALOME_Matrix_i(*this,_rtn_tab,_rtn_cpp_j,_rtn_cpp_i,true);\n"\ + "\tSALOME::Matrix_ptr _rtn_ior = _rtn_matrix_i->_this();\n\tdelete _rtn_cpp;\n" + cpp_impl_b["const MEDMEM::FIELD*"]=\ + "\tMEDMEM::FIELDINT_i * _rtn_field_i = new MEDMEM::FIELDINT_i(const_cast*>(_rtn_cpp),false);\n"\ + "\tSALOME_MED::FIELDINT_ptr _rtn_ior = _rtn_field_i->_this();\n" + cpp_impl_b["MEDMEM::FIELD*"]=\ + "\tMEDMEM::FIELDINT_i * _rtn_field_i = new MEDMEM::FIELDINT_i(_rtn_cpp,true);\n"\ + "\tSALOME_MED::FIELDINT_ptr _rtn_ior = _rtn_field_i->_this();\n" + cpp_impl_b["MEDMEM::FIELD&"]=\ + "\tMEDMEM::FIELDINT_i * _rtn_field_i = new MEDMEM::FIELDINT_i(&_rtn_cpp,false);\n"\ + "\tSALOME_MED::FIELDINT_ptr _rtn_ior = _rtn_field_i->_this();\n" + cpp_impl_b["const MEDMEM::FIELD&"]=\ + "\tMEDMEM::FIELDINT_i * _rtn_field_i = new MEDMEM::FIELDINT_i(const_cast*>(&_rtn_cpp),false);\n"\ + "\tSALOME_MED::FIELDINT_ptr _rtn_ior = _rtn_field_i->_this();\n" + cpp_impl_b["std::vector*"]=\ + "\tSALOME::SenderInt_ptr _rtn_ior = SenderFactory::buildSender(*this,&(*_rtn_cpp)[0],(*_rtn_cpp).size(),true);\n" + +# +# +# table for c++ code generation : out parameters processing and removeRef for reference counted objects +# + cpp_impl_c["MEDMEM::FIELD*&"]=\ + "\tMEDMEM::FIELDTEMPLATE_I * %s_ior = new MEDMEM::FIELDTEMPLATE_I(_%s, true);\n"\ + "\t%s = %s_ior->_this();\n" + cpp_impl_c["MEDMEM::FIELD*&"]=\ + "\tMEDMEM::FIELDINT_i * %s_ior = new MEDMEM::FIELDINT_i(_%s, true);\n"\ + "\t%s = %s_ior->_this();\n" + cpp_impl_c["std::vector*&"]=\ + "\t%s = SenderFactory::buildSender(*this,&(*_%s)[0],(*_%s).size(),true);\n" + cpp_impl_c["std::vector*&"]=\ + "\t%s = SenderFactory::buildSender(*this,&(*_%s)[0],(*_%s).size(),true);\n" + cpp_impl_c["std::string&"]="\t%s = CORBA::string_dup(_%s.c_str());\n" + cpp_impl_c["int&"]="\t%s = _%s;\n" + cpp_impl_c["double&"]="\t%s = _%s;\n" + cpp_impl_c["float&"]="\t%s = _%s;\n" + cpp_impl_c["long&"]="\t%s = _%s;\n" + cpp_impl_c["short&"]="\t%s = _%s;\n" + cpp_impl_c["unsigned&"]="\t%s = _%s;\n" + cpp_impl_c["const MEDMEM::MESH&"]="\t_%s->removeReference();\n" + cpp_impl_c["const MEDMEM::MESH*"]="\t_%s->removeReference();\n" +# +# +# record sep is ");\n" whith blanks all around, and optional "(" at the beginning + RS="[(]?[ \t]*[)][ \t]*;[ \t]*\n?" + FS="[ \t]*[(,][ \t]*" # field sep is either "(" or "," surrounded by blanks +} + +# --------------------- treatment 1 ---------------------------------- +# +# extract from fields types, function name, and argument's names +# +{ + print "Function : ",$0 >> "parse_result" # print for debug + for (i=1; i<=NF; i++) { + print "\t-> ",i," : ",$i >> "parse_result" + } + ok1=0;ok=1 + # check if returned type ($1) is one of the accepted types (idl_rtn_type) + for (cpptype in idl_rtn_type) { + if ( substr($1,1,length(cpptype)) == cpptype ) { + # if compatible, store returned type and function name + type[1]=cpptype + name[1]=substr($1,length(cpptype)+1) + sub("^[ \t]*","",name[1]) # get rid of leading blanks + ok1=1 + break + } + } + ok*=ok1 + # for each argument ($i), check if it is compatible (belongs to idl_arg_type) + for (i=2; i<=NF; i++) { + ok2=0 + split($i,tab,"=") # get rid of default value + item=tab[1] + for (cpptype in idl_arg_type) { + if ( substr(item,1,length(cpptype)) == cpptype ) { + # if compatible, store argument type and name + type[i]=cpptype + name[i]=substr(item,length(cpptype)+1) + sub("^[ \t]*","",name[i]) # get rid of leading blanks + if ( length(name[i]) == 0 ) # automatic name if argument's name wasn't precised + name[i]=sprintf("_arg%d",i-1) + ok2=1 + break + } + } + ok*=ok2 # ok=0 if one of the type is not compatible + } + if ( ok == 0) # pass to the next function if one of the c++ type is not compatible + next +} +# +# --------------------- treatment 2 ---------------------------------- +# +# generate the Corba interface (idl file) +# +{ + printf "\t%s %s(", idl_rtn_type[type[1]],name[1] >> idl_file # return type and name of function + if ( NF >= 2 ){ # if there is arguments, print them + for (i=2; i<=NF-1; i++) + printf "%s %s,",idl_arg_type[type[i]],name[i] >> idl_file + printf "%s %s", idl_arg_type[type[NF]],name[NF] >> idl_file + } + printf ");\n" >> idl_file +} +# +# --------------------- treatment 3 ---------------------------------- +# +# generate the C++ implementation of component (hxx file) +# +{ + printf " %s %s(",idl_impl_hxx[idl_rtn_type[type[1]]],name[1] >> hxx_file + if ( NF >= 2 ){ # if there is arguments, print them + for (i=2; i<=NF-1; i++) + printf "%s %s,",idl_impl_hxx[idl_arg_type[type[i]]],name[i] >> hxx_file + printf "%s %s", idl_impl_hxx[idl_arg_type[type[NF]]],name[NF] >> hxx_file + } + printf ");\n" >> hxx_file +} +# +# --------------------- treatment 4 ---------------------------------- +# +# generate the C++ implementation of component (cxx file) +# +{ + # a) generate the function declaration + macro declarations + func_name=class_name"_i::"name[1] + printf "%s %s(",idl_impl_hxx[idl_rtn_type[type[1]]],func_name >> cxx_file + if ( NF >= 2 ){ # if there is arguments, print them + for (i=2; i<=NF-1; i++) + printf "%s %s,",idl_impl_hxx[idl_arg_type[type[i]]],name[i] >> cxx_file + printf "%s %s", idl_impl_hxx[idl_arg_type[type[NF]]],name[NF] >> cxx_file + } + printf ")\n{\n\tbeginService(\"%s\");\n\tBEGIN_OF(\"%s\");\n",func_name,func_name >> cxx_file + + # b) generate the argument processing part + if ( NF >= 2 ){ + printf "//\tArguments processing\n" >> cxx_file + for (i=2; i<=NF; i++) + printf cpp_impl_a[type[i]],name[i],name[i],name[i],name[i],name[i],name[i],name[i],name[i],name[i],\ + name[i],name[i],name[i],name[i],name[i],name[i],name[i],name[i],name[i],name[i] >> cxx_file + } + + # c) generate the call to the c++ component + if ( type[1] == "void" ) # if return type is void, the call syntax is different. + printf "//\tCall cpp component\n\tcppCompo_->%s(",name[1] >> cxx_file + else + printf "//\tCall cpp component\n\t%s _rtn_cpp = cppCompo_->%s(",type[1],name[1] >> cxx_file + if ( NF >= 2 ){ # if there is arguments, print them + for (i=2; i<=NF; i++) { + # special treatment for some arguments + post="" + pre="" + if ( cpp_impl_a[type[i]] ~ "auto_ptr" ) + post=".get()" # for auto_ptr argument, retrieve the raw pointer behind + if ( type[i] == "const MEDMEM::MESH&" ) + pre="*" # we cannot create MESHClient on the stack (private constructor), so we create it on the heap and dereference it + if ( i < NF ) + post=post"," # separator between arguments + printf " %s_%s%s",pre,name[i],post >> cxx_file + } + } + + # d) generate the post_processing of returned and out parameters + printf ");\n//\tPost-processing & return\n" >> cxx_file + for (i=2; i<=NF; i++) + printf cpp_impl_c[type[i]],name[i],name[i],name[i],name[i] >> cxx_file # process for out parameters + printf cpp_impl_b[type[1]] >> cxx_file # process for returned value + printf "\tendService(\"%s\");\n\tEND_OF(\"%s\");\n",func_name,func_name >> cxx_file + if ( type[1] != "void" ) + printf "\treturn _rtn_ior;\n" >> cxx_file + printf "}\n\n" >> cxx_file +} +# +# +END { +# CNC peut être mis dans le template directement printf "\nprivate:\n std::auto_ptr<%s> cppImpl_;\n",class_name >> hxx_file +} diff --git a/src/wrappergen/src/parse30.awk b/src/wrappergen/src/parse30.awk new file mode 100644 index 000000000..33fb8cdc5 --- /dev/null +++ b/src/wrappergen/src/parse30.awk @@ -0,0 +1,138 @@ +# This awk program checks the arguments and return value compatibility +# +BEGIN { + +# +# +# allowed types for arguments +# + arg_type["int"]= 1; + arg_type["double"]= 1; + arg_type["float"]= 1; + arg_type["long"]= 1; + arg_type["short"]= 1; + arg_type["unsigned"]= 1; + arg_type["const char*"]= 1; + arg_type["const std::string&"]= 1; + arg_type["int&"]= 1; + arg_type["double&"]= 1; + arg_type["float&"]= 1; + arg_type["long&"]= 1; + arg_type["short&"]= 1; + arg_type["unsigned&"]= 1; + arg_type["std::string&"]= 1; + arg_type["const MEDMEM::MESH&"]= 1; + arg_type["const MEDMEM::MESH*"]= 1; + arg_type["const MEDMEM::FIELD*"]= 1; + arg_type["const MEDMEM::FIELD&"]= 1; + arg_type["MEDMEM::FIELD*&"]= 1; + arg_type["const std::vector&"]= 1; + arg_type["const std::vector >&"]= 1; + arg_type["std::vector&"]= 1; + arg_type["std::vector*&"]= 1; + arg_type["const MEDMEM::FIELD*"]= 1; + arg_type["const MEDMEM::FIELD&"]= 1; + arg_type["MEDMEM::FIELD*&"]= 1; + arg_type["const std::vector&"]= 1; + arg_type["std::vector*&"]= 1; + arg_type["std::vector&"]= 1; +# +# +# allowed types for return values +# + rtn_type["void"]= 1; + rtn_type["int"]= 1; + rtn_type["double"]= 1; + rtn_type["float"]= 1; + rtn_type["long"]= 1; + rtn_type["short"]= 1; + rtn_type["unsigned"]= 1; + rtn_type["const char*"]= 1; + rtn_type["char*"]= 1; + rtn_type["std::string"]= 1; + rtn_type["const MEDMEM::MESH&"]= 1; + rtn_type["MEDMEM::MESH&"]= 1; + rtn_type["MEDMEM::MESH*"]= 1; + rtn_type["const MEDMEM::MESH*"]= 1; + rtn_type["const MEDMEM::FIELD*"]= 1; + rtn_type["MEDMEM::FIELD*"]= 1; + rtn_type["MEDMEM::FIELD&"]= 1; + rtn_type["const MEDMEM::FIELD&"]= 1; + rtn_type["std::vector*"]= 1; + rtn_type["std::vector"]= 1; + rtn_type["std::vector >*"]= 1; + rtn_type["const MEDMEM::FIELD*"]= 1; + rtn_type["MEDMEM::FIELD*"]= 1; + rtn_type["MEDMEM::FIELD&"]= 1; + rtn_type["const MEDMEM::FIELD&"]= 1; + rtn_type["std::vector*"]= 1; +# +# +# record sep is ");\n" whith blanks all around, and optional "(" at the beginning + RS="[(]?[ \t]*[)][ \t]*;[ \t]*\n?" + FS="[ \t]*[(,][ \t]*" # field sep is either "(" or "," surrounded by blanks +} + +# --------------------- treatment 1 ---------------------------------- +# +# extract from fields types, function name, and argument's names +# +{ + + print "Function : ",$0 >> "parse_result" # print for debug + for (i=1; i<=NF; i++) { + print "\t-> ",i," : ",$i >> "parse_result" + } + ok1=0;ok=1 + # check if returned type ($1) is one of the accepted types (rtn_type) + for (cpptype in rtn_type) { + if ( substr($1,1,length(cpptype)) == cpptype ) { + # if compatible, store returned type and function name + type[1]=cpptype + name[1]=substr($1,length(cpptype)+1) + sub("^[ \t]*","",name[1]) # get rid of leading blanks + ok1=1 + break + } + } + ok*=ok1 + # for each argument ($i), check if it is compatible (belongs to arg_type) + for (i=2; i<=NF; i++) { + ok2=0 + split($i,tab,"=") # get rid of default value + item=tab[1] + for (cpptype in arg_type) { + if ( substr(item,1,length(cpptype)) == cpptype ) { + # if compatible, store argument type and name + type[i]=cpptype + name[i]=substr(item,length(cpptype)+1) + sub("^[ \t]*","",name[i]) # get rid of leading blanks + if ( length(name[i]) == 0 ) # automatic name if argument's name wasn't precised + name[i]=sprintf("_arg%d",i-1) + ok2=1 + break + } + } + ok*=ok2 # ok=0 if one of the type is not compatible + } + + # print compatibility + if ( $0 !~ class_name ) { # constructor are not considered, but we don't print it + if ( ok == 0){ # if one of the c++ type is not compatible + printf " [KO] : %s",$0 + } + else + printf " [OK] : %s",$0 + + if ( $0 !~ /\(/ ) { + printf "(" # if there is no argument, parenthesis was suppressed, so we add it for printing + } + printf ");\n" + } + if ( ok == 0) # pass to the next function if one of the c++ type is not compatible + next +} +# +# +END { +} diff --git a/src/wrappergen/src/parse4.awk b/src/wrappergen/src/parse4.awk new file mode 100644 index 000000000..ca29e89eb --- /dev/null +++ b/src/wrappergen/src/parse4.awk @@ -0,0 +1,205 @@ +# This awk program contains the type mapping tables - and the treatments +# for code generation +# +BEGIN { +# +# file name generation + print "Functions parsing (for debug parse4)" > "parse_result"; + dispatch_file="code_dispatch" + class_cpp=class_name"_cpp" + print "//\n// generated part\n//\n" > dispatch_file + + print "#include \n" >> dispatch_file + print "#include \"Any.hxx\"\n" >> dispatch_file + print "struct returnInfo {\n int code;\n std::string message;\n};\n\n" >> dispatch_file + print "extern \"C\"" >> dispatch_file + print "void * __init() {" >> dispatch_file + print "\n "class_name " *Obj = new " class_name ";\n return Obj;\n}\n" >> dispatch_file + + print "extern \"C\"" >> dispatch_file + print "void __terminate(void ** vObj) {" >> dispatch_file + print "\n "class_name " *Obj = ("class_name" *) *vObj;\n delete Obj;\n *vObj = NULL;\n}\n" >> dispatch_file + + print "extern \"C\"" >> dispatch_file + print "void __run(void * O, const char * service, int nbIn, int nbOut," >> dispatch_file + print " YACS::ENGINE::Any ** argIn, YACS::ENGINE::Any ** argOut, returnInfo *r)" >> dispatch_file + print " {" >> dispatch_file + print " if (O == NULL) {" >> dispatch_file + print " r->code = -1;" >> dispatch_file + print " r->message = \"Component "class_name" has not been initialized\";" >> dispatch_file + print " return;" >> dispatch_file + print " }\n" >> dispatch_file + print " returnInfo return_code;" >> dispatch_file + print " return_code.message = \"\";" >> dispatch_file + print " return_code.code = 0;\n" >> dispatch_file + print " int kIn = 0, kOut = 0;" >> dispatch_file; + print " "class_name" * Obj = ("class_name" *) O;">> dispatch_file; + print "\n try {\n" >> dispatch_file; + +# +# +# +# table for c++ code generation : argument's processing +# + cpp_arg["int"]=" int argIn%d = argIn[kIn++]->getIntValue();\n" + cpp_arg["double"]=" double argIn%d = argIn[kIn++]->getDoubleValue();\n" + cpp_arg["float"]=" float argIn%d = argIn[kIn++]->getDoubleValue();\n" + cpp_arg["long"]=" long argIn%d = argIn[kIn++]->getIntValue();\n" + cpp_arg["short"]=" short argIn%d = (short) argIn[kIn++]->getIntValue();\n" + cpp_arg["unsigned"]=" unsigned argIn%d = (unsigned ) argIn[kIn++];->getIntValue()\n" + cpp_arg["const char*"]=" const char * argIn%d = argIn[kIn++]->getStringValue().c_str();\n" + cpp_arg["const std::string&"]=" const std::string& argIn%d = argIn[kIn++]->getStringValue();\n" + cpp_arg["const std::vector&"]=" YACS::ENGINE::SequenceAny * sA\n"\ + " = dynamic_cast(argIn[kIn]);\n"\ + " if (NULL == sA) {\n"\ + " r->code = -1;\n"\ + " r->message = \"sequence expected\";\n"\ + " return;\n"\ + " }\n"\ + " unsigned int i, n = sA->size();\n"\ + " std::vector argIn%d(n);\n"\ + " for (i=0; igetDoubleValue();\n"\ + " kIn++;\n" + + cpp_arg["int&"]=" int argOut%d;\n" + cpp_arg["double&"]=" double argOut%d;\n" + cpp_arg["float&"]=" float argOut%d;\n" + cpp_arg["long&"]=" long argOut%d;\n" + cpp_arg["short&"]=" short argOut%d;\n" + cpp_arg["unsigned&"]=" unsigned argOut%d;\n" + cpp_arg["std::string&"]=" std::string argOut%d;\n" + cpp_arg["std::vector&"]=" std::vector argOut%d;\n" + + cpp_out["int&"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["double&"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["float&"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["long&"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["short&"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["unsigned&"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["std::string&"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["std::vector&"]=" argOut[kOut++] = YACS::ENGINE::SequenceAny::New(argOut%d);" + + cpp_out["int"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["double"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["float"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["long"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["short"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["unsigned"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["std::string"]=" argOut[kOut++] = YACS::ENGINE::AtomAny::New(argOut%d);" + cpp_out["std::vector"]=" argOut[kOut++] = YACS::ENGINE::SequenceAny::New(argOut%d);" + + type_in=1 + type_out=2 + + type_arg["int"]= type_in + type_arg["double"]= type_in + type_arg["float"]= type_in + type_arg["long"]= type_in + type_arg["short"]= type_in + type_arg["unsigned"]= type_in + type_arg["const char*"]= type_in + type_arg["const std::string&"]= type_in + type_arg["const std::vector&"]= type_in + + type_arg["int&"]= type_out + type_arg["double&"]= type_out + type_arg["float&"]= type_out + type_arg["long&"]= type_out + type_arg["short&"]= type_out + type_arg["unsigned&"]= type_out + type_arg["std::string&"]= type_out + type_arg["std::vector&"]= type_out + +# +# +# record sep is ");\n" whith blanks all around, and optional "(" at the beginning + RS="[(]?[ ]*[)][ ]*;[ ]*\n?" + FS="[ ]*[(,][ ]*" # field sep is either "(" or "," surrounded by blanks +} + +# --------------------- treatment 1 ---------------------------------- +# +# extract from fields types, function name, and argument's names +# +{ + nitems = split($0, items); + print "Function : ",$0 >> "parse_result"; # print for debug + for (i=1; i<=nitems; i++) { + print " -> ",i," : ",items[i] >> "parse_result"; + split(items[i], j, " "); + l=0; for (k in j) {l++;} + k=j[1]; + for (ll=2; ll> dispatch_file; + + for (i=2; i<=nitems; i++) { + printf cpp_arg[type[i]],(i-1),(i-1) >> dispatch_file; + } + + # Internal function call with local arguments + + # if no return value, return NULL + if (type[1] == "void") { + s = " "; + } + else { + s=" "type[1]" argOut0 = "; + } + + s = s"Obj->"name[1]"("; + for (i=2; i1) { + if (way[nitems] == type_in) { + s=s"argIn"(nitems-1); + } + else if (way[nitems] == type_out) { + s=s"argOut"(nitems-1); + } + } + s=s");" + print s >> dispatch_file; + + if (type[1] != "void") { + printf cpp_out[type[1]],0 >> dispatch_file; + } + + for (i=2; i> dispatch_file; + } + } + + print "\n }\n else" >> dispatch_file; + +} +# +END { + print " {\n // error in function name" >> dispatch_file + print " return_code.code = -1;" >> dispatch_file + print " return_code.message = std::string(service) + \" is not the name of a service\";\n }" >> dispatch_file + print "\n }\n catch(std::exception & e) {\n" >> dispatch_file + print " return_code.code = -1;" >> dispatch_file; + print " return_code.message = std::string(\"internal exception in \") + service + \" : \" + e.what();" >> dispatch_file; + print "\n }\n catch(...) {\n" >> dispatch_file + print " return_code.code = -1;" >> dispatch_file; + print " return_code.message = std::string(\"internal exception in \") + service;" >> dispatch_file; + print " }" >> dispatch_file + print " *r = return_code;\n}" >> dispatch_file + + print "\n#include \n" >> dispatch_file + print "extern \"C\"" >> dispatch_file + print "\nvoid __ping() {\n" >> dispatch_file + print " std::cerr << \"ping\" << std::endl;\n}" >> dispatch_file +} diff --git a/src/wrappergen/src/parse5.awk b/src/wrappergen/src/parse5.awk new file mode 100644 index 000000000..01311a0f4 --- /dev/null +++ b/src/wrappergen/src/parse5.awk @@ -0,0 +1,122 @@ +# This awk program generates the catalog for C++ components +# +BEGIN { +# +# file name generation + catalog_file="catalog.xml" + print "\n" > catalog_file + + print "\n"\ + "\n"\ + " " >> catalog_file + + print " \n"\ + " "class_name"\n"\ + " "class_name"\n"\ + " Solver\n"\ + " ""\n"\ + " 1.0\n"\ + " \n"\ + " 1\n"\ + " "class_name".png\n"\ + " 1\n"\ + " " >> catalog_file + + print " "class_name"\n"\ + " No comment\n"\ + " "\ + "\n" >> catalog_file + + type_in = 1 + type_out = 2 + + type_arg["int"]= type_in + type_arg["double"]= type_in + type_arg["float"]= type_in + type_arg["long"]= type_in + type_arg["short"]= type_in + type_arg["unsigned"]= type_in + type_arg["const char*"]= type_in + type_arg["const std::string&"]= type_in + type_arg["const std::vector&"]= type_in + + type_arg["int&"]= type_out + type_arg["double&"]= type_out + type_arg["float&"]= type_out + type_arg["long&"]= type_out + type_arg["short&"]= type_out + type_arg["unsigned&"]= type_out + type_arg["std::string&"]= type_out + type_arg["std::vector&"]= type_out + +# +# +# record sep is ");\n" whith blanks all around, and optional "(" at the beginning + RS="[(]?[ ]*[)][ ]*;[ ]*\n?" + FS="[ ]*[(,][ ]*" # field sep is either "(" or "," surrounded by blanks +} + +# --------------------- treatment 1 ---------------------------------- +# +# extract from fields types, function name, and argument's names +# +{ + nitems = split($0, items); + for (i=1; i<=nitems; i++) { + split(items[i], j, " "); + l=0; for (k in j) {l++;} + k=j[1]; + for (ll=2; ll\n"\ + " "name[1]"\n"\ + " \n"\ + " \n"\ + " \n"\ + " 0\n"\ + >> catalog_file + + print " " >> catalog_file + for (i=2; i<=nitems; i++) + if (way[i] == type_in) { + print " \n"\ + " "name[i]"\n"\ + " "type[i]"\n"\ + " \n"\ + " " >> catalog_file + } + print " \n" >> catalog_file + + print " " >> catalog_file + + if (type[1] != "void") + print " \n"\ + " return\n"\ + " "type[1]"\n"\ + " \n"\ + " " >> catalog_file + + for (i=2; i<=nitems; i++) + if (way[i] == type_out) { + print " \n"\ + " "name[i]"\n"\ + " "type[i]"\n"\ + " \n"\ + " " >> catalog_file + } + print " \n" >> catalog_file + + print " \n" >> catalog_file +} +# +END { + print " \n"\ + " \n"\ + " \n"\ + " \n"\ + "" >> catalog_file +} diff --git a/src/wrappergen/src/renameSalomeModule b/src/wrappergen/src/renameSalomeModule new file mode 100755 index 000000000..da37ca390 --- /dev/null +++ b/src/wrappergen/src/renameSalomeModule @@ -0,0 +1,124 @@ +#! /bin/bash + +usage() +{ + echo + echo Usage : + echo " renameSalomeModule oldName newName dirModule" + echo + echo " -> replace any occurence of oldName by newName in module dirModule" + echo + echo " (nex name cannot contain old name)" + echo + echo Example : + echo + echo " cp -r HELLO_SRC CALCULATOR_SRC" + echo " renameSalomeModule HELLO CALCULATOR CALCULATOR_SRC" + echo + exit 1 +} + +rename_dir() +{ + # Rename the first directory containing $oldName in their file name + liste=`find . -type d -name "*${oldName}*"` + for file in $liste + do + newFile=`echo $file | sed "s/${oldName}/${newName}/g"` + echo "mv -f $file $newFile" + mv -f $file $newFile + return 1 + done + return 0 +} + +if [ "$1" == "-i" ] +then + # mode interactif + if [ $# -ne 4 ] + then + usage + fi + oldName=$2 + newName=$3 + moduleName=$4 +else + if [ $# -ne 3 ] + then + usage + fi + oldName=$1 + newName=$2 + moduleName=$3 +fi + +# check names for restriction +echo $newName | grep $oldName > /dev/null +if [ $? -eq 0 ] +then + echo -e "Sorry : There is a restriction!\nNew name cannot contain old name.\n" + usage +fi + +today=`date +%d%m%y` + +# Check arguments +if [ "$1" == "-i" ] # mode interactif +then + echo replace any occurence of $oldName by $newName in module $moduleName +else + clear + echo "Do you want to replace any occurence of $oldName by $newName in module $moduleName ?" + echo + read rep + case $rep in + + y* | Y* | o* | O* ) ;; + * ) usage ;; + esac +fi + +cd ${moduleName} +echo +echo Renamed Directories: +echo + +# rename directories one by one +rename_dir +while [ $? -eq 1 ] +do + rename_dir +done + +# rename files containing ${oldName} in their name +echo +echo Renamed Files: +echo +liste=`find . -name "*${oldName}*"` +for file in $liste +do + newFile=`echo $file | sed "s/${oldName}/${newName}/g"` + echo "mv -f $file $newFile" + mv -f $file $newFile +done + +echo +echo Modified Files: +echo +# modify all files containing $oldName, replace occurences by $newName +liste=`find -name "*"` +for file in $liste +do + if [ -f $file ] + then + grep $oldName $file > /dev/null 2>&1 + if [ $? -eq 0 ] + then + echo $file + cat $file | sed "s/${oldName}/${newName}/g" > fic_temp_${today} + cp -f fic_temp_${today} $file + fi + fi +done +rm -f fic_temp_${today} +cd - diff --git a/src/wrappergen/src/runIDLparser b/src/wrappergen/src/runIDLparser new file mode 100755 index 000000000..e4f8e22e0 --- /dev/null +++ b/src/wrappergen/src/runIDLparser @@ -0,0 +1,67 @@ +#! /bin/bash + +# print the help message ==================================== + +# test $@="-h" -o -z $@ + +hh=0 + +if test "$#" = "0";then + hh=1 +else + for a in $@; do + if test "$a" = "-h"; then + hh=1 + fi + done +fi + +if test "$hh" = "1" ; then + echo "" + echo "Usage : " + echo "" + echo " to run IDLparser:" + echo "" + echo " $0 -Wbcatalog=[,icon=][,version=][,author=][,name=][,multistudy=][,remove=component_name] " + echo "" + echo " to have omniidl help:" + echo "" + echo " $0 -u " + echo "" + exit 1 +fi +#============================================================ + +# environment ============================================== + + +DIR=`pwd` +EXEC_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` +cd $EXEC_DIR/.. +SALOME_HOME_DIR=`pwd` +cd $EXEC_DIR + +export SALOME_HOME_DIR +export SALOME_SRC_DIR=/dn05/salome/apv/WORK/SOURCE/KERNEL +export ORB_HOME_DIR=/dn05/salome/ref/PRODUCTS/IW/omniORB-3.0.5 + +export LD_LIBRARY_PATH=${SALOME_HOME_DIR}/lib:${LD_LIBRARY_PATH} + +# echo $SALOME_HOME_DIR = SALOME_HOME_DIR +# echo $SALOME_SRC_DIR = SALOME_SRC_DIR + +PYVTK_PATH= +export PYTHONPATH=${PYTHONPATH}:${SALOME_HOME_DIR}/idl:${SALOME_HOME_DIR}/bin:${SALOME_HOME_DIR}/lib:${PYVTK_PATH}:${EXEC_DIR} + +MICORC=/dev/null +export MICORC + + +cd $DIR + +PYTHONPATH=${PYTHONPATH}:${SALOME_HOME_DIR}/bin +#============================================================ + +# omiidl ==================================================== +omniidl -bIDLparser -I ${SALOME_SRC_DIR}/idl $@ +#============================================================ diff --git a/src/yacsloader/LoadState.cxx b/src/yacsloader/LoadState.cxx new file mode 100644 index 000000000..10bc40637 --- /dev/null +++ b/src/yacsloader/LoadState.cxx @@ -0,0 +1,646 @@ + +#include "LoadState.hxx" +#include "Proc.hxx" +#include "Node.hxx" +#include "ForLoop.hxx" +#include "WhileLoop.hxx" +#include "Switch.hxx" +#include "InGate.hxx" +#include "Runtime.hxx" +#include "InputPort.hxx" +#include "ElementaryNode.hxx" + +#include +#include +#include +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +XMLReadState stateParser::_state; +std::string stateParser::_what; +std::stack stateParser::_stackState; +Proc* stateParser::_p; +Runtime* stateParser::_runtime; +std::map stateParser::_nodeStateValue; +std::map stateParser::_nodeStates; + +// ---------------------------------------------------------------------------- +void stateParser::setProc(Proc* p) +{ + _p= p; +} + +void stateParser::setRuntime(Runtime* runtime) +{ + _runtime = runtime; +} + +void stateParser::init(const xmlChar** p, xmlParserBase* father) +{ + DEBTRACE("stateParser::init()"); + _state = XMLNOCONTEXT; + _father = father; + _stackState.push(_state); + _nodeStateValue["INITED"] =YACS::INITED; + _nodeStateValue["TOLOAD"] =YACS::TOLOAD; + _nodeStateValue["LOADED"] =YACS::LOADED; + _nodeStateValue["TOACTIVATE"] =YACS::TOACTIVATE; + _nodeStateValue["ACTIVATED"] =YACS::ACTIVATED; + _nodeStateValue["DESACTIVATED"] =YACS::DESACTIVATED; + _nodeStateValue["DONE"] =YACS::DONE; + _nodeStateValue["SUSPENDED"] =YACS::SUSPENDED; + _nodeStateValue["LOADFAILED"] =YACS::LOADFAILED; + _nodeStateValue["EXECFAILED"] =YACS::EXECFAILED; + _nodeStateValue["PAUSE"] =YACS::PAUSE; + _nodeStateValue["INTERNALERR"] =YACS::INTERNALERR; + _nodeStateValue["DISABLED"] =YACS::DISABLED; + _nodeStateValue["FAILED"] =YACS::FAILED; + _nodeStateValue["ERROR"] =YACS::ERROR; +} + + +void stateParser::onStart (const XML_Char* elem, const xmlChar** p) +{ + DEBTRACE("stateParser::onStart"); + string element(elem); + stateParser *parser = 0; + if (element == "graphState") parser = new graphParser(); + else + { + _what = "expected , got <" + element + ">"; + _state = XMLFATALERROR; + stopParse(_what); + } + if (parser) + { + _stackParser.push(parser); + XML_SetUserData(_xmlParser, parser); + parser->init(p); + } +} + + +void stateParser::onEnd (const XML_Char* name) +{ + _stackState.pop(); + _state = _stackState.top(); + //cerr << "end " << name << " " << _stackParser.size() << " " << _state << endl; +} + + +void stateParser::charData(std::string data) +{ + //cerr << "data " << data << endl; +} + +// ---------------------------------------------------------------------------- + +void graphParser::init(const xmlChar** p, xmlParserBase* father) +{ + // DEBTRACE("graphParser::init()"); + _state = XMLINGRAPH; + _father = father; + _stackState.push(_state); + if (p) getAttributes(p); +} + +void graphParser::onStart (const XML_Char* elem, const xmlChar** p) +{ + string element(elem); + stateParser *parser = 0; + if (element == "node") parser = new nodeParser(); + else + { + _what = "expected , got <" + element + ">"; + _state = XMLFATALERROR; + stopParse(_what); + } + if (parser) + { + _stackParser.push(parser); + XML_SetUserData(_xmlParser, parser); + parser->init(p, this); + } +} + + +void graphParser::onEnd (const XML_Char* name) +{ + std::map::const_iterator it; + for (it = _nodeStates.begin(); it != _nodeStates.end(); it++) + { + Node *node =0; + string nodeName = it->first; + DEBTRACE("nodeName = " << nodeName); + if ( _p->nodeMap.find(nodeName) != _p->nodeMap.end() ) + node = _p->getChildByName(nodeName); + else + { + assert(_p->getName() == nodeName); + node = _p; + } + InGate* inGate = node->getInGate(); + list backlinks = inGate->getBackLinks(); + for (list::iterator io = backlinks.begin(); io != backlinks.end(); io++) + { + Node* fromNode = (*io)->getNode(); + string fromName; + if (fromNode == _p) fromName = fromNode->getName(); + else fromName = _p->getChildName(fromNode); + if (_nodeStates[fromName] == YACS::DONE) + { + DEBTRACE(" fromNode = " << fromName); + inGate->setPrecursorDone(*io); + } + } + } + stateParser::onEnd(name); +} + +// ---------------------------------------------------------------------------- + +void nodeParser::init(const xmlChar** p, xmlParserBase* father) +{ + //DEBTRACE("nodeParser::init()"); + _state = XMLINNODE; + _father = father; + _stackState.push(_state); + if (p) getAttributes(p); +} + + +void nodeParser::onStart (const XML_Char* elem, const xmlChar** p) +{ + string element(elem); + stateParser *parser = 0; + if (element == "inputPort") parser = new portParser(); + else if (element == "name") parser = new attrParser(); + else if (element == "state") parser = new attrParser(); + else if (element == "nsteps") parser = new attrParser(); + else if (element == "nbdone") parser = new attrParser(); + else if (element == "condition") parser = new attrParser(); + else if (element == "inputPort") parser = new portParser(); + else + { + _what = "expected name, state or inputPort, got <" + element + ">"; + _state = XMLFATALERROR; + stopParse(_what); + } + if (parser) + { + _stackParser.push(parser); + XML_SetUserData(_xmlParser, parser); + parser->init(p, this); + } +} + +void nodeParser::onEnd (const XML_Char* name) +{ + string nodeName = _mapAttrib["name"]; + string nodeType = _mapAttrib["type"]; + string nodeState = _mapAttrib["state"]; + cerr << "nodeName: " << nodeName \ + << " nodeType: " << nodeType \ + << " nodeState: " << nodeState << endl; +// for (std::map< std::string, Node * >::iterator it=_p->nodeMap.begin(); it != _p->nodeMap.end(); it++) +// cerr << "nodeMap: " << it->first << endl; + _nodeStates[nodeName] = _nodeStateValue[nodeState]; + Node *node =0; + if ( _p->nodeMap.find(nodeName) != _p->nodeMap.end() ) + node = _p->getChildByName(nodeName); + else + { + assert(_p->getName() == nodeName); + node = _p; + } + assert(_nodeStateValue.find(nodeState) != _nodeStateValue.end()); + YACS::ENGINE::StateLoader(node, _nodeStateValue[nodeState]); + + if (nodeType == "forLoop") + { + if (_mapAttrib.find("nsteps") == _mapAttrib.end()) + { + _what = "no attribute nsteps in forLoop " + _mapAttrib["name"]; + _state = XMLFATALERROR; + stopParse(_what); + } + int nsteps = atoi(_mapAttrib["nsteps"].c_str()); + + if (_mapAttrib.find("nbdone") == _mapAttrib.end()) + { + _what = "no attribute nbdone in forLoop " + _mapAttrib["name"]; + _state = XMLFATALERROR; + stopParse(_what); + } + int nbdone = atoi(_mapAttrib["nbdone"].c_str()); + DEBTRACE("nsteps = " << nsteps << ", nbdone = " << nbdone); + + ForLoop* loop = dynamic_cast(node); + if (!loop) + { + _what = "node is not a ForLoop: " + _mapAttrib["name"]; + _state = XMLFATALERROR; + stopParse(_what); + } + loop->edGetNbOfTimesInputPort()->edInit(nsteps); + YACS::ENGINE::NbDoneLoader(loop, nbdone); + } + + else if (nodeType == "whileLoop") + { + if (_mapAttrib.find("nbdone") == _mapAttrib.end()) + { + _what = "no attribute nbdone in forLoop " + _mapAttrib["name"]; + _state = XMLFATALERROR; + stopParse(_what); + } + int nbdone = atoi(_mapAttrib["nbdone"].c_str()); + + if (_mapAttrib.find("condition") == _mapAttrib.end()) + { + _what = "no attribute condition in forLoop " + _mapAttrib["name"]; + _state = XMLFATALERROR; + stopParse(_what); + } + bool condition = atoi(_mapAttrib["condition"].c_str()); + DEBTRACE("condition = " << condition << ", nbdone = " << nbdone); + + WhileLoop* loop = dynamic_cast(node); + if (!loop) + { + _what = "node is not a WhileLoop: " + _mapAttrib["name"]; + _state = XMLFATALERROR; + stopParse(_what); + } + loop->edGetConditionPort()->edInit(condition); + YACS::ENGINE::NbDoneLoader(loop, nbdone); + } + + else if (nodeType == "switch") + { + if (_mapAttrib.find("condition") == _mapAttrib.end()) + { + _what = "no attribute condition in switch " + _mapAttrib["name"]; + _state = XMLFATALERROR; + stopParse(_what); + } + int condition = atoi(_mapAttrib["condition"].c_str()); + DEBTRACE("condition = " << condition); + + Switch* mySwitch = dynamic_cast(node); + if (!mySwitch) + { + _what = "node is not a Switch: " + _mapAttrib["name"]; + _state = XMLFATALERROR; + stopParse(_what); + } + mySwitch->edGetConditionPort()->edInit(condition); + } + + stateParser::onEnd(name); +} + +// ---------------------------------------------------------------------------- + +void attrParser::init(const xmlChar** p, xmlParserBase* father) +{ + //DEBTRACE("attrParser::init()"); + //_state = XMLINNODE; + _father = father; + _stackState.push(_state); // keep current state + if (p) getAttributes(p); +} + + +void attrParser::onStart (const XML_Char* elem, const xmlChar** p) +{ + string element(elem); + _what = "expected nothing, got <" + element + ">"; + _state = XMLFATALERROR; + stopParse(_what); +} + +void attrParser::charData(std::string data) +{ + _attrValue = data; +} + +void attrParser::onEnd (const XML_Char* name) +{ + // cerr << "end attrParser " << name << " " << _stackParser.size() << endl; + assert(_father); + _father->setAttribute((char*)name, _attrValue); + stateParser::onEnd(name); +} + +// ---------------------------------------------------------------------------- + +void portParser::init(const xmlChar** p, xmlParserBase* father) +{ + // DEBTRACE("portParser::init()"); + _state = XMLINPORT; + _father = father; + assert( dynamic_cast (father)); + _stackState.push(_state); + if (p) getAttributes(p); +} + + +void portParser::onStart (const XML_Char* elem, const xmlChar** p) +{ + string element(elem); + stateParser *parser = 0; + if (element == "name") parser = new attrParser(); + else if (element == "value") parser = new valueParser(); + else + { + _what = "expected name or value, got <" + element + ">"; + _state = XMLFATALERROR; + stopParse(_what); + } + if (parser) + { + _stackParser.push(parser); + XML_SetUserData(_xmlParser, parser); + parser->init(p, this); + } +} + +void portParser::addData(std::string value) +{ + _data = value; +} + +void portParser::onEnd (const XML_Char* name) +{ + cerr << "portName: " << _mapAttrib["name"] << endl; + cerr << "value: " << _data << endl; + string nodeName = _father->getAttribute("name"); + string nodeType = _father->getAttribute("type"); + Node *node = _p->getChildByName(nodeName); + if (nodeType == "elementaryNode") + { + ElementaryNode* eNode = dynamic_cast(node); + assert(eNode); + InputPort *port = eNode->getInputPort(_mapAttrib["name"]); + port->edInit("XML",_data.c_str()); + } + else if (nodeType == "forLoop") + { + string what="no way to set a port value on port " + _mapAttrib["name"]; + what += " in node " + nodeName + " of type " + nodeType; + throw Exception(what); + } + else if (nodeType == "whileLoop") + { + string what="no way to set a port value on port " + _mapAttrib["name"]; + what += " in node " + nodeName + " of type " + nodeType; + throw Exception(what); + } + else if (nodeType == "switch") + { + string what="no way to set a port value on port " + _mapAttrib["name"]; + what += " in node " + nodeName + " of type " + nodeType; + throw Exception(what); + } + else if (nodeType == "foreachLoop") + { + string what="no way to set a port value on port " + _mapAttrib["name"]; + what += " in node " + nodeName + " of type " + nodeType; + throw Exception(what); + } + else + { + string what="no way to set a port value on port " + _mapAttrib["name"]; + what += " in node " + nodeName + " of type " + nodeType; + throw Exception(what); + } + + stateParser::onEnd(name); +} + +// ---------------------------------------------------------------------------- + +void valueParser::init(const xmlChar** p, xmlParserBase* father) +{ + // DEBTRACE("valueParser::init()"); + _state = XMLINVALUE; + _father = father; + _stackState.push(_state); + if (p) getAttributes(p); +} + + +void valueParser::onStart (const XML_Char* elem, const xmlChar** p) +{ + string element(elem); + // cerr << "value type " << element << endl; + stateParser *parser = 0; + if (element == "data") parser = new dataParser(); + else if (element == "array") parser = new arrayParser(); + else parser = new simpleTypeParser(); + if (parser) + { + _stackParser.push(parser); + XML_SetUserData(_xmlParser, parser); + parser->init(p, this); + } +} + +void valueParser::addData(std::string value) +{ + _data = "" + value + ""; +} + +void valueParser::onEnd (const XML_Char* name) +{ + // cerr << _data << endl; + _father->addData(_data); + string elem = (char *) name; + //if (elem == "value" || elem == "data" || elem == "array") + stateParser::onEnd(name); + //else assert(0); //DEBTRACE("valueParser::onEnd " << elem); +} + +// ---------------------------------------------------------------------------- + +void arrayParser::init(const xmlChar** p, xmlParserBase* father) +{ + // DEBTRACE("arrayParser::init()"); + _state = XMLINVALUE; + _father = father; + _stackState.push(_state); + if (p) getAttributes(p); +} + + +void arrayParser::onStart (const XML_Char* elem, const xmlChar** p) +{ + string element(elem); + // cerr << "array type " << element << endl; + stateParser *parser = 0; + if (element == "data") parser = new dataParser(); + else + { + _what = "expected data, got <" + element + ">"; + _state = XMLFATALERROR; + stopParse(_what); + } + if (parser) + { + _stackParser.push(parser); + XML_SetUserData(_xmlParser, parser); + parser->init(p, this); + } +} + +void arrayParser::addData(std::string value) +{ + string val = "" + value + ""; + _data = val; +} + + +void arrayParser::onEnd (const XML_Char* name) +{ + // cerr << "arrayParser::onEnd " << name << endl; + // cerr << _data << endl; + _father->addData(_data); + stateParser::onEnd(name); +} + +// ---------------------------------------------------------------------------- + +void dataParser::init(const xmlChar** p, xmlParserBase* father) +{ + // DEBTRACE("dataParser::init()"); + _state = XMLINVALUE; + _father = father; + _stackState.push(_state); + if (p) getAttributes(p); +} + + +void dataParser::onStart (const XML_Char* elem, const xmlChar** p) +{ + string element(elem); + // cerr << "data type " << element << endl; + stateParser *parser = 0; + if (element == "value") parser = new valueParser(); + else + { + _what = "expected value, got <" + element + ">"; + _state = XMLFATALERROR; + stopParse(_what); + } + if (parser) + { + _stackParser.push(parser); + XML_SetUserData(_xmlParser, parser); + parser->init(p, this); + } +} + +void dataParser::addData(std::string value) +{ + _dataList.push_back(value); +} + +void dataParser::onEnd (const XML_Char* name) +{ + // cerr << "dataParser::onEnd " << name << endl; + string val = ""; + while (!_dataList.empty()) + { + val += _dataList.front(); + _dataList.pop_front(); + } + val += ""; + // cerr << val << endl; + _father->addData(val); + stateParser::onEnd(name); +} + +// ---------------------------------------------------------------------------- + +void simpleTypeParser::init(const xmlChar** p, xmlParserBase* father) +{ + // DEBTRACE("simpleTypeParser::init()"); + _state = XMLINVALUE; + _father = father; + _stackState.push(_state); + if (p) getAttributes(p); +} + +void simpleTypeParser::onStart (const XML_Char* elem, const xmlChar** p) +{ + string element(elem); + _what = "expected nothing, got <" + element + ">"; + _state = XMLFATALERROR; + stopParse(_what); +} + +void simpleTypeParser::onEnd (const XML_Char* name) +{ + // cerr << "simpleTypeParser::onEnd " << name << endl; + string val = string("<") + (char*) name + ">" + _data + ""; + // cerr << val << endl; + _father->addData(val); + stateParser::onEnd(name); +} + +void simpleTypeParser::charData(std::string data) +{ + // cerr << "simple data " << data << endl; + _data = data; +} + + + +// ---------------------------------------------------------------------------- + +stateLoader::stateLoader(xmlParserBase* parser, + YACS::ENGINE::Proc* p) : xmlReader(parser) +{ + _runtime = getRuntime(); + _p = p; +} + +void stateLoader::parse(std::string xmlState) +{ + stateParser *parser = dynamic_cast (_rootParser); + parser->setProc(_p); + parser->setRuntime(_runtime); + + xmlReader::parse(xmlState); + + cerr << parser->_state << endl; + switch (parser->_state) + { + case XMLNOCONTEXT: + case XMLDONE: + { + cerr << "parse OK" << endl; + break; + } + case XMLFATALERROR: + { + string what = "Abort Parse: " + parser->_what; + throw Exception(what); + break; + } + default: + { + string what = "Abort Parse: unknown execution problem"; + throw Exception(what); + break; + } + } +} + diff --git a/src/yacsloader/LoadState.hxx b/src/yacsloader/LoadState.hxx new file mode 100644 index 000000000..5fe4665e0 --- /dev/null +++ b/src/yacsloader/LoadState.hxx @@ -0,0 +1,150 @@ +#ifndef __LOADSTATE_HXX_ +#define __LOADSTATE_HXX_ + +#include "xmlParserBase.hxx" + +#include "define.hxx" +#include "Exception.hxx" + +namespace YACS +{ + namespace ENGINE + { + class Proc; + class Runtime; + + /*! \brief class for parse an xml file, use a dedicated parser, to load a + * saved state of a SALOME execution. + */ + + class stateLoader: public xmlReader + { + public: + stateLoader(xmlParserBase* parser, + YACS::ENGINE::Proc* p); + virtual void parse(std::string xmlState); + protected: + Proc* _p; + Runtime* _runtime; + }; + + typedef enum + { + XMLNOCONTEXT = 0, + XMLINGRAPH = 1, + XMLINNODE = 2, + XMLINPORT = 3, + XMLINVALUE = 4, + XMLDONE = 5, + XMLFATALERROR = 6 + } XMLReadState; + + //! \brief specialized parser to load SALOME execution saved states. + /*! this base class must be derived to build specific parsers for each tag + * defined in the xml file + */ + + class stateParser: public xmlParserBase + { + public: + static XMLReadState _state; + static std::string _what; + + static void setProc(Proc* p); + static void setRuntime(Runtime* runtime); + + public: + virtual void init(const xmlChar** p, xmlParserBase* father=0); + + protected: + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + virtual void charData(std::string data); + + protected: + static std::stack _stackState; + static Proc* _p; + static Runtime* _runtime; + static std::map _nodeStateValue; + static std::map _nodeStates; + }; + + class graphParser: public stateParser + { + public: + virtual void init(const xmlChar** p, xmlParserBase* father=0); + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + }; + + + class nodeParser: public stateParser + { + public: + virtual void init(const xmlChar** p, xmlParserBase* father=0); + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + std::string _nodeName; + std::string _nodeState; + }; + + class attrParser: public stateParser + { + public: + virtual void init(const xmlChar** p, xmlParserBase* father=0); + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void charData(std::string data); + virtual void onEnd (const XML_Char* name); + std::string _attrValue; + }; + + + class portParser: public stateParser + { + public: + virtual void init(const xmlChar** p, xmlParserBase* father=0); + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + virtual void addData(std::string value); + }; + + class valueParser: public stateParser + { + public: + virtual void init(const xmlChar** p, xmlParserBase* father=0); + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + virtual void addData(std::string value); + }; + + class arrayParser: public stateParser + { + public: + virtual void init(const xmlChar** p, xmlParserBase* father=0); + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + virtual void addData(std::string value); + }; + + class dataParser: public stateParser + { + public: + virtual void init(const xmlChar** p, xmlParserBase* father=0); + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + virtual void addData(std::string value); + std::list _dataList; + }; + + class simpleTypeParser: public stateParser + { + public: + virtual void init(const xmlChar** p, xmlParserBase* father=0); + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + virtual void charData(std::string data); + }; + + } +} +#endif diff --git a/src/yacsloader/Makefile.am b/src/yacsloader/Makefile.am new file mode 100644 index 000000000..ff401bdc8 --- /dev/null +++ b/src/yacsloader/Makefile.am @@ -0,0 +1,121 @@ + +include $(top_srcdir)/adm/unix/make_begin.am + +SUBDIRS = Test + +bin_PROGRAMS=driver debugger resume + +lib_LTLIBRARIES = libYACSloader.la + +libYACSloader_la_SOURCES = \ + parsers.cxx LoadState.cxx xmlParserBase.cxx \ + $(__dummy__) + +EXTRA_libYACSloader_la_SOURCES = \ + $(__dummy__) + +libYACSloader_la_LIBADD = ../engine/libYACSEngine.la + +AM_CXXFLAGS = \ + $(THREAD_DEF) \ + $(PYTHON_CPPFLAGS) \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CXXFLAGS) \ + -I$(srcdir) \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + -I$(srcdir)/../runtime + +if SALOME_KERNEL +SALOME_LIBS=-L$(KERNEL_ROOT_DIR)/lib/salome -lSalomeLifeCycleCORBA +endif + + +driver_SOURCES = driver.cxx + +driver_CXXFLAGS = -g -DYACS_PTHREAD \ + $(PYTHON_CPPFLAGS) \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CXXFLAGS) \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + -I$(srcdir)/../runtime + +driver_LDADD = libYACSloader.la \ + ../runtime/libYACSRuntimeSALOME.la \ + ../engine/libYACSEngine.la \ + $(SALOME_LIBS) \ + $(OMNIORB_LIBS) \ + $(PYTHON_LDFLAGS) \ + $(PYTHON_EXTRA_LIBS) + +driver_LDFLAGS = $(PYTHON_EXTRA_LDFLAGS) -lexpat -pthread -lxml2 + + +resume_SOURCES = resume.cxx + +resume_CXXFLAGS = -g -DYACS_PTHREAD \ + $(PYTHON_CPPFLAGS) \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CXXFLAGS) \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + -I$(srcdir)/../runtime + +resume_LDADD = libYACSloader.la \ + ../runtime/libYACSRuntimeSALOME.la \ + ../engine/libYACSEngine.la \ + $(SALOME_LIBS) \ + $(OMNIORB_LIBS) \ + $(PYTHON_LDFLAGS) \ + $(PYTHON_EXTRA_LIBS) + +resume_LDFLAGS = $(PYTHON_EXTRA_LDFLAGS) -lexpat -pthread -lxml2 + + +debugger_SOURCES = debugger.cxx + +debugger_CXXFLAGS = -g -DYACS_PTHREAD \ + $(PYTHON_CPPFLAGS) \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CXXFLAGS) \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + -I$(srcdir)/../runtime + +debugger_LDADD = libYACSloader.la \ + ../runtime/libYACSRuntimeSALOME.la \ + ../engine/libYACSEngine.la \ + $(SALOME_LIBS) \ + $(OMNIORB_LIBS) \ + $(PYTHON_LDFLAGS) \ + $(PYTHON_EXTRA_LIBS) + +debugger_LDFLAGS = $(PYTHON_EXTRA_LDFLAGS) -lexpat -pthread -lxml2 + + +SWIG_PYTHON_INCLUDES = -noexcept -I$(srcdir)/../bases -I$(srcdir)/../engine +BUILT_SOURCES = loaderWRAP.cxx + +pkgpython_PYTHON = loader.py +pkgpyexec_LTLIBRARIES = _loader.la + +_loader_la_SOURCES = \ + loaderWRAP.cxx + +_loader_la_CXXFLAGS = \ + $(THREAD_DEF) \ + $(PYTHON_CPPFLAGS) \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CXXFLAGS) \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + -I$(srcdir)/../runtime + +_loader_la_LDFLAGS = -module -lexpat -pthread -lxml2 + +_loader_la_LIBADD = libYACSloader.la \ + ../runtime/libYACSRuntimeSALOME.la \ + ../engine/libYACSEngine.la + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/yacsloader/README.html b/src/yacsloader/README.html new file mode 100644 index 000000000..7c7bae688 --- /dev/null +++ b/src/yacsloader/README.html @@ -0,0 +1,406 @@ + + + + + + +Work in progress + + + +
+

Work in progress

+ +
+

What is done ?

+
    +
  • XML parser with expat. No more xsd : problem with license
  • +
  • support several elementary nodes : CompoNode, +RefNode, FuncNode, ScriptNode
  • +
  • support all composite nodes : Bloc, While, ForLoop, ForEachLoop, Switch
  • +
  • support control links, data links and datastream links (DSC and Calcium datastream)
  • +
  • support initialization from data in XML-RPC syntax
  • +
  • support execution in threaded Executor : manage Python GIL
  • +
  • the Runtime SALOME is connected to the SALOME LifeCycle to implement +CompoNode. It's not yet possible to choose a computer or to express +a resource constraint.
  • +
  • dump of the schema state in graphviz form (.dot file)
  • +
  • execution error management : an ElementaryNode signals an error by throwing +an exception. This exception is catched by the executor which notifies the +ElementaryNode and makes propagate the error to all depending nodes and to +the father. All depending nodes and the father are put in FAILED state. The +ElementaryNode is put in ERROR state.
  • +
  • Python interface : main C++ API wrapped with SWIG to be able to create schema from Python +and to control execution
  • +
  • a Salome loader in pyqt directory (salomeloader.py)
  • +
+
+
+

To do

+
+

Output a trace (PR)

+

It would be fine to have an execution trace (event sequence) +to be able to analyze the execution afterwards.

+
+
+

Make another runtime (MT)

+

To check the design

+
+
+

Save/load (PR)

+

Be able to dump the schema state in a XML file. +Then to reload the state and restart from this state.

+

Two levels : with CORBA objects and without

+
+
+

Partial execution

+

Execute some selected nodes (directly or with backtrack)

+
+ +
+

Add other data types

+

struct, enum

+
+
+

Managing several schema

+

One executor for all schemas or one executor by schema ?

+
+
+

Better management of outputs in ElementaryNode

+

Execution in threads : all outputs are mixed

+
+
+

Errors when reading the XML file

+
    +
  • Stop at first error (Exception)
  • +
  • Collect all errors
  • +
  • Check the overall validity
  • +
+
+
+

Errors when executing

+
    +
  • Stop as soon as possible when encountering an error
  • +
  • Or execute most calculations possible
  • +
+

Need an execution option to specify that

+

To be able to restart an execution on another computer

+
+
+

Add macro nodes

+

Define macronodes +Be able to reference them several times

+
+
+

Discover base types from runtime (GUI and parser)

+

Runtime would have a service to give all known types (map name:type)

+
+
+
+ + diff --git a/src/yacsloader/README.txt b/src/yacsloader/README.txt new file mode 100644 index 000000000..929436a0c --- /dev/null +++ b/src/yacsloader/README.txt @@ -0,0 +1,91 @@ + +=========================== +Work in progress +=========================== + +.. contents:: + +What is done ? +============================== +- XML parser with expat. No more xsd : problem with license +- support several elementary nodes : CompoNode, + RefNode, FuncNode, ScriptNode +- support all composite nodes : Bloc, While, ForLoop, ForEachLoop, Switch +- support control links, data links and datastream links (DSC and Calcium datastream) +- support initialization from data in XML-RPC syntax +- support execution in threaded Executor : manage Python GIL +- the Runtime SALOME is connected to the SALOME LifeCycle to implement + CompoNode. It's not yet possible to choose a computer or to express + a resource constraint. +- dump of the schema state in graphviz form (.dot file) +- execution error management : an ElementaryNode signals an error by throwing + an exception. This exception is catched by the executor which notifies the + ElementaryNode and makes propagate the error to all depending nodes and to + the father. All depending nodes and the father are put in FAILED state. The + ElementaryNode is put in ERROR state. +- Python interface : main C++ API wrapped with SWIG to be able to create schema from Python + and to control execution +- a Salome loader in pyqt directory (salomeloader.py) + +To do +=============================== + +Output a trace (PR) +-------------------------------------- +It would be fine to have an execution trace (event sequence) +to be able to analyze the execution afterwards. + +Make another runtime (MT) +--------------------------- +To check the design + +Save/load (PR) +-------------------- +Be able to dump the schema state in a XML file. +Then to reload the state and restart from this state. + +Two levels : with CORBA objects and without + +Partial execution +----------------------- +Execute some selected nodes (directly or with backtrack) + +Deployment, resource management +------------------------------------- +Not easy + +Add other data types +----------------------------------- +struct, enum + +Managing several schema +------------------------------------------------------ +One executor for all schemas or one executor by schema ? + +Better management of outputs in ElementaryNode +------------------------------------------------- +Execution in threads : all outputs are mixed + +Errors when reading the XML file +---------------------------------------------------- +- Stop at first error (Exception) +- Collect all errors +- Check the overall validity + +Errors when executing +--------------------------------------- +- Stop as soon as possible when encountering an error +- Or execute most calculations possible + +Need an execution option to specify that + +To be able to restart an execution on another computer + +Add macro nodes +---------------------------- +Define macronodes +Be able to reference them several times + +Discover base types from runtime (GUI and parser) +-------------------------------------------------------------- +Runtime would have a service to give all known types (map name:type) diff --git a/src/yacsloader/Test/Makefile.am b/src/yacsloader/Test/Makefile.am new file mode 100644 index 000000000..ffb9943d1 --- /dev/null +++ b/src/yacsloader/Test/Makefile.am @@ -0,0 +1,77 @@ + +include $(top_srcdir)/adm/unix/make_begin.am + +check_PROGRAMS = TestYacsLoader echoSrv +bin_PROGRAMS = echoSrv + +check_SCRIPTS = \ + YacsLoaderTest.sh \ + YacsLoaderInSessionTest.sh \ + YacsLoaderInSessionTest2.sh \ + display.sh \ + waitContainers.py \ + testExec.py + +bin_SCRIPTS = display.sh + +TESTS = YacsLoaderTest.sh +TESTS_ENVIRONMENT=$(SHELL) -x + +TestYacsLoader_SOURCES = \ + TestYacsLoader.cxx \ + YacsLoaderTest.cxx + +TestYacsLoader_LDADD = \ + $(OMNIORB_LIBS) \ + $(PYTHON_LDFLAGS) \ + $(PYTHON_EXTRA_LIBS) \ + ../libYACSloader.la \ + ../../runtime/libYACSRuntimeSALOME.la \ + ../../engine/libYACSEngine.la \ + ../../bases/libYACSBases.la + +TestYacsLoader_LDFLAGS = \ + @CPPUNIT_LIBS@ -pthread -ldl -lxml2 -lexpat + +TestYacsLoader_CXXFLAGS = \ + $(THREAD_DEF) \ + $(CPPUNIT_INCLUDES) \ + $(PYTHON_CPPFLAGS) \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CCXFLAGS) \ + -I$(srcdir)/.. \ + -I$(srcdir)/../../bases \ + -I$(srcdir)/../../bases/Test \ + -I$(srcdir)/../../runtime \ + -I$(srcdir)/../../engine \ + -I/usr/include/libxml2 + +IDL_FILES = echo.idl +IDL_SOURCES = echoSK.cc +BUILT_SOURCES = $(IDL_SOURCES) echo_idl.py xmlrun.sh + +xmlrun.sh:xmlrun_orig.sh + cp $(srcdir)/xmlrun_orig.sh xmlrun.sh + +echoSrv_SOURCES = echoSrv.cxx $(IDL_SOURCES) + +echoSrv_CXXFLAGS = \ + -I$(srcdir)/../../bases \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CXXFLAGS) + +echoSrv_LDFLAGS = \ + $(OMNIORB_LIBS) + +AM_CXXFLAGS = $(THREAD_DEF) + +install-exec-local: $(IDL_FILES) + $(INSTALL) -d $(pkgpythondir) + ls $^ | while read file; do \ + $(OMNIORB_IDL) -bpython -C$(pkgpythondir) $$file ; \ + done + +check-local: + cat /tmp/${USER}/UnitTestsResult + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/yacsloader/Test/TestYacsLoader.cxx b/src/yacsloader/Test/TestYacsLoader.cxx new file mode 100644 index 000000000..5a59028d6 --- /dev/null +++ b/src/yacsloader/Test/TestYacsLoader.cxx @@ -0,0 +1,15 @@ + +#define UNIT_TEST_HEADER " --- TEST src/yacsloader" + +#include "YacsLoaderTest.hxx" + +using namespace YACS; +using namespace std; + +// --- Registers the fixture into the 'registry' + +CPPUNIT_TEST_SUITE_REGISTRATION( YacsLoaderTest ); + +// --- generic Main program from bases/Test + +#include "BasicMainTest.hxx" diff --git a/src/yacsloader/Test/YacsLoaderInSessionTest.sh.in b/src/yacsloader/Test/YacsLoaderInSessionTest.sh.in new file mode 100755 index 000000000..8db9d0ab5 --- /dev/null +++ b/src/yacsloader/Test/YacsLoaderInSessionTest.sh.in @@ -0,0 +1,25 @@ +#!/bin/bash + +# --- script to execute in SALOME environment (use runSession) + +# --- wait until SALOME containers are ready + +python @srcdir@/waitContainers.py + +# --- launch CORBA server echoSrv for tests + +./echoSrv & +pidecho=$! +echo $pidecho > "/tmp/YACSTEST_PidEcho" + +# --- launch unit tests + +export ROOT_SAMPLES=@ROOT_SRCDIR@/src/yacsloader/samples + +./TestYacsLoader +ret=$? +echo "exec status TestYacsLoader " $ret + +# --- return unit tests status + +exit $ret diff --git a/src/yacsloader/Test/YacsLoaderInSessionTest2.sh.in b/src/yacsloader/Test/YacsLoaderInSessionTest2.sh.in new file mode 100644 index 000000000..854a15b86 --- /dev/null +++ b/src/yacsloader/Test/YacsLoaderInSessionTest2.sh.in @@ -0,0 +1,32 @@ +#!/bin/bash + +# --- script to execute in SALOME environment (use runSession) + +# --- launch unit tests + +export ROOT_SAMPLES=@ROOT_SRCDIR@/src/yacsloader/samples + +export PYTHONPATH=..:../.libs:${PYTHONPATH} +export PYTHONPATH=../../runtime:../../runtime/.libs:${PYTHONPATH} +export PYTHONPATH=../../engine:../../engine/.libs:${PYTHONPATH} + +python @srcdir@/testExec.py +ret0=$? + +python @srcdir@/testResume.py +ret1=$? + +python @srcdir@/testLoader.py +ret2=$? + +python @srcdir@/testEdit.py +ret3=$? + +python @srcdir@/testSave.py +ret4=$? + +let ret=$ret0+$ret1+$ret2+$ret3+$ret4 + +# --- return unit tests status + +exit $ret diff --git a/src/yacsloader/Test/YacsLoaderTest.cxx b/src/yacsloader/Test/YacsLoaderTest.cxx new file mode 100644 index 000000000..fc76e21ca --- /dev/null +++ b/src/yacsloader/Test/YacsLoaderTest.cxx @@ -0,0 +1,710 @@ +#include "yacsconfig.h" +#include "RuntimeSALOME.hxx" +#include "PythonPorts.hxx" +#include "CORBAPorts.hxx" +#include "YacsLoaderTest.hxx" +#include "parsers.hxx" +#include "Proc.hxx" +#include "Exception.hxx" +#include "Executor.hxx" +#include "parsers.hxx" + +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; +using namespace YACS; +using namespace std; + +int driverTest(Proc* &p, const char* schema) +{ + DEBTRACE("+++++++++++++++++++ BEGIN test " << schema); + RuntimeSALOME::setRuntime(); + + YACSLoader loader; + Executor executor; + + try + { + p=loader.load(schema); + DEBTRACE("Proc *p = " << p); + std::ofstream f("toto"); + p->writeDot(f); + f.close(); + DEBTRACE("+++++++++++++++++++ BEGIN execution " << schema); + executor.RunW(p,0); + DEBTRACE("+++++++++++++++++++ END execution " << schema); + std::ofstream g("titi"); + p->writeDot(g); + g.close(); + DEBTRACE("+++++++++++++++++++ END test " << schema); + return 0; + } + catch (YACS::Exception& e) + { + DEBTRACE("YACS exception caught: "); + DEBTRACE(e.what()); + DEBTRACE("+++++++++++++++++++ END test in error " << schema); + return 1; + } + catch (const std::ios_base::failure&) + { + DEBTRACE("io failure"); + DEBTRACE("+++++++++++++++++++ END test in error " << schema); + return 1; + } + catch(CORBA::SystemException& ex) + { + DEBTRACE("Caught a CORBA::SystemException."); + CORBA::Any tmp; + tmp <<= ex; + CORBA::TypeCode_var tc = tmp.type(); + const char *p = tc->name(); + if ( *p != '\0' ) + { + DEBTRACE(p); + } + else + { + DEBTRACE(tc->id()); + } + DEBTRACE("+++++++++++++++++++ END test in error " << schema); + return 1; + } + catch(omniORB::fatalException& fe) + { + DEBTRACE("Caught omniORB::fatalException:" ); + DEBTRACE(" file: " << fe.file()); + DEBTRACE(" line: " << fe.line()); + DEBTRACE(" mesg: " << fe.errmsg()); + DEBTRACE("+++++++++++++++++++ END test in error " << schema); + return 1; + } + catch(...) + { + DEBTRACE("Caught unknown exception."); + DEBTRACE("+++++++++++++++++++ END test in error " << schema); + return 1; + } +} + +void YacsLoaderTest::setUp() +{ +} + +void YacsLoaderTest::tearDown() +{ +} + +void YacsLoaderTest::aschema() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/aschema.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p != 0); + if (p) + { + CORBA::Double dval = 0; + char *text = ""; + CPPUNIT_ASSERT(p->nodeMap["c0.c1.n1"]); + *((OutputCorbaPort*)p->nodeMap["c0.c1.n1"]->getOutputPort("p1"))->getAny() >>= dval; + PyObject *data = ((OutputPyPort*)p->nodeMap["node32"]->getOutputPort("p1"))->get(); + double val = PyFloat_AsDouble(data); + CPPUNIT_ASSERT_DOUBLES_EQUAL(22., dval, 1.E-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20., val, 1.E-12); + delete p; + } +} + +void YacsLoaderTest::bschema() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/bschema.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { + CORBA::Double dval = 0; + const char *text = ""; + *((OutputCorbaPort*)p->nodeMap["node1"]->getOutputPort("p1"))->getAny() >>= dval; + *((OutputCorbaPort*)p->nodeMap["node2"]->getOutputPort("p1"))->getAny() >>= text; + CPPUNIT_ASSERT_DOUBLES_EQUAL(24., dval, 1.E-12); + CPPUNIT_ASSERT_EQUAL(string("coucou"), string(text)); + delete p; + } +} + +void YacsLoaderTest::cschema() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/cschema.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); +#ifdef SALOME_KERNEL + if (p) + { + CORBA::Double dval = 0; + const char *text = ""; + *((OutputCorbaPort*)p->nodeMap["node1"]->getOutputPort("p1"))->getAny() >>= text; + CPPUNIT_ASSERT_EQUAL(string("Hello coucou!"), string(text) ); + text = ""; + *((OutputCorbaPort*)p->nodeMap["node2"]->getOutputPort("p1"))->getAny() >>= text; + CPPUNIT_ASSERT_EQUAL(string("Hello Hello coucou!!"), string(text) ); + delete p; + } +#endif +} + +void YacsLoaderTest::dschema() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/dschema.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); +#ifdef SALOME_KERNEL + if (p) + { + CORBA::Double dval = 0; + const char *text = ""; + *((OutputCorbaPort*)p->nodeMap["node1"]->getOutputPort("p1"))->getAny() >>= text; + CPPUNIT_ASSERT_EQUAL(string("Hello coucou!"), string(text) ); + text = ""; + *((OutputCorbaPort*)p->nodeMap["node2"]->getOutputPort("p1"))->getAny() >>= text; + CPPUNIT_ASSERT_EQUAL(string("Hello Hello coucou!!"), string(text) ); + text = ""; + *((OutputCorbaPort*)p->nodeMap["node3"]->getOutputPort("p1"))->getAny() >>= text; + CPPUNIT_ASSERT_EQUAL( string("Hello Hello coucou!!"), string(text)); + delete p; + } +#endif +} + +void YacsLoaderTest::eschema() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/eschema.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { + PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); + char *text = PyString_AsString(data); + CPPUNIT_ASSERT_EQUAL(string("coucoucoucoucoucoucoucou"), string(text)); + delete p; + } +} + +void YacsLoaderTest::fschema() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/fschema.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { + PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); + char *text = PyString_AsString(data);; + CPPUNIT_ASSERT_EQUAL(string("coucoucoucoucoucoucoucou"), string(text) ); + delete p; + } +} + +void YacsLoaderTest::oschema() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/oschema.xml"); + CPPUNIT_ASSERT(ret == 1); +} + +void YacsLoaderTest::pschema() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/pschema.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { + { + CORBA::Double dval = 0; + *((OutputCorbaPort*)p->nodeMap["node61"]->getOutputPort("p1"))->getAny() >>= dval; + CPPUNIT_ASSERT_DOUBLES_EQUAL(25., dval, 1.E-12); + } + { + CORBA::Double dval = 0; + *((OutputCorbaPort*)p->nodeMap["node62"]->getOutputPort("p1"))->getAny() >>= dval; + CPPUNIT_ASSERT_DOUBLES_EQUAL(25., dval, 1.E-12); + } + { + CORBA::Double dval = 0; + *((OutputCorbaPort*)p->nodeMap["node63"]->getOutputPort("p1"))->getAny() >>= dval; + CPPUNIT_ASSERT_DOUBLES_EQUAL(25., dval, 1.E-12); + } + delete p; + } +} + +void YacsLoaderTest::schema() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/schema.xml"); + CPPUNIT_ASSERT(ret == 1); +} + +void YacsLoaderTest::schema2() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/schema2.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { + { + CORBA::Double dval = 0; + *((OutputCorbaPort*)p->nodeMap["node61"]->getOutputPort("p1"))->getAny() >>= dval; + CPPUNIT_ASSERT_DOUBLES_EQUAL(25., dval, 1.E-12); + } + { + CORBA::Double dval = 0; + *((OutputCorbaPort*)p->nodeMap["node62"]->getOutputPort("p1"))->getAny() >>= dval; + CPPUNIT_ASSERT_DOUBLES_EQUAL(25., dval, 1.E-12); + } + { + CORBA::Double dval = 0; + *((OutputCorbaPort*)p->nodeMap["node63"]->getOutputPort("p1"))->getAny() >>= dval; + CPPUNIT_ASSERT_DOUBLES_EQUAL(25., dval, 1.E-12); + } + delete p; + } +} + +void YacsLoaderTest::forloop1() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/forloop1.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { + PyObject *data = ((OutputPyPort*)p->nodeMap["b1.node2"]->getOutputPort("p1"))->get(); + double val = PyFloat_AsDouble(data);; + CPPUNIT_ASSERT_DOUBLES_EQUAL(33., val, 1.E-12); + delete p; + } +} + +void YacsLoaderTest::forloop2() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/forloop2.xml"); + CPPUNIT_ASSERT(ret == 0); +} + +///////////////////////////// + +void YacsLoaderTest::forloop3() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/forloop3.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::forloop4() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/forloop4.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::forloop5() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/forloop5.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::forloop6() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/forloop6.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + + +void YacsLoaderTest::forloop7() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/forloop7.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::switch1() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/switch1.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::switch2() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/switch2.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::switch3() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/switch3.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::switch4() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/switch4.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::switch5() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/switch5.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::switch6() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/switch6.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::switch7() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/switch7.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::switch8() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/switch8.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::switch9() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/switch9.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::whiles() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/while1.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } + ret = driverTest(p, "samples/while2.xml"); + CPPUNIT_ASSERT(ret == 0); + ret = driverTest(p, "samples/while3.xml"); + CPPUNIT_ASSERT(ret == 0); +} + +void YacsLoaderTest::forwhile1() +{ + Proc *p = 0; + int ret = driverTest(p, "samples/forwhile1.xml"); + CPPUNIT_ASSERT(ret == 0); + DEBTRACE("Proc *p = " << p); + CPPUNIT_ASSERT(p != 0); + if (p) + { +// PyObject *data = ((OutputPyPort*)p->nodeMap["node2"]->getOutputPort("p1"))->get(); +// char *text = PyString_AsString(data);; +// CPPUNIT_ASSERT_EQUAL(string(text), string("coucoucoucoucoucoucoucou")); + delete p; + } +} + +void YacsLoaderTest::blocs() +{ + Proc *p = 0; + int ret; + ret = driverTest(p, "samples/bloc1.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); + ret = driverTest(p, "samples/bloc2.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); + ret = driverTest(p, "samples/bloc3.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() != YACS::DONE ); + ret = driverTest(p, "samples/bloc4.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); +} + +void YacsLoaderTest::refcnt() +{ + Proc *p = 0; + int ret; + PyObject *data; + ret = driverTest(p, "samples/refcnt1.xml"); + CPPUNIT_ASSERT(ret == 0); + data = ((OutputPyPort*)p->nodeMap["b1.b.node1"]->getOutputPort("p1"))->get(); + CPPUNIT_ASSERT_EQUAL(13, data->ob_refcnt); + ret = driverTest(p, "samples/refcnt2.xml"); + CPPUNIT_ASSERT(ret == 0); + data = ((OutputPyPort*)p->nodeMap["b1.b.node1"]->getOutputPort("p1"))->get(); + CPPUNIT_ASSERT_EQUAL(19, data->ob_refcnt); +} + +void YacsLoaderTest::foreachs() +{ + Proc *p = 0; + int ret; + ret = driverTest(p, "samples/foreach1.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); + ret = driverTest(p, "samples/foreach2.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); + ret = driverTest(p, "samples/foreach3.xml"); + CPPUNIT_ASSERT(ret == 1); + ret = driverTest(p, "samples/foreach4.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); + ret = driverTest(p, "samples/foreach5.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); + ret = driverTest(p, "samples/foreach6.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); +} + +void YacsLoaderTest::sinlines() +{ + Proc *p = 0; + int ret; + ret = driverTest(p, "samples/sinline1.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); + ret = driverTest(p, "samples/sinline2.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); + ret = driverTest(p, "samples/sinline3.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); + ret = driverTest(p, "samples/sinline4.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); + ret = driverTest(p, "samples/sinline5.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); +} + +void YacsLoaderTest::bools() +{ + Proc *p = 0; + int ret; + ret = driverTest(p, "samples/bool1.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); +} +void YacsLoaderTest::integers() +{ + Proc *p = 0; + int ret; + ret = driverTest(p, "samples/integer1.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); +} +void YacsLoaderTest::doubles() +{ + Proc *p = 0; + int ret; + ret = driverTest(p, "samples/double1.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); +} +void YacsLoaderTest::strings() +{ + Proc *p = 0; + int ret; + ret = driverTest(p, "samples/string1.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); +} +void YacsLoaderTest::objrefs() +{ + Proc *p = 0; + int ret; + ret = driverTest(p, "samples/objref1.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); +} +void YacsLoaderTest::structs() +{ + Proc *p = 0; + int ret; + ret = driverTest(p, "samples/struct1.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); +} + +void YacsLoaderTest::cpps() +{ + Proc *p = 0; + int ret; + ret = driverTest(p, "samples/cpp1.xml"); + CPPUNIT_ASSERT(ret == 0); + CPPUNIT_ASSERT(p->getEffectiveState() == YACS::DONE ); + delete p; +} diff --git a/src/yacsloader/Test/YacsLoaderTest.hxx b/src/yacsloader/Test/YacsLoaderTest.hxx new file mode 100644 index 000000000..61dbfdee4 --- /dev/null +++ b/src/yacsloader/Test/YacsLoaderTest.hxx @@ -0,0 +1,108 @@ + +#ifndef _YACSLOADERTEST_HXX_ +#define _YACSLOADERTEST_HXX_ + +#include +#include +#include + +namespace YACS +{ + class YacsLoaderTest: public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( YacsLoaderTest ); + CPPUNIT_TEST(aschema); + CPPUNIT_TEST(bschema); + CPPUNIT_TEST(cschema); + CPPUNIT_TEST(dschema); + CPPUNIT_TEST(eschema); + CPPUNIT_TEST(fschema); + CPPUNIT_TEST(oschema); + CPPUNIT_TEST(pschema); + CPPUNIT_TEST(schema); + CPPUNIT_TEST(schema2); + CPPUNIT_TEST(forloop1); + CPPUNIT_TEST(forloop2); + CPPUNIT_TEST(forloop3); + CPPUNIT_TEST(forloop4); + CPPUNIT_TEST(forloop5); + CPPUNIT_TEST(forloop6); + CPPUNIT_TEST(forloop7); + CPPUNIT_TEST(switch1); + CPPUNIT_TEST(switch2); + CPPUNIT_TEST(switch3); + CPPUNIT_TEST(switch4); + CPPUNIT_TEST(switch5); + CPPUNIT_TEST(switch6); + CPPUNIT_TEST(switch7); + CPPUNIT_TEST(switch8); + CPPUNIT_TEST(switch9); + CPPUNIT_TEST(whiles); + CPPUNIT_TEST(forwhile1); + CPPUNIT_TEST(blocs); + CPPUNIT_TEST(refcnt); + CPPUNIT_TEST(foreachs); + CPPUNIT_TEST(sinlines); + CPPUNIT_TEST(bools); + CPPUNIT_TEST(integers); + CPPUNIT_TEST(doubles); + CPPUNIT_TEST(strings); + CPPUNIT_TEST(objrefs); + CPPUNIT_TEST(structs); + CPPUNIT_TEST(cpps); + CPPUNIT_TEST_SUITE_END(); + + public: + + void setUp(); + void tearDown(); + + void aschema(); + void bschema(); + void cschema(); + void dschema(); + void eschema(); + void fschema(); + void oschema(); + void pschema(); + void schema(); + void schema2(); + void forloop1(); + void forloop2(); + void forloop3(); + void forloop4(); + void forloop5(); + void forloop6(); + void forloop7(); + void switch1(); + void switch2(); + void switch3(); + void switch4(); + void switch5(); + void switch6(); + void switch7(); + void switch8(); + void switch9(); + void whiles(); + void forwhile1(); + void blocs(); + void refcnt(); + void foreachs(); + void sinlines(); + void bools(); + void integers(); + void doubles(); + void strings(); + void objrefs(); + void structs(); + void cpps(); + + protected: + + private: + + }; + +} + +#endif diff --git a/src/yacsloader/Test/YacsLoaderTest.sh.in b/src/yacsloader/Test/YacsLoaderTest.sh.in new file mode 100755 index 000000000..c3f73149e --- /dev/null +++ b/src/yacsloader/Test/YacsLoaderTest.sh.in @@ -0,0 +1,74 @@ +#!/bin/bash + +if test -f @KERNEL_ROOT_DIR@/bin/salome/appli_gen.py ; then + + # --- create a SALOME Application environment + + @KERNEL_ROOT_DIR@/bin/salome/appli_gen.py + sed -i s/\"yes\"/\"no\"/ SalomeApp.xml + sed -i s/\,study\,cppContainer\,registry\,moduleCatalog// SalomeApp.xml + sed -i s/pyContainer/pyContainer\,study\,cppContainer\,registry\,moduleCatalog/ SalomeApp.xml + +cat > CatalogResources.xml << EOF + + + + +EOF + + # --------------------------------------------------------------------------- + # --- first set of test in C++ + + # --- launch in background a SALOME session (servers) + + ln -fs @top_srcdir@/src/yacsloader/samples . + ./runAppli > log1 2>&1 + + # --- wait a little to let the background process define + # the CORBA naming service port and host + + sleep 5 + + # --- execute the test script in SALOME session environment + + chmod +x @builddir@/YacsLoaderInSessionTest.sh + ./runSession @builddir@/YacsLoaderInSessionTest.sh + ret1=$? + + # --------------------------------------------------------------------------- + # --- second set of tests: Python scripts + + chmod +x @builddir@/YacsLoaderInSessionTest2.sh + ./runSession @builddir@/YacsLoaderInSessionTest2.sh + ret2=$? + + # --------------------------------------------------------------------------- + + kill -9 `cat "/tmp/YACSTEST_PidEcho"` + ./runSession killSalome.py + + echo "exec status YacsLoaderInSessionTest.sh " $ret1 + echo "exec status YacsLoaderInSessionTest2.sh " $ret2 + let ret=$ret1+$ret2 + + # --- delete all the SALOME Application environment + + ./bin/salome/appli_clean.sh + +else + + ln -fs @top_srcdir@/src/yacsloader/samples . + chmod +x @builddir@/YacsLoaderInSessionTest.sh + @builddir@/YacsLoaderInSessionTest.sh + ret=$? + echo "exec status YacsLoaderInSessionTest.sh " $ret + +fi + +if [ $ret -ne 0 ] +then cat /tmp/${USER}/UnitTestsResult +else echo "Results are in /tmp/${USER}/UnitTestsResult" +fi + +exit $ret diff --git a/src/yacsloader/Test/config_appli.xml.in b/src/yacsloader/Test/config_appli.xml.in new file mode 100644 index 000000000..16d3c601a --- /dev/null +++ b/src/yacsloader/Test/config_appli.xml.in @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/yacsloader/Test/display.sh.in b/src/yacsloader/Test/display.sh.in new file mode 100755 index 000000000..8a1ec8290 --- /dev/null +++ b/src/yacsloader/Test/display.sh.in @@ -0,0 +1,12 @@ +#!/bin/sh + +sleep 2 + +if [ -f killdisplay.sh ] ; then + sh killdisplay.sh +fi + +dot -Tpng titi >tutu.png +display tutu.png & +pidisplay=$! +echo "kill -9 " $pidisplay > killdisplay.sh diff --git a/src/yacsloader/Test/echo.idl b/src/yacsloader/Test/echo.idl new file mode 100644 index 000000000..e3c642009 --- /dev/null +++ b/src/yacsloader/Test/echo.idl @@ -0,0 +1,90 @@ +#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 BoolVec; + 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 ; + struct S1 + { + double x; + long y; + string s; + boolean b; + DoubleVec vd; + }; + struct S2 + { + S1 s; + }; + + interface Echo + { + string echoString(in string mesg); + boolean echoBoolean(in boolean b); + 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 echoBoolVec(in BoolVec i,out BoolVec j) ; + void echoObj2(in Obj i,out Obj j) ; + void echoD(in D i,out D j) ; + void echoC(in C i,out C 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); + void sleepLong(in double time1,out double time2) ; + S2 echoStruct(in S2 s); + }; + interface SubEcho:Echo + { + }; +}; + +#endif diff --git a/src/yacsloader/Test/echoSrv.cxx b/src/yacsloader/Test/echoSrv.cxx new file mode 100644 index 000000000..c8e270cb0 --- /dev/null +++ b/src/yacsloader/Test/echoSrv.cxx @@ -0,0 +1,497 @@ +#include +#include +#include + +#include + +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; + +static CORBA::Boolean bindObjectToName(CORBA::ORB_ptr, CORBA::Object_ptr,const char*); + +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 echoLong(CORBA::Long 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); + virtual CORBA::Boolean echoBoolean(CORBA::Boolean b); + 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 echoBoolVec(const eo::BoolVec&, eo::BoolVec_out); + void echoObjectVec(const eo::ObjectVec&, eo::ObjectVec_out); + void echoObj2(eo::Obj_ptr , eo::Obj_out); + void echoD(eo::D_ptr , eo::D_out); + void echoC(eo::C_ptr , eo::C_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); + void sleepLong(CORBA::Double time1,CORBA::Double& time2) ; + virtual eo::S2* echoStruct(const eo::S2&); + virtual PortableServer::POA_ptr _default_POA(); +protected: + int _ctr; + pthread_mutex_t _mutex; +}; + +//Implementation Echo +PortableServer::POA_ptr Echo_i::_default_POA() +{ + _ctr =0; + pthread_mutex_init(&_mutex, NULL); + 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) +{ + DEBTRACE("Echo_i::echoString " << mesg); + return CORBA::string_dup(mesg); +} + +CORBA::Boolean Echo_i::echoBoolean(CORBA::Boolean b ) +{ + DEBTRACE("Echo_i::echoBoolean " << b); + return b; +} + +void Echo_i::echoDouble(CORBA::Double i,CORBA::Double& j ) { + DEBTRACE("Echo_i::echoDouble " << i); + j=i+1; +} + +void Echo_i::echoIntVec(const eo::IntVec& in, eo::IntVec_out out) +{ + DEBTRACE("Echo_i::echoIntVec " << in.length()); + for(int i=0;i_PD_repoId); + }; + out=new eo::ObjectVec(in); +} + +void Echo_i::echoObjectVecVec(const eo::ObjectVecVec& in, eo::ObjectVecVec_out out) +{ + DEBTRACE("Echo_i::echoObjectVecVec " << in.length()); + for(int i=0;i< in.length(); i++){ + for(int j=0;j< in[i].length(); j++){ + DEBTRACE(in[i][j]->_PD_repoId); + }; + }; + out=new eo::ObjectVecVec(in); +} + +void Echo_i::echoDoubleVec(const eo::DoubleVec& in,eo::DoubleVec_out out ) +{ + DEBTRACE("Echo_i::echoDoubleVec " << in.length()); + for(int i=0;iechoLong(10); + oo=eo::C::_duplicate(o); +} + +void Echo_i::echoD(eo::D_ptr o,eo::D_out oo){ + DEBTRACE("Echo_i::echoD "); + o->echoLong2(10); + //oo=eo::D::_duplicate(o); + D_i* myD = new D_i(); + oo=myD->_this(); + myD->_remove_ref(); +} + +void Echo_i::echoObj2(eo::Obj_ptr o,eo::Obj_out oo){ + DEBTRACE("Echo_i::echoObj2 "); + o->echoLong(10); + oo=eo::Obj::_duplicate(o); +} + +eo::Obj_ptr Echo_i::echoObj(CORBA::Long i ,eo::Obj_ptr o,CORBA::Long j,eo::Obj_out oo){ + DEBTRACE("Echo_i::echoObj " << i << "," << j ); + oo=eo::Obj::_duplicate(o); + return eo::Obj::_duplicate(o); +} + +void Echo_i::createObj(CORBA::Long i ,eo::Obj_out oo){ + DEBTRACE("Echo_i::createObj " << i); + Obj_i* myobj = new Obj_i(); + CORBA::Object_var myref = myobj->_this(); + oo = eo::Obj::_narrow(myref); + myobj->_remove_ref(); +} + +void Echo_i::createC(eo::C_out oo){ + DEBTRACE("Echo_i::createC "); + 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) +{ + DEBTRACE("Echo_i::echoAll " << d << "," << l << "," << m); + dd=d; + ll=l; + s=CORBA::string_dup(m); + oo=eo::Obj::_duplicate(o); +}; + +void Echo_i::sleepLong(CORBA::Double time1, CORBA::Double& time2) +{ + DEBTRACE("Echo_i::sleepLong"); + pthread_mutex_lock(&_mutex); + int num = _ctr++; + pthread_mutex_unlock(&_mutex); + DEBTRACE("Echo_i::sleepLong start " << num); + unsigned int t=(unsigned int) time1; + sleep(t); + DEBTRACE("Echo_i::sleepLong stop " << num); + time2 = time1; +} +eo::S2* Echo_i::echoStruct(const eo::S2& s) +{ + DEBTRACE("Echo_i::echoStruct " << s.s.x << " " << s.s.y); + eo::S1 s1; + s1.x=10.; + s1.y=2; + eo::S2* s2=new eo::S2; + s2->s=s1; + return s2; +} + +//Implementation Obj +CORBA::Long Obj_i::echoLong(CORBA::Long i ){ + DEBTRACE("Obj_i::echoLong " << i ); + CORBA::Long j=i+1; + return j; +} + +//Implementation C +CORBA::Long C_i::echoLong(CORBA::Long i ){ + DEBTRACE("C_i::echoLong " << i); + CORBA::Long j=i+5; + return j; +} + +//Implementation D +CORBA::Long D_i::echoLong2(CORBA::Long i ){ + DEBTRACE("D_i::echoLong " << i); + CORBA::Long j=i+10; + return j; +} +CORBA::Long D_i::echoLong(CORBA::Long i ){ + DEBTRACE("D_i::echoLong " << i); + CORBA::Long j=i+1; + return j; +} + +//Implementation E +CORBA::Long E_i::echoLong2(CORBA::Long i ){ + DEBTRACE("E_i::echoLong " << i); + CORBA::Long j=i+20; + return j; +} +CORBA::Long E_i::echoLong(CORBA::Long i ){ + DEBTRACE("E_i::echoLong " << i); + 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)); + DEBTRACE("'" << (char*)sior << "'"); + myechoref = eo::Echo::_narrow(obj); + + if( !bindObjectToName(orb, myechoref,"Echo") ) 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(); + + //create object C and register it in naming service + C_i* myC = new C_i(); + obj=myC->_this(); + eo::C_var myCref=eo::C::_narrow(obj); + myC->_remove_ref(); + if( !bindObjectToName(orb, myCref,"C") ) return 1; + + //create object D and register it in naming service + D_i* myD = new D_i(); + obj=myD->_this(); + eo::D_var myDref=eo::D::_narrow(obj); + myD->_remove_ref(); + if( !bindObjectToName(orb, myDref,"D") ) return 1; + + //create object Obj and register it in naming service + Obj_i* myObj = new Obj_i(); + obj=myObj->_this(); + eo::Obj_var myObjref=eo::Obj::_narrow(obj); + myObj->_remove_ref(); + if( !bindObjectToName(orb, myObjref,"Obj") ) return 1; + } + orb->run(); + } + catch(CORBA::SystemException&) { + DEBTRACE("Caught CORBA::SystemException."); + } + catch(CORBA::Exception& ex) { + DEBTRACE("Caught CORBA::Exception." << ex); + } + catch(omniORB::fatalException& fe) { + DEBTRACE("Caught omniORB::fatalException:"); + DEBTRACE(" file: " << fe.file()); + DEBTRACE(" line: " << fe.line()); + DEBTRACE(" mesg: " << fe.errmsg()); + } + catch(...) { + DEBTRACE("Caught unknown exception." ); + } + + return 0; +} + + +////////////////////////////////////////////////////////////////////// + +static CORBA::Boolean +bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref,const char *name) +{ + 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) ) { + DEBTRACE("Failed to narrow the root naming context."); + return 0; + } + } + catch(CORBA::ORB::InvalidName& ex) { + // This should not happen! + DEBTRACE("Service required is invalid [does not exist]." ); + 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) ) { + DEBTRACE("Failed to narrow naming context."); + return 0; + } + } + + // Bind objref with name Echo to the testContext: + CosNaming::Name objectName; + objectName.length(1); + objectName[0].id = name; // 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) { + DEBTRACE("Caught system exception COMM_FAILURE -- unable to contact the " + << "naming service."); + return 0; + } + catch(CORBA::SystemException&) { + DEBTRACE("Caught a CORBA::SystemException while using the naming service."); + return 0; + } + + return 1; +} + diff --git a/src/yacsloader/Test/genPascal.py b/src/yacsloader/Test/genPascal.py new file mode 100644 index 000000000..8ee54b97c --- /dev/null +++ b/src/yacsloader/Test/genPascal.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python + +def triangle(n): + """generate a YACS graph for computation of the Pascal triangle + + parameter: rank of the triangle. + Use module decimal for an exact calculation with big numbers. + The last node gives the sum of rank n (=2**n) and also a direct calculation of 2**n. + """ + + print """ + + + + + + + + + +""" + + print """ + +" + for i in range (n+1): + inport='' + print inport + pass + print '' + print '' + print "" + print + + for i in range (1,n+1): + for j in range (i+1): + node="node_" + str(i) +"_" + str(j) + nodetxt='' + print nodetxt + pass + pass + + print """ + + + + + """ + + for i in range (n): + for j in range (i+1): + fromnode="node_" + str(i) +"_" + str(j) + tonode1="node_" + str(i+1) +"_" + str(j) + tonode2="node_" + str(i+1) +"_" + str(j+1) + control1=' '+fromnode+' '+tonode1+' ' + control2=' '+fromnode+' '+tonode2+' ' + print control1 + print control2 + pass + pass + for i in range (n+1): + fromnode="node_" + str(n) +"_" + str(i) + control=' '+fromnode+' collect ' + print control + pass + + print """ + + + + """ + + for i in range (n): + for j in range (i+1): + fromnode="node_" + str(i) +"_" + str(j) + tonode1="node_" + str(i+1) +"_" + str(j) + tonode2="node_" + str(i+1) +"_" + str(j+1) + datafrom='' + fromnode + ' c' + datato1 ='' + tonode1 + ' b' + datato2 ='' + tonode2 + ' a' + print '' + print ' ' + datafrom + print ' ' + datato1 + print '' + print '' + print ' ' + datafrom + print ' ' + datato2 + print '' + pass + pass + for i in range (n+1): + fromnode="node_" + str(n) +"_" + str(i) + datafrom='' + fromnode + ' c' + toport='a' + str(i) + datato ='collect ' + toport + '' + print '' + print ' ' + datafrom + print ' ' + datato + print '' + + + print """ + + + + """ + + print """ + + node_0_0 a + 0 + + + node_0_0 b + 1 + + """ + + for i in range (1,n+1): + node1="node_" + str(i) +"_" + str(0) + node2="node_" + str(i) +"_" + str(i) + tonode1 =' ' + node1 + ' a' + tonode2 =' ' + node2 + ' b' + print '' + print tonode1 + print ' 0' + print '' + + print '' + print tonode2 + print ' 0' + print '' + + print """ + + + """ + +if __name__ == "__main__": + import sys + usage ="""Usage: %s rank > file.xml + where rank is positive integer > 2 + """ + try: + rank = int(sys.argv[1]) + if rank <2: + raise ValueError("rank must be >1") + except (IndexError, ValueError): + print usage%(sys.argv[0]) + sys.exit(1) + pass + triangle(rank) + pass diff --git a/src/yacsloader/Test/genTriangle.py b/src/yacsloader/Test/genTriangle.py new file mode 100644 index 000000000..18bec8252 --- /dev/null +++ b/src/yacsloader/Test/genTriangle.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python + +debut=""" + + + + + + + + + + + + +""" + + +def triangle(n): + """generate a YACS graph for computation of the Pascal triangle + + parameter: rank of the triangle. + Use integers, so rank is limited to 31 (2**31) + The last node gives the sum of rank n (=2**n) and also a direct calculation of 2**n. + """ + + print debut + + print """ + +" + for i in range (n+1): + inport='' + print inport + pass + print '' + print '' + print "" + print + + for i in range (1,n+1): + for j in range (i+1): + node="node_" + str(i) +"_" + str(j) + nodetxt='' + print nodetxt + pass + pass + + print """ + + + + + """ + + for i in range (n): + for j in range (i+1): + fromnode="node_" + str(i) +"_" + str(j) + tonode1="node_" + str(i+1) +"_" + str(j) + tonode2="node_" + str(i+1) +"_" + str(j+1) + control1=' '+fromnode+' '+tonode1+' ' + control2=' '+fromnode+' '+tonode2+' ' + print control1 + print control2 + pass + pass + + print """ + + + + """ + + for i in range (n): + for j in range (i+1): + fromnode="node_" + str(i) +"_" + str(j) + tonode1="node_" + str(i+1) +"_" + str(j) + tonode2="node_" + str(i+1) +"_" + str(j+1) + datafrom='' + fromnode + ' c' + datato1 ='' + tonode1 + ' b' + datato2 ='' + tonode2 + ' a' + print '' + print ' ' + datafrom + print ' ' + datato1 + print '' + print '' + print ' ' + datafrom + print ' ' + datato2 + print '' + pass + pass + + for i in range (n+1): + fromnode="node_" + str(n) +"_" + str(i) + datafrom='' + fromnode + ' c' + toport='a' + str(i) + datato ='collect ' + toport + '' + print '' + print ' ' + datafrom + print ' ' + datato + print '' + + print """ + + + + """ + + print """ + + node_0_0 a + 0 + + + node_0_0 b + 1 + + """ + + for i in range (1,n+1): + node1="node_" + str(i) +"_" + str(0) + node2="node_" + str(i) +"_" + str(i) + tonode1 =' ' + node1 + ' a' + tonode2 =' ' + node2 + ' b' + print '' + print tonode1 + print ' 0' + print '' + + print '' + print tonode2 + print ' 0' + print '' + + print """ + + + """ + +if __name__ == "__main__": + import sys + usage ="""Usage: %s rank > file.xml + where rank is positive integer >2 and <32 + """ + try: + rank = int(sys.argv[1]) + if rank <2: + raise ValueError("rank must be >1") + if rank >31: + raise ValueError("rank must be <32") + except (IndexError, ValueError): + print usage%(sys.argv[0]) + sys.exit(1) + pass + triangle(rank) + pass diff --git a/src/yacsloader/Test/testEdit.py b/src/yacsloader/Test/testEdit.py new file mode 100644 index 000000000..6d61edcb6 --- /dev/null +++ b/src/yacsloader/Test/testEdit.py @@ -0,0 +1,186 @@ + +import sys +import pilot +import SALOMERuntime +import loader +import unittest + +class TestEdit(unittest.TestCase): + + def setUp(self): + SALOMERuntime.RuntimeSALOME_setRuntime() + self.r = pilot.getRuntime() + self.l = loader.YACSLoader() + self.e = pilot.ExecutorSwig() + pass + + def test1_edit(self): + p = self.r.createProc("pr") + print p.typeMap + t=p.getTypeCode("double") + print t.kind() + t=p.typeMap["double"] + + td=p.createType("double","double") + ti=p.createType("int","int") + tc1=p.createInterfaceTc("","Obj",[]) + print tc1.name(),tc1.id() + tc2=p.createInterfaceTc("","Obj2",[tc1]) + print tc2.name(),tc2.id() + tc3=p.createSequenceTc("","seqdbl",td) + print tc3.name(),tc3.id(),tc3.contentType() + tc4=p.createSequenceTc("","seqObj2",tc2) + tc5=p.createSequenceTc("","seqint",ti) + print tc4.name(),tc4.id() + print tc4.isA(tc1),0 + print tc2.isA(tc1),1 + print tc1.isA(tc2),0 + print td.isA(ti),0 + print td.isAdaptable(ti),1 + print ti.isAdaptable(td),0 + print tc5.isAdaptable(tc3),0 + print tc3.isAdaptable(tc5),1 + + n=self.r.createScriptNode("","node1") + n.setScript("print 'coucou1'") + n.edAddInputPort("p1",ti) + n.edAddOutputPort("p1",ti) + p.edAddChild(n) + inport=n.getInputPort("p1"); + retex=None + try: + inport.edInit("XML","5") + except ValueError, ex: + print "Value Error: ", ex + retex=ex + except pilot.Exception,ex: + print "YACS exception:",ex.what() + retex=ex.what() + self.assert_(retex is not None, "exception not raised, or wrong type") + inport.edInit("XML","5") + + # --- create script node node2 + n2=self.r.createScriptNode("","node2") + n2.setScript("print 'coucou2'") + n2.edAddInputPort("p1",ti) + p.edAddChild(n2) + # --- end of node + + # --- control link between nodes n and n2 + p.edAddCFLink(n,n2) + # --- end control link + + # --- datalink between ports p1 of nodes n1 and n2 + p.edAddLink(n.getOutputPort("p1"),n2.getInputPort("p1")) + # --- end datalink + + n=self.r.createFuncNode("","node3") + n.setScript(""" + def f(): + print 'coucou3' + """) + n.setFname("f") + p.edAddChild(n) + + n4=self.r.createRefNode("","node4") + n4.setRef("corbaname:rir:#test.my_context/Echo.Object") + n4.setMethod("echoDouble") + n4.edAddInputDataStreamPort("pin",ti) + n4.edAddOutputDataStreamPort("pout",ti) + p.edAddChild(n4) + + n5=self.r.createRefNode("","node5") + n5.setRef("corbaname:rir:#test.my_context/Echo.Object") + n5.setMethod("echoDouble") + n5.edAddInputDataStreamPort("pin",ti) + n5.edAddOutputDataStreamPort("pout",ti) + p.edAddChild(n5) + + p.edAddLink(n4.getOutputDataStreamPort("pout"),n5.getInputDataStreamPort("pin")) + + #n=self.r.createCompoNode("","node5") + #n.setRef("PYHELLO") + #n.setMethod("makeBanner") + #p.edAddChild(n) + + # --- create a bloc with one node + b=self.r.createBloc("b1") + p.edAddChild(b) + + n=self.r.createScriptNode("","b1.node2") + n.setScript("print 'coucou2'") + b.edAddChild(n) + # --- end bloc + + # --- create a for loop with one node + lo=self.r.createForLoop("l1") + p.edAddChild(lo) + ip=lo.edGetNbOfTimesInputPort() + ip.edInitInt(3) + + n=self.r.createScriptNode("","l1.node2") + n.setScript("print 'coucou2'") + lo.edSetNode(n) + # --- end loop + + # --- control link between bloc b1 and loop l1 + p.edAddCFLink(b,lo) + # --- end control link + + # --- create a while loop with one node + wh=self.r.createWhileLoop("w1") + p.edAddChild(wh) + n=self.r.createFuncNode("","w1.node3") + n.setScript(""" +def f(): + print 'coucou3' + return 0 +""") + n.setFname("f") + n.edAddOutputPort("p1",ti) + wh.edSetNode(n) + cport=wh.edGetConditionPort() + cport.edInitBool(True) + # --- end loop + p.edAddLink(n.getOutputPort("p1"),wh.getInputPort("condition")) #or cport + + # --- create a switch + sw=self.r.createSwitch("sw1") + p.edAddChild(sw) + n=self.r.createFuncNode("","sw1.node3") + n.setScript(""" +def f(): + print 'case1' + return 0 +""") + n.setFname("f") + n.edAddOutputPort("p1",ti) + sw.edSetNode(1,n) + n=self.r.createFuncNode("","sw1.node4") + n.setScript(""" +def f(): + print 'default' + return 0 +""") + n.setFname("f") + n.edAddOutputPort("p1",ti) + sw.edSetDefaultNode(n) + sw.edGetConditionPort().edInitInt(1) + # --- end switch + + try: + self.e.RunW(p,0) + except pilot.Exception,ex: + print ex.what() + self.fail(ex) + + #self.e.displayDot(p) + + +import os +U = os.getenv('USER') +f=open("/tmp/" + U + "/UnitTestsResult", 'a') +f.write(" --- TEST src/yacsloader: testEdit.py\n") +suite = unittest.makeSuite(TestEdit) +unittest.TextTestRunner(f, descriptions=1, verbosity=1).run(suite) +f.close() diff --git a/src/yacsloader/Test/testExec.py b/src/yacsloader/Test/testExec.py new file mode 100644 index 000000000..cfa36bb54 --- /dev/null +++ b/src/yacsloader/Test/testExec.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python +import time +import unittest +import threading + +import SALOMERuntime +import loader +import pilot + +class TestExec(unittest.TestCase): + + def setUp(self): + SALOMERuntime.RuntimeSALOME_setRuntime(1) + self.l = loader.YACSLoader() + self.e = pilot.ExecutorSwig() + self.p = self.l.load("samples/aschema.xml") + pass + + def test1_StepByStep(self): + # --- execution step by step + + print "================= Start of STEPBYSTEP ===================" + self.e.setExecMode(1) # YACS::STEPBYSTEP + + run1 = threading.Thread(None, self.e.RunPy, "stepbystep", (self.p,0)) + run1.start() + time.sleep(0.1) # let the thread be initialised + #e.displayDot(self.p) + + tocont = True + while tocont: + self.e.waitPause() + #e.displayDot(p) + bp = self.e.getTasksToLoad() + print "nexts possible steps = ", bp + if len(bp) > 0: + tte= bp[-1:] # only one node at each step, the last one in the list + r = self.e.setStepsToExecute(tte) + self.e.resumeCurrentBreakPoint() + tocont = self.e.isNotFinished() + else: + tocont = False + pass + print "toContinue = ", tocont + pass + + self.e.resumeCurrentBreakPoint() + run1.join() + self.assertEqual(106, self.p.getChildByName('node48').getEffectiveState()) + self.assertEqual(999, self.p.getChildByName('node13').getEffectiveState()) + self.assertEqual(888, self.p.getChildByName('node14').getEffectiveState()) + self.assertEqual(777, self.p.getChildByName('c1').getEffectiveState()) + self.assertEqual(777, self.p.getChildByName('c1.c1.n2').getEffectiveState()) + self.assertEqual(106, self.p.getChildByName('c0.c1.n1').getEffectiveState()) + self.assertEqual(999, self.p.getChildByName('c0.n2').getEffectiveState()) + self.assertEqual(888, self.p.getChildByName('node62').getEffectiveState()) + print "================= End of STEPBYSTEP =====================" + pass + + def test2_StopToBreakpoint(self): + # --- start execution, set a breakpoint before node48, then continue + time.sleep(1) + print "================= Start of BREAKPOINT ===================" + brp=['node48'] + self.e.setListOfBreakPoints(brp) + self.e.setExecMode(2) # YACS::STOPBEFORENODES + self.run2 = threading.Thread(None, self.e.RunPy, "breakpoint", (self.p,0)) + self.run2.start() + time.sleep(0.1) + self.e.waitPause() + #self.e.displayDot(p) + print "================= reach BREAKPOINT ======================" + # --- resume from breakpoint + print "=========== BREAKPOINT, start RESUME ====================" + time.sleep(1) + self.e.setExecMode(0) # YACS::CONTINUE + self.e.resumeCurrentBreakPoint() + time.sleep(0.1) + self.e.waitPause() + #self.e.displayDot(p) + self.run2.join() + self.assertEqual(106, self.p.getChildByName('node48').getEffectiveState()) + self.assertEqual(999, self.p.getChildByName('node13').getEffectiveState()) + self.assertEqual(888, self.p.getChildByName('node14').getEffectiveState()) + self.assertEqual(777, self.p.getChildByName('c1').getEffectiveState()) + self.assertEqual(777, self.p.getChildByName('c1.c1.n2').getEffectiveState()) + self.assertEqual(106, self.p.getChildByName('c0.c1.n1').getEffectiveState()) + self.assertEqual(999, self.p.getChildByName('c0.n2').getEffectiveState()) + self.assertEqual(888, self.p.getChildByName('node62').getEffectiveState()) + print "================= End of RESUME =========================" + pass + + def test3_RunWithoutBreakpoints(self): + # --- start execution, run without breakpoints + time.sleep(1) + + print "================= Start of CONTINUE =====================" + self.e.setExecMode(0) # YACS::CONTINUE + run3 = threading.Thread(None, self.e.RunPy, "continue", (self.p,0)) + run3.start() + time.sleep(0.1) + self.e.waitPause() + #self.e.displayDot(p) + run3.join() + self.assertEqual(106, self.p.getChildByName('node48').getEffectiveState()) + self.assertEqual(999, self.p.getChildByName('node13').getEffectiveState()) + self.assertEqual(888, self.p.getChildByName('node14').getEffectiveState()) + self.assertEqual(777, self.p.getChildByName('c1').getEffectiveState()) + self.assertEqual(777, self.p.getChildByName('c1.c1.n2').getEffectiveState()) + self.assertEqual(106, self.p.getChildByName('c0.c1.n1').getEffectiveState()) + self.assertEqual(999, self.p.getChildByName('c0.n2').getEffectiveState()) + self.assertEqual(888, self.p.getChildByName('node62').getEffectiveState()) + print "================= End of CONTINUE =======================" + pass + + def test4_StopOnError(self): + # --- stop execution on first error and save state + time.sleep(1) + + print "================= Start of STOPONERROR ==================" + self.e.setStopOnError() + run4 = threading.Thread(None, self.e.RunPy, "continue", (self.p,0)) + run4.start() + time.sleep(0.1) + self.e.waitPause() + self.e.saveState("dumpErrorASchema.xml") + self.e.stopExecution() + run4.join() + #self.e.displayDot(self.p) + s13 = self.p.getChildByName('node13').getEffectiveState() + s43 = self.p.getChildByName('node43').getEffectiveState() + self.assert_((s13==999) or (s43==999)) + print "================= End of STOPONERROR =====================" + pass + + def test5_PartialExec(self): + # --- stop execution after breakpoint + time.sleep(1) + + print "================= Start of PARTIALEXEC ===================" + brp=['node35'] + self.e.setListOfBreakPoints(brp) + self.e.setExecMode(2) # YACS::STOPBEFORENODES + #self.e.displayDot(self.p) + run5 = threading.Thread(None, self.e.RunPy, "breakpoint", (self.p,0)) + run5.start() + time.sleep(0.1) + self.e.waitPause() + #self.e.displayDot(self.p) + self.e.saveState('dumpPartialASchema.xml') + #self.e.displayDot(self.p) + self.e.stopExecution() + run5.join() + #self.e.displayDot(self.p) + self.assertEqual(106, self.p.getChildByName('node34').getEffectiveState()) + self.assertEqual(101, self.p.getChildByName('node35').getEffectiveState()) + print "================= reach BREAKPOINT PARTIAL EXEC ==========" + pass + + pass + +import os +U = os.getenv('USER') +f=open("/tmp/" + U + "/UnitTestsResult", 'a') +f.write(" --- TEST src/yacsloader: testExec.py\n") +suite = unittest.makeSuite(TestExec) +unittest.TextTestRunner(f, descriptions=1, verbosity=1).run(suite) +f.close() diff --git a/src/yacsloader/Test/testLoader.py b/src/yacsloader/Test/testLoader.py new file mode 100644 index 000000000..d091e7ff3 --- /dev/null +++ b/src/yacsloader/Test/testLoader.py @@ -0,0 +1,67 @@ + +import pilot +import SALOMERuntime +import loader +import unittest + +class TestLoader(unittest.TestCase): + + def setUp(self): + SALOMERuntime.RuntimeSALOME_setRuntime() + self.r = pilot.getRuntime() + self.l = loader.YACSLoader() + self.e = pilot.ExecutorSwig() + pass + + def test1_FileNotExist(self): + # --- File does not exist + retex=None + try: + p = self.l.load("nonexisting") + except IOError, ex: + print "IO Error: ", ex + retex=ex + #except pilot.invalid_argument,ex: + # print "invalid_argument:",ex.what() + # retex=ex.what() + self.assert_(retex is not None, "exception not raised, or wrong type") + pass + + def test2_parseError(self): + # --- File exists but parse error + retex=None + try: + p = self.l.load("samples/bid.xml") + except ValueError,ex: + print "Caught ValueError Exception:",ex + retex = ex + self.assert_(retex is not None, "exception not raised, or wrong type") + pass + + def test3_normal(self): + # --- File exists and no parsing problem + try: + p = self.l.load("samples/aschema.xml") + print p + print p.getName() + for k in p.typeMap: print k + for k in p.nodeMap: print k + for k in p.names: print k + for k in p.inlineMap: print k + for k in p.serviceMap: print k + print self.e.getTasksToLoad() + self.e.RunW(p,0) + self.assertEqual(106, p.getChildByName('node48').getEffectiveState()) + except pilot.Exception,ex: + print "YACS exception:",ex + self.fail(ex) + pass + pass + +import os +U = os.getenv('USER') +f=open("/tmp/" + U + "/UnitTestsResult", 'a') +f.write(" --- TEST src/yacsloader: testLoader.py\n") +suite = unittest.makeSuite(TestLoader) +unittest.TextTestRunner(f, descriptions=1, verbosity=1).run(suite) +f.close() diff --git a/src/yacsloader/Test/testResume.py b/src/yacsloader/Test/testResume.py new file mode 100644 index 000000000..bc8beeba3 --- /dev/null +++ b/src/yacsloader/Test/testResume.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +import time +import unittest +import threading + +import SALOMERuntime +import loader +import pilot + +class TestResume(unittest.TestCase): + + def setUp(self): + SALOMERuntime.RuntimeSALOME_setRuntime(1) + self.l = loader.YACSLoader() + self.e = pilot.ExecutorSwig() + self.p = self.l.load("samples/bloc2.xml") + pass + + def test1_PartialExec(self): + # --- stop execution after breakpoint + time.sleep(1) + + print "================= Start of PARTIALEXEC ===================" + brp=['b1.b2.node1'] + self.e.setListOfBreakPoints(brp) + self.e.setExecMode(2) # YACS::STOPBEFORENODES + #self.e.displayDot(self.p) + run1 = threading.Thread(None, self.e.RunPy, "breakpoint", (self.p,0)) + run1.start() + time.sleep(0.1) + self.e.waitPause() + #self.e.displayDot(self.p) + self.e.saveState('dumpPartialBloc2.xml') + #self.e.displayDot(self.p) + self.e.stopExecution() + #self.e.displayDot(self.p) + self.assertEqual(101, self.p.getChildByName('b1.b2.node1').getEffectiveState()) + self.assertEqual(106, self.p.getChildByName('b1.node1').getEffectiveState()) + print "================= reach BREAKPOINT PARTIAL EXEC ==========" + pass + + def test2_ExecFromLoadState(self): + # --- reload state from previous partial execution then exec + time.sleep(1) + + print "================= Start of EXECLOADEDSTATE ===============" + sp = loader.stateParser() + sl = loader.stateLoader(sp,self.p) + sl.parse('dumpPartialBloc2.xml') + #self.e.displayDot(self.p) + self.e.setExecMode(0) # YACS::CONTINUE + run2 = threading.Thread(None, self.e.RunPy, "loadState", (self.p,0,1,1)) + run2.start() + time.sleep(0.1) + self.e.waitPause() + #self.e.displayDot(self.p) + run2.join() + self.assertEqual(106, self.p.getChildByName('node1').getEffectiveState()) + self.assertEqual(106, self.p.getChildByName('node2').getEffectiveState()) + self.assertEqual(106, self.p.getChildByName('b1.node1').getEffectiveState()) + self.assertEqual(106, self.p.getChildByName('b1.node2').getEffectiveState()) + self.assertEqual(106, self.p.getChildByName('b1.b2.node1').getEffectiveState()) + self.assertEqual(106, self.p.getChildByName('b1.b2.node2').getEffectiveState()) + self.assertEqual(106, self.p.getChildByName('b1.b2.loop1.node1').getEffectiveState()) + print "================= End of EXECLOADEDSTATE =================" + + pass + +import os +U = os.getenv('USER') +f=open("/tmp/" + U + "/UnitTestsResult", 'a') +f.write(" --- TEST src/yacsloader: testResume.py\n") +suite = unittest.makeSuite(TestResume) +unittest.TextTestRunner(f, descriptions=1, verbosity=1).run(suite) +f.close() diff --git a/src/yacsloader/Test/testSave.py b/src/yacsloader/Test/testSave.py new file mode 100644 index 000000000..211dd2e3f --- /dev/null +++ b/src/yacsloader/Test/testSave.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +import time +import unittest +import threading + +import SALOMERuntime +import loader +import pilot + +class TestSave(unittest.TestCase): + + def setUp(self): + SALOMERuntime.RuntimeSALOME_setRuntime(1) + pass + + def test0_saveAndExec(self): + """Execute twice the scheme. Each time the final state is dumped + and the scheme is written. The second exeuction is done with the + saved scheme file. Final state dumps and scheme files produced must + be identical for the 2 executions. Nodes are not always written in + the same order, so the comparison is done after sort of lines... + """ + schemaList = [] + schemaList += ["aschema","bschema","cschema","dschema","eschema","fschema"] + schemaList += ["bloc1","bloc2","bloc3","bloc4"] + schemaList += ["foreach1","foreach2","foreach4","foreach5"] + schemaList += ["foreach_LongCorba","foreach_LongPython"] + schemaList += ["forloop1","forloop2","forloop3","forloop4","forloop5","forloop6","forloop7"] + schemaList += ["forwhile1"] + schemaList += ["legendre7"] + schemaList += ["switch1","switch2","switch3","switch4","switch5","switch6","switch7","switch8","switch9"] + schemaList += ["while1","while2","while3"] + r = pilot.getRuntime() + l = loader.YACSLoader() + e = pilot.ExecutorSwig() + for schema in schemaList: + fileOrig = "samples/" + schema + ".xml" + saveSchema1 = "schema1_" + schema + dumpSchema1 = "dump1_" + schema + saveSchema2 = "schema2_" + schema + dumpSchema2 = "dump2_" + schema + try: + p = l.load(fileOrig) + s = pilot.SchemaSave(p) + s.save(saveSchema1) + e.RunW(p,0) + e.saveState(dumpSchema1) + p = l.load(saveSchema1) + s = pilot.SchemaSave(p) + s.save(saveSchema2) + e.RunW(p,0) + e.saveState(dumpSchema2) + except ValueError, ex: + print "Value Error: ", ex + pb = "problem on " + fileOrig + " : ValueError" + self.fail(pb) + except pilot.Exception,ex: + print ex.what() + pb = "problem on " + fileOrig + " : " + ex.what() + self.fail(pb) + except: + pb = "unknown problem on " + fileOrig + self.fail(pb) + s1=open(saveSchema1,'r') + s2=open(saveSchema2,'r') + d1=open(dumpSchema1,'r') + d2=open(dumpSchema2,'r') + ls1 = s1.readlines().sort() + ls2 = s2.readlines().sort() + ld1 = d1.readlines().sort() + ld2 = d2.readlines().sort() + pb1 = "file schemes produced by successive executions are not identical: " + fileOrig + pb2 = "final dump states produced by successive executions are not identical: " + fileOrig + self.assertEqual(ls1,ls2,pb1) + self.assertEqual(ld1,ld2,pb2) + pass + + +import os +U = os.getenv('USER') +f=open("/tmp/" + U + "/UnitTestsResult", 'a') +f.write(" --- TEST src/yacsloader: testSave.py\n") +suite = unittest.makeSuite(TestSave) +unittest.TextTestRunner(f, descriptions=1, verbosity=1).run(suite) +f.close() diff --git a/src/yacsloader/Test/waitContainers.py b/src/yacsloader/Test/waitContainers.py new file mode 100644 index 000000000..c8a2b6174 --- /dev/null +++ b/src/yacsloader/Test/waitContainers.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +import os +import orbmodule +clt = orbmodule.client() +FactoryContainer = "/Containers/" + os.environ["NSHOST"] + "/FactoryServer" +clt.waitNS(FactoryContainer) + diff --git a/src/yacsloader/Test/xmlrun_orig.sh b/src/yacsloader/Test/xmlrun_orig.sh new file mode 100755 index 000000000..07124a49d --- /dev/null +++ b/src/yacsloader/Test/xmlrun_orig.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env python + +import xmlrpclib,sys + +#example +data=""" + + echo + + hello, world + 3.5 + coucou + + +""" +def echo(args): + print "args=",args + if not args: + return None + elif len(args) == 1: + return args[0] + else: + return args + +f=open("input") +data=f.read() +f.close() +print data + +class Objref: + """Wrapper for objrefs """ + def __init__(self,data=None): + self.data=data + def __str__(self): + return self.data or "" + def __cmp__(self, other): + if isinstance(other, Binary): + other = other.data + return cmp(self.data, other) + + def decode(self, data): + self.data = data + + def encode(self, out): + out.write("") + out.write(self.data or "") + out.write("\n") + +xmlrpclib.WRAPPERS=xmlrpclib.WRAPPERS+(Objref,) + +def end_objref(self,data): + self.append(Objref(data)) + self._value=0 + +xmlrpclib.Unmarshaller.end_objref=end_objref +xmlrpclib.Unmarshaller.dispatch["objref"]=end_objref + +params, method = xmlrpclib.loads(data) + +try: + call=eval(method) + response=call(params) + response = (response,) +except: + # report exception back to server + response = xmlrpclib.dumps( xmlrpclib.Fault(1, "%s:%s" % sys.exc_info()[:2])) +else: + response = xmlrpclib.dumps( response, methodresponse=1) + +print response +f=open("output",'w') +f.write(response) +f.close() diff --git a/src/yacsloader/debugger.cxx b/src/yacsloader/debugger.cxx new file mode 100644 index 000000000..17df8f259 --- /dev/null +++ b/src/yacsloader/debugger.cxx @@ -0,0 +1,130 @@ +#include "RuntimeSALOME.hxx" +#include "Proc.hxx" +#include "Exception.hxx" +#include "Executor.hxx" +#include "parsers.hxx" +#include "Thread.hxx" + +#include +#include + +using YACS::YACSLoader; +using YACS::ENGINE::RuntimeSALOME; +using YACS::ENGINE::Executor; +using YACS::ENGINE::Proc; +using YACS::BASES::Thread; +using namespace std; + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +void *executorFunc(void *arg) +{ + void **argT=(void **)arg; + Executor *myExec = (Executor *)argT[0]; + Proc *myProc = (Proc *)argT[1]; + myExec->RunB(myProc, 2); +} + +int +main (int argc, char* argv[]) +{ + if (argc != 2) + { + cerr << "usage: " << argv[0] << " schema.xml" << endl; + return 1; + } + + RuntimeSALOME::setRuntime(); + + YACSLoader loader; + Executor *executor = new Executor(); + + try + { + Proc* p=loader.load(argv[1]); + std::ofstream f("toto"); + p->writeDot(f); + f.close(); + + executor->setExecMode(YACS::STEPBYSTEP); + void **args=new void *[2]; + args[0]=(void *)executor; + args[1]=(void *)p; + Thread* execThread = new Thread(executorFunc,args); + char com; + cerr << "enter a char to start" << endl; + cin >> com; + //executor->wakeUp(); + while (executor->isNotFinished()) + { + YACS::ExecutorState executorState = executor->getExecutorState(); + cerr << "executorState: " << executorState << endl; + cerr << "command display=d step=s : "; + cin >> com; + switch (com) + { + case 's': + { + executor->setExecMode(YACS::STEPBYSTEP); + bool res = executor->resumeCurrentBreakPoint(); + cerr << "resumeCurrentBreakPoint(): " << res << endl; + break; + } + case 'd': + { + executor->displayDot(p); + break; + } + default: + { + cerr << "commande inconnue" << endl; + } + } + } + execThread->join(); + std::ofstream g("titi"); + p->writeDot(g); + g.close(); + delete executor; + return 0; + } + catch (YACS::Exception& e) + { + DEBTRACE("exception YACS levee " << e.what()); + return 1; + } + catch (const std::ios_base::failure&) + { + DEBTRACE("io failure"); + return 1; + } + catch(CORBA::SystemException& ex) + { + DEBTRACE("..."); + CORBA::Any tmp; + tmp <<= ex; + CORBA::TypeCode_var tc = tmp.type(); + const char *p = tc->name(); + if ( *p != '\0' ) + { + DEBTRACE("Caught a CORBA::SystemException. " <id()); + } + return 1; + } + catch(omniORB::fatalException& fe) + { + DEBTRACE("Caught omniORB::fatalException: file: "< +#include +#include + +using YACS::YACSLoader; +using namespace YACS::ENGINE; +using namespace std; + + +// --- use of glibc argp interface for parsing unix-style arguments + +const char *argp_program_version ="driver V0.1"; +const char *argp_program_bug_address =""; +static char doc[] ="driver -- a SALOME YACS graph executor"; +static char args_doc[] = "graph.xml"; + +static struct argp_option options[] = + { + {"display", 'd', "level", 0, "Display dot files: 0=never to 3=very often"}, + {"verbose", 'v', 0, 0, "Produce verbose output" }, + {"stop-on-error", 's', 0, 0, "Stop on first error" }, + {"dump-on-error", 'e', "file", OPTION_ARG_OPTIONAL, "Stop on first error and dump state"}, + {"dump-final", 'f', "file", OPTION_ARG_OPTIONAL, "dump final state"}, + {"load-state", 'l', "file", 0, "Load State from a previous partial execution"}, + {"save-xml-schema", 'x', "file", OPTION_ARG_OPTIONAL, "dump xml schema"}, + { 0 } + }; + +struct arguments +{ + char *args[1]; + int display; + int verbose; + int stop; + char *dumpErrorFile; + char *finalDump; + char *xmlSchema; + char *loadState; +}; + +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + // Get the input argument from argp_parse, which we + // know is a pointer to our arguments structure. + struct arguments *myArgs = (arguments*)state->input; + + switch (key) + { + case 'd': + myArgs->display = atoi(arg); + break; + case 'v': + myArgs->verbose = 1; + break; + case 's': + myArgs->stop = 1; + break; + case 'e': + myArgs->stop = 1; + if (arg) + myArgs->dumpErrorFile = arg; + else + myArgs->dumpErrorFile = "dumpErrorState.xml"; + break; + case 'f': + if (arg) + myArgs->finalDump = arg; + else + myArgs->finalDump = "finalDumpState.xml"; + break; + case 'l': + myArgs->loadState = arg; + break; + case 'x': + if (arg) + myArgs->xmlSchema = arg; + else + myArgs->xmlSchema = "saveSchema.xml"; + break; + + case ARGP_KEY_ARG: + if (state->arg_num >=1) // Too many arguments. + argp_usage (state); + myArgs->args[state->arg_num] = arg; + break; + + case ARGP_KEY_END: + if (state->arg_num < 1) // Not enough arguments. + argp_usage (state); + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +// Our argp parser. +static struct argp argp = { options, parse_opt, args_doc, doc }; + + +main (int argc, char* argv[]) +{ + struct arguments myArgs; + + // Default values. + myArgs.display = 0; + myArgs.verbose = 0; + myArgs.stop = 0; + myArgs.dumpErrorFile= ""; + myArgs.finalDump = ""; + myArgs.loadState = ""; + myArgs.xmlSchema = ""; + + // Parse our arguments; every option seen by parse_opt will be reflected in arguments. + argp_parse (&argp, argc, argv, 0, 0, &myArgs); + cerr << "graph = " << myArgs.args[0] + << " options: display=" << myArgs.display + << " verbose="<writeDot(f); + f.close(); + + cerr << "+++++++++++++++++++ start calculation +++++++++++++++++++" << endl; + executor.RunW(p,myArgs.display, fromScratch); + cerr << "+++++++++++++++++++ end calculation +++++++++++++++++++" << endl; + cerr << "Proc state : " << p->getEffectiveState() << endl; + + std::ofstream g("titi"); + p->writeDot(g); + g.close(); + + bool isFinalDump = (strlen(myArgs.finalDump) != 0); + if (isFinalDump) + { + YACS::ENGINE::VisitorSaveState vst(p); + vst.openFileDump(myArgs.finalDump); + p->accept(&vst); + vst.closeFileDump(); + } + delete p; + Runtime* r=YACS::ENGINE::getRuntime(); + Dispatcher* disp=Dispatcher::getDispatcher(); + r->fini(); + delete r; + delete disp; + return 0; + } + catch (YACS::Exception& e) + { + cerr << "Caught a YACS exception" << endl; + cerr << e.what() << endl; + Runtime* r=YACS::ENGINE::getRuntime(); + Dispatcher* disp=Dispatcher::getDispatcher(); + r->fini(); + delete r; + delete disp; + return 1; + } + catch (const std::ios_base::failure&) + { + cerr << "Caught an io failure exception" << endl; + return 1; + } + catch(CORBA::SystemException& ex) + { + cerr << "Caught a CORBA::SystemException." ; + CORBA::Any tmp; + tmp <<= ex; + CORBA::TypeCode_var tc = tmp.type(); + const char *p = tc->name(); + if ( *p != '\0' ) + cerr <id(); + cerr << endl; + return 1; + } + catch(omniORB::fatalException& fe) + { + cerr << "Caught omniORB::fatalException:" << endl; + cerr << " file: " << fe.file() << endl; + cerr << " line: " << fe.line() << endl; + cerr << " mesg: " << fe.errmsg() << endl; + return 1; + } + catch(...) + { + cerr << "Caught unknown exception." << endl; + return 1; + } +} + diff --git a/src/yacsloader/factory.cxx b/src/yacsloader/factory.cxx new file mode 100644 index 000000000..4a292b4e7 --- /dev/null +++ b/src/yacsloader/factory.cxx @@ -0,0 +1,4 @@ +#include + +#include "factory.hxx" + diff --git a/src/yacsloader/factory.hxx b/src/yacsloader/factory.hxx new file mode 100644 index 000000000..669e42882 --- /dev/null +++ b/src/yacsloader/factory.hxx @@ -0,0 +1,106 @@ +#ifndef _FACTORY_HXX_ +#define _FACTORY_HXX_ + +#include +#include +#include + +struct mytype{ + std::string _name; + std::string _kind; +}; + +struct mycontrol{ + void fromnode(const std::string& fromnode) { _fromnode = fromnode; } + void tonode(const std::string& tonode) { _tonode = tonode; } + std::string fromnode()const { return _fromnode ; } + std::string tonode()const { return _tonode ; } + std::map _props; + void clear() + { + _props.clear(); + } + void setProperty(const std::string& name, const std::string& value) + { + _props[name]=value; + } +private: + std::string _fromnode; + std::string _tonode; +}; + +struct mylink:mycontrol{ + void fromport(const std::string& fromport) { _fromport = fromport; } + void toport(const std::string& toport) { _toport = toport; } + std::string fromport()const { return _fromport ; } + std::string toport()const { return _toport ; } + bool withControl() const { return _withControl ;} + + bool _withControl; +private: + std::string _fromport; + std::string _toport; +public: + void clear() + { + _props.clear(); + _withControl=true; + } +}; + +struct mystream:mylink{ +}; + +struct myparam{ + std::string _tonode; + std::string _toport; + std::string _value; +}; + +struct myinport{ + std::string _name; + std::string _type; + std::map _props; + void clear() + { + _props.clear(); + } + void setProperty(const std::string& name, const std::string& value) + { + _props[name]=value; + } +}; + +struct myoutport:myinport{}; + +struct myprop{ + std::string _name; + std::string _value; +}; + +typedef std::vector myprops; + +struct myfunc{ + std::string _name; + std::string _code; +}; + +struct machine +{ + std::string _name; +}; +typedef std::vector machines; + +struct mycontainer +{ + std::string _name; + machines _machs; + std::map _props; +}; + +struct loadon +{ + std::string _container; +}; + +#endif diff --git a/src/yacsloader/loader.i b/src/yacsloader/loader.i new file mode 100644 index 000000000..0f0206b26 --- /dev/null +++ b/src/yacsloader/loader.i @@ -0,0 +1,74 @@ +// ---------------------------------------------------------------------------- +%define LOADERDOCSTRING +"Loader docstring +loads an XML file." +%enddef + +%module(docstring=LOADERDOCSTRING) loader + +%feature("autodoc", "0"); + +%include std_string.i + +// ---------------------------------------------------------------------------- + +%{ +#include +#include +#include + +#include "Proc.hxx" +#include "Exception.hxx" +#include "parsers.hxx" +#include "LoadState.hxx" + +using namespace YACS::ENGINE; +using namespace std; + +%} + +%exception load { + try { + $action + } catch(YACS::Exception& _e) { + PyErr_SetString(PyExc_ValueError,_e.what()); + return NULL; + } catch(std::invalid_argument& _e) { + PyErr_SetString(PyExc_IOError ,_e.what()); + return NULL; + } +} + +namespace YACS +{ + class YACSLoader + { + public: + YACSLoader(); +%feature("autodoc", "load(self, file) -> YACS::ENGINE::Proc"); +%feature("docstring") "loads a XML file which name is given by file argument" ; + virtual YACS::ENGINE::Proc* load(char *); + }; +} + +class xmlParserBase +{ +}; + +namespace YACS +{ + namespace ENGINE + { + class stateParser: public xmlParserBase + { + }; + + class stateLoader: public xmlReader + { + public: + stateLoader(xmlParserBase* parser, + YACS::ENGINE::Proc* p); + virtual void parse(std::string xmlState); + }; + } +} diff --git a/src/yacsloader/parsers.cxx b/src/yacsloader/parsers.cxx new file mode 100644 index 000000000..19f307f58 --- /dev/null +++ b/src/yacsloader/parsers.cxx @@ -0,0 +1,3005 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "parsers.hxx" +#include "factory.hxx" +#include "Runtime.hxx" +#include "Exception.hxx" +#include "Cstr2d.hxx" +#include "TypeCode.hxx" +#include "Loop.hxx" +#include "ForLoop.hxx" +#include "ForEachLoop.hxx" +#include "WhileLoop.hxx" +#include "Switch.hxx" +#include "Bloc.hxx" +#include "Proc.hxx" +#include "InlineNode.hxx" +#include "ServiceNode.hxx" +#include "ServiceInlineNode.hxx" +#include "OutputPort.hxx" +#include "InputPort.hxx" +#include "OutputDataStreamPort.hxx" +#include "InputDataStreamPort.hxx" +#include "ComponentInstance.hxx" +#include "Container.hxx" + +using namespace YACS; +using YACS::ENGINE::Runtime; +using YACS::ENGINE::getRuntime; + +using YACS::ENGINE::TypeCode; +using YACS::Exception; +using YACS::ENGINE::TypeCodeObjref; +using YACS::ENGINE::TypeCodeStruct; +using YACS::ENGINE::Objref; +using YACS::ENGINE::InlineNode; +using YACS::ENGINE::InlineFuncNode; +using YACS::ENGINE::ServiceNode; +using YACS::ENGINE::ServiceInlineNode; +using YACS::ENGINE::Node; +using YACS::ENGINE::Loop; +using YACS::ENGINE::ForLoop; +using YACS::ENGINE::ForEachLoop; +using YACS::ENGINE::WhileLoop; +using YACS::ENGINE::Switch; +using YACS::ENGINE::Bloc; +using YACS::ENGINE::Proc; +using YACS::ENGINE::InputPort; +using YACS::ENGINE::OutputPort; +using YACS::ENGINE::InputDataStreamPort; +using YACS::ENGINE::OutputDataStreamPort; + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +Runtime* theRuntime=0; +static Proc* currentProc; + +#define BUFFSIZE 8192 + +char Buff[BUFFSIZE]; + +XML_Parser p ; + +std::stack sp; + +parser::~parser() +{ + if(_level==0) + { + delete _counts; + } + else + { + DEBTRACE("Problem with parser: final stack level should be 0 and not " << _level); + } +} + +void parser::SetUserDataAndPush(parser* pp) +{ + XML_SetUserData(p,pp); + sp.push(pp); +} + +void XMLCALL parser::start(void *data, const XML_Char* el, const XML_Char** attr) +{ + parser* pp=static_cast (data); + pp->incrCount(el); + pp->onStart(el,attr); +} + +void parser::onEnd(const XML_Char *el,parser* child) +{ + DEBTRACE("parser::onEnd: " << el) +} + +void XMLCALL parser::end(void *data, const char *el) +{ + DEBTRACE("parser::end: " << el); + parser* child=static_cast (data); + sp.pop(); + parser* pp=sp.top(); + XML_SetUserData(p,pp); + pp->onEnd(el,child); + child->end(); +} + +void parser::charData(const XML_Char *s, int len) +{ + _content=_content+std::string(s,len); +} + +void XMLCALL parser::charac(void *data, const XML_Char *s, int len) +{ + parser* pp=static_cast (data); + pp->charData(s,len); +} + +void parser::end () +{ + _level=_level-1; + if(_level>0) + { + delete _counts; + _counts=_stackCount.top(); + _orderState=_stackOrder.top(); + _stackCount.pop(); + _stackOrder.pop(); + } +} + +void parser::init () +{ + if(_level>0) + { + _stackCount.push(_counts); + _stackOrder.push(_orderState); + _counts=new std::map; + } + _level=_level+1; + _counts->clear(); + _orderState=0; +} + +void parser::incrCount(const XML_Char *el) +{ + if(_counts->count(el)==0) + (*_counts)[el]=1; + else + (*_counts)[el]=(*_counts)[el]+1; +} + +void parser::checkOrder(std::string& el) +{ + if(_orders.count(el)==0)return; + if(_orders[el] < _orderState) + { + std::string msg="unexpected "+el+" element (wrong order)"; + throw YACS::Exception::Exception(msg); + } + else if(_orders[el] > _orderState) + { + _orderState=_orders[el]; + } +} + +void parser::maxcount(std::string name, int max, std::string& el) +{ + if(el!=name)return; + if((*_counts)[name]>max) + { + std::stringstream msg; + msg <<"unexpected "+name+" element (count="<<(*_counts)[name]; + msg <<" > maxOccurs=" << max << ")"; + throw YACS::Exception::Exception(msg.str()); + } +} + +void parser::mincount(std::string name,int min ) +{ + if((*_counts)[name]max) + { + std::stringstream msg; + msg<<"unexpected "+el+" element (choice count="< maxOccurs=" << max << ")"; + throw YACS::Exception::Exception(msg.str()); + } +} + +void parser::minchoice(std::string *names, int min) +{ + int i=0; + int ncount=0; + while (names[i]!= "") + { + ncount=ncount+(*_counts)[names[i]]; + ++i; + } + if(ncount> a)) +// throw YACS::Exception::Exception("problem in conversion from string to double"); +// std::cerr << "--------------_content s a "<< _content.c_str() << " " << s.str() << " " << a << std::endl; +// return a; + } +}; +static doubletypeParser doubleParser; + +/*! \brief Class for integer parser. + * + * Class used to parse integer + */ +struct inttypeParser:parser +{ + int post() + { + return atoi(_content.c_str()); + } +}; +static inttypeParser intParser; + +/*! \brief Class for boolean parser. + * + * Class used to parse bool + */ +struct booltypeParser:parser +{ + bool post() + { + DEBTRACE( _content ) + if(_content == "true")return true; + if(_content == "false")return false; + std::stringstream temp(_content); + bool b ; + temp >> b; + //std::cerr << b << std::endl; + return b; + } +}; +static booltypeParser boolParser; + +/*! \brief Class for property parser. + * + * Class used to parse a property + * A property is a pair of name(string), value(string) + * XML schema is + * + * + * + * + * + */ +struct propertytypeParser: parser +{ + virtual void buildAttr(const XML_Char** attr) + { + required("name",attr); + required("value",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "value")value(attr[i+1]); + } + } + virtual void name(const std::string& name){ _prop._name=name; } + virtual void value(const std::string& name){ _prop._value=name; } + myprop post(){return _prop;} + myprop _prop; +}; +static propertytypeParser propertyParser; + +/*! \brief Class for type parser. + * + * Class used to parse a type definition (class TypeCode in implementation) + * with a name and a kind (reserved to atomic types) + * XML schema is + * + * + * + * + * + */ +struct typetypeParser: parser +{ + virtual void buildAttr(const XML_Char** attr) + { + required("name",attr); + required("kind",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "kind")kind(attr[i+1]); + } + } + virtual void pre (){} + virtual void name(const std::string& name) + { + DEBTRACE( "type_name: " << name ) + _name=name; + } + virtual void kind(const std::string& name) + { + DEBTRACE( "type_kind: " << name ) + _kind=name; + } + virtual mytype post() + { + DEBTRACE( "type_post" ) + mytype t; + t._kind=_kind; + t._name=_name; + return t; + } + std::string _name; + std::string _kind; +}; +static typetypeParser typeParser; + +/*! \brief Class for sequence parser. + * + * Class used to parse a sequence (type) definition (class TypeCodeSeq in implementation) + * XML schema is + * + * + * + * + * + */ +struct seqtypeParser:public parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + DEBTRACE( "seqtypeParser::onStart: " << el ) + parser* pp=&main_parser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + DEBTRACE( "seqtypeParser::onEnd: " << el ) + } + virtual void buildAttr(const XML_Char** attr) + { + required("name",attr); + required("content",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "content")content(attr[i+1]); + } + } + void name(const std::string& name) + { + DEBTRACE( "seqtype_name: " << name ) + _name=name; + } + void content(const std::string& name) + { + DEBTRACE( "seqtype_content: " << name ) + if(currentProc->typeMap.count(name)==0) + { + std::stringstream msg; + msg << "Type " << name << " does not exist" << " (" <<__FILE__ << ":" << __LINE__ << ")"; + throw Exception(msg.str()); + } + _contentType=currentProc->typeMap[name]; + + } + TypeCode* post() + { + DEBTRACE( "seqtype_post" ) + TypeCode *t = currentProc->createSequenceTc(_name,_name,_contentType); + return t; + } + TypeCode* _contentType; + std::string _name; +}; +static seqtypeParser seqParser; + +/*! \brief Class for objref parser. + * + * Class used to parse a objref (type) definition (class TypeCodeObjref in implementation) + * XML schema is + * + * + * + * + * + * + * + * + */ +struct objtypeParser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + DEBTRACE( "objtypeParser::onStart: " << el ) + std::string element(el); + parser* pp=&main_parser; + if(element == "base")pp=&stringParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + DEBTRACE( "objtypeParser::onEnd: " << el ) + std::string element(el); + if(element == "base")base(((stringtypeParser*)child)->post()); + } + virtual void buildAttr(const XML_Char** attr) + { + required("name",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "id")id(attr[i+1]); + } + } + virtual void pre () + { + _id=""; + _ltc.clear(); + } + virtual void name(const std::string& name) + { + DEBTRACE( "objtype_name: " << name ) + _name=name; + } + virtual void id(const std::string& name) + { + DEBTRACE( "objtype_id: " << name ) + _id=name; + } + virtual void base(const std::string& name) + { + DEBTRACE( "base_name: " << name ) + if(currentProc->typeMap.count(name)==0) + { + std::stringstream msg; + msg << "Type " << name << " does not exist" ; + msg << " (" <<__FILE__ << ":" << __LINE__ << ")"; + throw Exception(msg.str()); + } + if(currentProc->typeMap[name]->kind() != Objref) + { + std::stringstream msg; + msg << "Type " << name << " is not an objref" ; + msg << " (" <<__FILE__ << ":" << __LINE__ << ")"; + throw Exception(msg.str()); + } + _ltc.push_back((TypeCodeObjref *)currentProc->typeMap[name]); + } + virtual TypeCode * post() + { + DEBTRACE( "objtype_post" ) + TypeCode *t = currentProc->createInterfaceTc(_id,_name,_ltc); + return t; + } + std::string _name; + std::string _id; + std::list _ltc; +}; +static objtypeParser objParser; + +/*! \brief Class for member parser. + * + * Class used to parse a struct member + * A struct member is a pair of name(string), type(string) + * XML schema is + * + * + * + * + * + */ +struct membertypeParser: parser +{ + virtual void buildAttr(const XML_Char** attr) + { + required("name",attr); + required("type",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "type")type(attr[i+1]); + } + } + virtual void name(const std::string& name){ _prop._name=name; } + virtual void type(const std::string& name){ _prop._value=name; } + myprop post(){return _prop;} + myprop _prop; +}; +static membertypeParser memberParser; + +/*! \brief Class for struct parser. + * + * Class used to parse a struct (type) definition (class TypeCodeStruct in implementation) + * XML schema is + * + * + * + * + * + * + * + * + */ +struct structtypeParser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + DEBTRACE( "structtypeParser::onStart: " << el ) + std::string element(el); + parser* pp=&main_parser; + if(element == "member")pp=&memberParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + DEBTRACE( "structtypeParser::onEnd: " << el ) + std::string element(el); + if(element == "member")member(((membertypeParser*)child)->post()); + } + virtual void buildAttr(const XML_Char** attr) + { + required("name",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "id")id(attr[i+1]); + } + } + virtual void pre () + { + _id=""; + _members.clear(); + } + virtual void name(const std::string& name) + { + DEBTRACE( "structtype_name: " << name ); + _name=name; + } + virtual void id(const std::string& name) + { + DEBTRACE( "structtype_id: " << name ); + _id=name; + } + virtual void member (const myprop& prop) + { + DEBTRACE( "structtype_member: " << prop._name << prop._value ); + if(currentProc->typeMap.count(prop._value)!=0) + _members.push_back(prop); + else + { + std::string msg="Unknown type " + prop._value + " for member " + prop._name + " in struct " + _name; + throw Exception(msg); + } + } + virtual TypeCode * post() + { + DEBTRACE( "structtype_post" ); + TypeCodeStruct *t; + if(currentProc->typeMap.count(_name)!=0) + { + //reuse a forward declaration + TypeCode* tt=currentProc->typeMap[_name]; + if(tt->kind()==YACS::ENGINE::Struct) + { + t=(TypeCodeStruct*)tt; + } + else + { + std::string msg="Forward declaration must be a struct type but " + std::string(tt->name()) + " is not one" ; + throw Exception(msg); + } + } + else + { + t = (TypeCodeStruct*)currentProc->createStructTc(_id,_name); + } + std::vector::const_iterator iter; + for(iter=_members.begin();iter!=_members.end();iter++) + { + DEBTRACE("member: " << iter->_name << " " <_value); + t->addMember(iter->_name,currentProc->typeMap[iter->_value]); + } + return t; + } + std::string _name; + std::string _id; + std::vector _members; +}; +static structtypeParser structParser; + +/*! \brief Class for machine parser. + * + * Class used to parse computer adress on which container must be started + * XML schema is + * + * + * + */ +struct machinetypeParser: parser +{ + virtual void buildAttr(const XML_Char** attr) + { + required("name",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + } + } + virtual void pre (){_mach._name="";} + virtual void name(const std::string& name){ _mach._name=name; } + machine post() + { + return _mach; + } + machine _mach; +}; +static machinetypeParser machineParser; + +/*! \brief Class for container parser + * + * Class used to parse container description + * XML schema is + * + * + * + * + * + * + * + */ +struct containertypeParser: parser +{ + virtual void buildAttr(const XML_Char** attr) + { + required("name",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + } + } + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::string element(el); + parser* pp=&main_parser; + if(element == "machine")pp=&machineParser; + if(element == "property")pp=&propertyParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + std::string element(el); + if(element == "machine")machine_(((machinetypeParser*)child)->post()); + if(element == "property")property(((propertytypeParser*)child)->post()); + } + virtual void pre (){_container._machs.clear();} + virtual void name(const std::string& name){ _container._name=name; } + virtual void machine_(const machine& m) + { + DEBTRACE( "machine: " << m._name ) + _container._machs.push_back(m); + } + virtual void property (const myprop& prop) + { + DEBTRACE( "property_set: " << prop._name << prop._value ) + _container._props[prop._name]=prop._value; + } + mycontainer post() + { + //mincount("machine",1); + return _container; + } + mycontainer _container; +}; +static containertypeParser containerParser; + +/*! \brief Class for loading parser + * + * Class used to parse service node loading information + * XML schema is + * + * + * + */ +struct loadtypeParser: parser +{ + virtual void buildAttr(const XML_Char** attr) + { + required("container",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "container")container(attr[i+1]); + } + } + virtual void pre (){_loadon._container="";} + virtual void container(const std::string& name){ _loadon._container=name; } + loadon post() + { + return _loadon; + } + loadon _loadon; +}; +static loadtypeParser loadParser; + +/*! \brief Class for Inport parser. + * + * This class is a base class for other inport parsers + * + * + * + * + * + * + * + * + */ +template +struct inporttypeParser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::string element(el); + parser* pp=&main_parser; + if(element == "property")pp=&propertyParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + std::string element(el); + if(element == "property")property(((propertytypeParser*)child)->post()); + } + virtual void buildAttr(const XML_Char** attr) + { + required("name",attr); + required("type",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "type")type(attr[i+1]); + } + } + virtual void pre () + { + _port._name=""; + _port._type=""; + _port.clear(); + } + virtual void name(const std::string& name) + { + _port._name=name; + } + virtual void type(const std::string& type) + { + _port._type=type; + } + virtual void property (const myprop& prop) + { + DEBTRACE( "property_set: " << prop._name << prop._value ) + _port.setProperty(prop._name,prop._value); + } + virtual T& post() + { + return _port; + } +protected: + T _port; +}; +static inporttypeParser<> inportParser; + +/*! \brief Class for Outport parser. + * + * This class is also used for OutputDataStream Port + * same XML schema as inporttypeParser + */ +template +struct outporttypeParser:public inporttypeParser +{ +}; +static outporttypeParser<> outportParser; + +/*! \brief Class for node parser. + * + * This class is a base class for other parsers + */ +template +struct nodetypeParser:public parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + DEBTRACE( "nodetypeParser::onStart: " << el ) + std::string element(el); + parser* pp=&main_parser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + DEBTRACE( "nodetypeParser::onEnd: " << el ) + std::string element(el); + } + virtual void buildAttr(const XML_Char** attr) + { + required("name",attr); + required("type",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "state")state(attr[i+1]); + if(std::string(attr[i]) == "type")type(attr[i+1]); + } + } + virtual void pre() + { + _node=0; + } + virtual void name (const std::string& name) + { + DEBTRACE( "inline_name: " << name ) + _name=name; + } + virtual void state (const std::string& name) + { + _state=name; + } + virtual void type (const std::string& name) + { + DEBTRACE( "node_type " << name ) + _type=name; + } + virtual T post() + { + return _node; + } + std::string _type; + std::string _name; + std::string _state; + T _node; +}; +static nodetypeParser<> nodeParser; + +template <> +InlineNode* nodetypeParser::post () +{ + std::string fullname = currentProc->names.back()+_type; + if(currentProc->inlineMap.count(_type) != 0) + { + //InlineNode type with absolute name found + InlineNode* n=currentProc->inlineMap[_type]; + _node=n->cloneNode(_name); + } + else if(currentProc->inlineMap.count(fullname) != 0) + { + //InlineNode type with relative name found + InlineNode* n=currentProc->inlineMap[fullname]; + _node=n->cloneNode(_name); + } + else + { + throw Exception("Unknown InlineNode type"); + } + if(_state == "disabled")_node->exDisabledState(); + DEBTRACE( "node_post " << _node->getName() ) + return _node; +} + +struct codetypeParser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::string element(el); + parser* pp=&main_parser; + if(element == "code")pp=&stringParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + std::string element(el); + if(element == "code")code(((stringtypeParser*)child)->post()); + } + virtual void pre (){_code="";} + virtual void code (const std::string& s) + { + if(_code == "") + _code=s; + else + _code=_code + '\n' + s; + } + virtual myfunc post () + { + _func._name="script"; + _func._code=_code; + return _func; + } + std::string _code; + myfunc _func; +}; +static codetypeParser codeParser; + +struct functypeParser: codetypeParser +{ + virtual void buildAttr(const XML_Char** attr) + { + required("name",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + } + } + virtual void name (const std::string& name) + { + _func._name=name; + } + virtual myfunc post () + { + _func._code=_code; + return _func; + } +}; +static functypeParser funcParser; + +static std::string t1[]={"script","function",""}; + +template +struct inlinetypeParser:public nodetypeParser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + DEBTRACE( "inlinetypeParser::onStart: " << el ) + std::string element(el); + parser* pp=&main_parser; + this->maxcount("kind",1,element); + this->maxcount("script",1,element); + this->maxcount("function",1,element); + this->maxchoice(t1,1,element); + if(element == "kind")pp=&stringParser; + else if(element == "script")pp=&codeParser; + else if(element == "function")pp=&funcParser; + else if(element == "inport")pp=&inportParser; + else if(element == "outport")pp=&outportParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + DEBTRACE( "inlinetypeParser::onEnd: " << el ) + std::string element(el); + if(element == "kind")kind(((stringtypeParser*)child)->post()); + else if(element == "script")script(((codetypeParser*)child)->post()); + else if(element == "function")function(((functypeParser*)child)->post()); + else if(element == "inport") inport(((inporttypeParser*)child)->post()); + else if(element == "outport") outport(((outporttypeParser*)child)->post()); + } + virtual void buildAttr(const XML_Char** attr) + { + this->required("name",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")this->name(attr[i+1]); + if(std::string(attr[i]) == "state")this->state(attr[i+1]); + } + } + virtual void pre () + { + this->_node=0; + _kind=""; + this->_state=""; + } + virtual void kind (const std::string& name) + { + DEBTRACE( "inline_kind " << name ) + _kind=name; + } + virtual void script (const myfunc& f){} + virtual void function (const myfunc& f) {} + virtual void inport (const myinport& p) + { + DEBTRACE( "inline_inport: " << p._name <<":"<_node==0) + throw Exception("Node must be completely defined before defining its ports"); + if(currentProc->typeMap.count(p._type)==0) + { + std::string msg="Unknown InPort Type: "; + msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name; + throw Exception(msg); + } + this->_node->edAddInputPort(p._name,currentProc->typeMap[p._type]); + } + virtual void outport (const myoutport& p) + { + DEBTRACE( "inline_outport: " << p._name <<":"<_node==0) + throw Exception("Node must be completely defined before defining its ports"); + if(currentProc->typeMap.count(p._type)==0) + { + std::string msg="Unknown OutPort Type: "; + msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name; + throw Exception(msg); + } + this->_node->edAddOutputPort(p._name,currentProc->typeMap[p._type]); + } + virtual T post() + { + DEBTRACE( "inline_post " << this->_node->getName() ) + if(this->_state == "disabled")this->_node->exDisabledState(); + /* + std::list::iterator iter; + std::list s=_node->getSetOfOutputPort(); + for(iter=s.begin();iter!=s.end();iter++) + { + std::cerr << "port name: " << (*iter)->getName() << std::endl; + std::cerr << "port kind: " << (*iter)->edGetType()->kind() << std::endl; + } + */ + return this->_node; + } + std::string _kind; +}; +static inlinetypeParser<> inlineParser; + +template <> +void inlinetypeParser::script (const myfunc& f) +{ + DEBTRACE( "inline_script: " << f._code ) + _node=theRuntime->createScriptNode(_kind,_name); + _node->setScript(f._code); +} +template <> +void inlinetypeParser::function (const myfunc& f) +{ + DEBTRACE( "inline_function: " << f._code ) + InlineFuncNode *fnode; + fnode=theRuntime->createFuncNode(_kind,_name); + fnode->setScript(f._code); + fnode->setFname(f._name); + _node=fnode; +} + +/*! \brief Class for parsing ServiceInlineNode description + * + * + */ +template +struct sinlinetypeParser:public inlinetypeParser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + DEBTRACE( "sinlinetypeParser::onStart: " << el ) + std::string element(el); + parser* pp=&main_parser; + this->maxcount("kind",1,element); + this->maxcount("function",1,element); + this->maxcount("load",1,element); + if(element == "kind")pp=&stringParser; + else if(element == "function")pp=&funcParser; + else if(element == "load")pp=&loadParser; + else if(element == "inport")pp=&inportParser; + else if(element == "outport")pp=&outportParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + DEBTRACE( "sinlinetypeParser::onEnd: " << el ) + std::string element(el); + if(element == "kind")this->kind(((stringtypeParser*)child)->post()); + else if(element == "function")this->function(((functypeParser*)child)->post()); + else if(element == "load") load(((loadtypeParser*)child)->post()); + else if(element == "inport") this->inport(((inporttypeParser*)child)->post()); + else if(element == "outport") this->outport(((outporttypeParser*)child)->post()); + } + //virtual void service (const myfunc& f) {} + virtual void load (const loadon& l) + { + DEBTRACE( "sinline_load: " ) + if(this->_node==0) + throw Exception("ServiceInlineNode must be completely defined before defining how to load it"); + + if(currentProc->containerMap.count(l._container) != 0) + { + //If it has already a container replace it ????? + this->_node->getComponent()->setContainer(currentProc->containerMap[l._container]); + } + else + { + std::cerr << "WARNING: Unknown container " << l._container << std::endl; + } + } +}; + +template <> +void inlinetypeParser::function (const myfunc& f) +{ + DEBTRACE( "sinline_function: " << f._code ) + ServiceInlineNode *fnode; + fnode=theRuntime->createSInlineNode(_kind,_name); + fnode->setScript(f._code); + fnode->setMethod(f._name); + fnode->setComponent(theRuntime->createComponentInstance("PyCompo","SalomePy")); + //fnode->setRef("PyCompo"); + _node=fnode; +} + +static sinlinetypeParser<> sinlineParser; + +static std::string t2[]={"ref","node","component",""}; + +template +struct servicetypeParser:public inlinetypeParser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + DEBTRACE( "servicetypeParser::onStart: " << el ) + std::string element(el); + parser* pp=&main_parser; + this->maxcount("kind",1,element); + this->maxcount("ref",1,element); + this->maxcount("node",1,element); + this->maxcount("component",1,element); + this->maxcount("method",1,element); + this->maxcount("load",1,element); + this->maxchoice(t2,1,element); + if(element == "kind")pp=&stringParser; + else if(element == "ref")pp=&stringParser; + else if(element == "component")pp=&stringParser; + else if(element == "node")pp=&stringParser; + else if(element == "method")pp=&stringParser; + else if(element == "load")pp=&loadParser; + else if(element == "inport")pp=&inportParser; + else if(element == "outport")pp=&outportParser; + else if(element == "instream")pp=&inportParser; + else if(element == "outstream")pp=&outportParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + DEBTRACE( "servicetypeParser::onEnd: " << el ) + std::string element(el); + if(element == "kind")this->kind(((stringtypeParser*)child)->post()); + else if(element == "ref") ref(((stringtypeParser*)child)->post()); + else if(element == "component") component(((stringtypeParser*)child)->post()); + else if(element == "node") node(((stringtypeParser*)child)->post()); + else if(element == "method") method(((stringtypeParser*)child)->post()); + else if(element == "load") load(((loadtypeParser*)child)->post()); + else if(element == "inport") this->inport(((inporttypeParser*)child)->post()); + else if(element == "outport") this->outport(((outporttypeParser*)child)->post()); + else if(element == "instream") instream(((inporttypeParser*)child)->post()); + else if(element == "outstream") outstream(((outporttypeParser*)child)->post()); + } + virtual void ref (const std::string& name) + { + DEBTRACE( "service_ref: " << name ) + this->_node=theRuntime->createRefNode(this->_kind,this->_name); + this->_node->setRef(name); + } + virtual void component (const std::string& name) + { + DEBTRACE( "service_component: " << name ) + this->_node=theRuntime->createCompoNode(this->_kind,this->_name); + this->_node->setRef(name); + } + virtual void node (const std::string& name) + { + DEBTRACE( "service_node: " << name ) + std::string fullname = currentProc->names.back()+name; + if(currentProc->serviceMap.count(name) != 0) + { + //ServiceNode with absolute name found + ServiceNode* n=currentProc->serviceMap[name]; + this->_node =n->createNode(this->_name); + } + else if(currentProc->serviceMap.count(fullname) != 0) + { + //ServiceNode with relative name found + //TODO: must be a short name (possible only in the same context) + ServiceNode* n=currentProc->serviceMap[fullname]; + this->_node =n->createNode(this->_name); + } + else + { + throw Exception("Unknown ServiceNode"); + } + } + virtual void method (const std::string& name) + { + DEBTRACE( "service_method: " << name ) + if(this->_node==0) + throw Exception("ServiceNode must be completely defined before defining its method"); + this->_node->setMethod(name); + } + + virtual void load (const loadon& l) + { + DEBTRACE( "service_load: " ) + if(this->_node==0) + throw Exception("ServiceNode must be completely defined before defining how to load it"); + + if(currentProc->containerMap.count(l._container) != 0) + { + //If it has already a container replace it ????? + this->_node->getComponent()->setContainer(currentProc->containerMap[l._container]); + } + else + { + std::cerr << "WARNING: Unknown container " << l._container << std::endl; + } + } + + virtual void instream (const myinport& p) + { + DEBTRACE( "service_instream" ) + DEBTRACE( p._type ) + DEBTRACE( p._name ) + if(this->_node==0) + throw Exception("ServiceNode must be completely defined before defining its ports"); + if(currentProc->typeMap.count(p._type)==0) + { + std::string msg="Unknown InPort Type: "; + msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name; + throw Exception(msg); + } + InputDataStreamPort* port; + port=this->_node->edAddInputDataStreamPort(p._name,currentProc->typeMap[p._type]); + // Set all properties for this port + std::map::const_iterator pt; + for(pt=p._props.begin();pt!=p._props.end();pt++) + port->setProperty((*pt).first,(*pt).second); + } + virtual void outstream (const myoutport& p) + { + DEBTRACE( "service_outstream" ) + DEBTRACE( p._type ) + DEBTRACE( p._name ) + if(this->_node==0) + throw Exception("ServiceNode must be completely defined before defining its ports"); + if(currentProc->typeMap.count(p._type)==0) + { + std::string msg="Unknown OutPort Type: "; + msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name; + throw Exception(msg); + } + OutputDataStreamPort* port; + port=this->_node->edAddOutputDataStreamPort(p._name,currentProc->typeMap[p._type]); + // Set all properties for this port + std::map::const_iterator pt; + for(pt=p._props.begin();pt!=p._props.end();pt++) + port->setProperty((*pt).first,(*pt).second); + } + virtual T post() + { + DEBTRACE( "service_post " << this->_node->getName() ) + this->mincount("method",1); + if(this->_state == "disabled")this->_node->exDisabledState(); + return this->_node; + } +}; +static servicetypeParser<> serviceParser; + +template +struct controltypeParser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::string element(el); + parser* pp=&main_parser; + this->maxcount("fromnode",1,element); + this->maxcount("tonode",1,element); + if(element == "fromnode")pp=&stringParser; + else if(element == "tonode")pp=&stringParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + std::string element(el); + if(element == "fromnode")fromnode(((stringtypeParser*)child)->post()); + else if(element == "tonode")tonode(((stringtypeParser*)child)->post()); + } + virtual void pre () + { + _link.clear(); + } + virtual void fromnode (const std::string& name) + { + _link.fromnode(name); + } + virtual void tonode (const std::string& name) + { + _link.tonode(name); + } + virtual void property (const myprop& prop) + { + DEBTRACE( "property_set: " << prop._name << prop._value ) + _link.setProperty(prop._name,prop._value); + } + virtual T& post() + { + mincount("fromnode",1); + mincount("tonode",1); + return _link; + } + T _link; +}; +static controltypeParser<> controlParser; + +template +struct linktypeParser: controltypeParser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::string element(el); + this->maxcount("fromnode",1,element); + this->maxcount("tonode",1,element); + this->maxcount("fromport",1,element); + this->maxcount("toport",1,element); + parser* pp=&main_parser; + if(element == "fromnode")pp=&stringParser; + else if(element == "tonode")pp=&stringParser; + else if(element == "toport")pp=&stringParser; + else if(element == "fromport")pp=&stringParser; + else if(element == "property")pp=&propertyParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + std::string element(el); + if(element == "fromnode")this->fromnode(((stringtypeParser*)child)->post()); + else if(element == "tonode")this->tonode(((stringtypeParser*)child)->post()); + else if(element == "toport")toport(((stringtypeParser*)child)->post()); + else if(element == "fromport")fromport(((stringtypeParser*)child)->post()); + else if(element == "property")this->property(((propertytypeParser*)child)->post()); + } + virtual void buildAttr(const XML_Char** attr) + { + for (int i = 0; attr[i]; i += 2) + { + if((std::string(attr[i]) == "control") + && (std::string(attr[i+1]) == "false")) + this->_link._withControl=false; + } + } + virtual void fromport (const std::string& name) + { + this->_link.fromport(name); + } + virtual void toport (const std::string& name) + { + this->_link.toport(name); + } + virtual T& post() + { + this->mincount("fromnode",1); + this->mincount("tonode",1); + this->mincount("fromport",1); + this->mincount("toport",1); + return this->_link; + } +}; +static linktypeParser<> linkParser; + +template +struct streamtypeParser: linktypeParser +{ +}; +static streamtypeParser<> streamParser; + +static std::string t4[]={"string","objref","double","int","boolean","array","struct",""}; + +/*! \brief Class for XML-RPC value parser. + * + * This class is used to parse XML data that describes a sequence in XML-RPC format + * Its XML schema is: + * + * + * + * + * + * + * + * + * + * + * + */ +struct valuetypeParser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr); + virtual void onEnd(const char *el,parser* child); + virtual void pre (){ } + virtual void int_ (const int& d) + { + std::ostringstream os; + os << "" << d<< ""; + _data=os.str(); + _v.push_back(_data); + } + virtual void boolean (const bool& d) + { + std::ostringstream os; + os << "" << d<< ""; + _data=os.str(); + _v.push_back(_data); + } + virtual void double_ (const double& d) + { + std::ostringstream os; + os << ""<< d<< ""; + _data=os.str(); + _v.push_back(_data); + } + virtual void string(const std::string& d) + { + _data=""+ d+ ""; + _v.push_back(_data); + } + virtual void objref(const std::string& d) + { + _data=""+ d+ ""; + _v.push_back(_data); + } + virtual void array (const std::string& d) + { + _v.push_back(d); + } + virtual void struct_ (const std::string& d) + { + _v.push_back(d); + } + virtual std::string post() + { + minchoice(t4,1); + std::string value=""+_v.back()+"\n"; + _v.pop_back(); + return value; + } + std::string _data; + std::vector _v; +}; +static valuetypeParser valueParser; + +/*! \brief Class for XML-RPC data parser. + * + * This class is used to parse XML data that describes a sequence in XML-RPC format + * Its XML schema is: + * + * + * + */ +struct datatypeParser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::string element(el); + parser* pp=&main_parser; + if(element == "value")pp=&valueParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + std::string element(el); + if(element == "value")value(((valuetypeParser*)child)->post()); + } + virtual void pre () + { + _datas.push_back(_data); + _data=""; + } + virtual void value (const std::string& v){ + _data=_data+v; + } + virtual std::string post() + { + mincount("value",1); + std::string d="\n"+_data+""; + _data=_datas.back(); + _datas.pop_back(); + return d; + } + std::string _data; + std::vector _datas; +}; +static datatypeParser dataParser; + +/*! \brief Class for XML-RPC member parser. + * + * This class is used to parse XML data that describes a sequence in XML-RPC format + * Its XML schema is: + * + * + * + * + */ +struct memberdatatypeParser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::string element(el); + parser* pp=&main_parser; + if(element == "name")pp=&stringParser; + else if(element == "value")pp=&valueParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + std::string element(el); + this->maxcount("name",1,element); + this->maxcount("value",1,element); + if(element == "name")name(((stringtypeParser*)child)->post()); + else if(element == "value")value(((valuetypeParser*)child)->post()); + } + virtual void pre () + { + _datas.push_back(_data); + _data=""; + } + virtual void name (const std::string& v) + { + _data=_data+""+v+""; + } + virtual void value (const std::string& v) + { + _data=_data+v; + } + virtual std::string post() + { + mincount("value",1); + mincount("name",1); + std::string d="\n"+_data+""; + _data=_datas.back(); + _datas.pop_back(); + return d; + } + std::string _data; + std::vector _datas; +}; +static memberdatatypeParser memberdataParser; + +/*! \brief Class for XML-RPC struct parser. + * + * This class is used to parse XML data that describes a sequence in XML-RPC format + * Its XML schema is: + * + * + * + */ +struct structdatatypeParser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::string element(el); + parser* pp=&main_parser; + if(element == "member")pp=&memberdataParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + std::string element(el); + if(element == "member")member(((memberdatatypeParser*)child)->post()); + } + virtual void pre () + { + _membersStack.push_back(_members); + _members=""; + } + virtual void member (const std::string& d) + { + _members=_members+d; + } + virtual std::string post() + { + mincount("member",1); + std::string value=""+_members+""; + _members=_membersStack.back(); + _membersStack.pop_back(); + return value; + } + std::string _members; + std::vector _membersStack; +}; +static structdatatypeParser structdataParser; + +/*! \brief Class for XML-RPC array parser. + * + * This class is used to parse XML data that describes a sequence in XML-RPC format + * Its XML schema is: + * + * + * + */ +struct arraytypeParser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::string element(el); + this->maxcount("data",1,element); + parser* pp=&main_parser; + if(element == "data")pp=&dataParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + std::string element(el); + if(element == "data")data(((datatypeParser*)child)->post()); + } + virtual void pre (){ } + virtual void data (const std::string& d) + { + _arrays.push_back(d); + } + virtual std::string post() + { + mincount("data",1); + std::string value=""+_arrays.back()+""; + _arrays.pop_back(); + return value; + } + std::vector _arrays; +}; +static arraytypeParser arrayParser; + + +void valuetypeParser::onStart(const XML_Char* el, const XML_Char** attr) +{ + std::string element(el); + parser* pp=&main_parser; + this->maxcount("string",1,element); + this->maxcount("objref",1,element); + this->maxcount("double",1,element); + this->maxcount("int",1,element); + this->maxcount("boolean",1,element); + this->maxcount("array",1,element); + this->maxcount("struct",1,element); + this->maxchoice(t4,1,element); + if(element == "string")pp=&stringParser; + else if(element == "objref")pp=&stringParser; + else if(element == "double")pp=&doubleParser; + else if(element == "int")pp=&intParser; + else if(element == "boolean")pp=&boolParser; + else if(element == "array")pp=&arrayParser; + else if(element == "struct")pp=&structdataParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); +} + +void valuetypeParser::onEnd(const char *el,parser* child) +{ + std::string element(el); + if(element == "string")string(((stringtypeParser*)child)->post()); + else if(element == "objref")objref(((stringtypeParser*)child)->post()); + else if(element == "double")double_(((doubletypeParser*)child)->post()); + else if(element == "int")int_(((inttypeParser*)child)->post()); + else if(element == "boolean")boolean(((booltypeParser*)child)->post()); + else if(element == "array")array(((arraytypeParser*)child)->post()); + else if(element == "struct")struct_(((structdatatypeParser*)child)->post()); +} + +struct parametertypeParser: parser +{ + virtual void onStart(const XML_Char* el, const XML_Char** attr) + { + std::string element(el); + this->maxcount("tonode",1,element); + this->maxcount("toport",1,element); + this->maxcount("value",1,element); + parser* pp=&main_parser; + if(element == "tonode")pp=&stringParser; + else if(element == "toport")pp=&stringParser; + else if(element == "value")pp=&valueParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + std::string element(el); + if(element == "tonode")tonode(((stringtypeParser*)child)->post()); + else if(element == "toport")toport(((stringtypeParser*)child)->post()); + else if(element == "value")value(((valuetypeParser*)child)->post()); + } + virtual void pre (){} + virtual void tonode (const std::string& name){ + _param._tonode=name; + } + virtual void toport (const std::string& name){ + _param._toport=name; + } + virtual void value (const std::string& name){ + _param._value=name; + } + virtual myparam& post(){ + mincount("tonode",1); + mincount("toport",1); + mincount("value",1); + return _param; + } + myparam _param; +}; +static parametertypeParser paramParser; + +static std::string t3[]={"inline","sinline","service","node","forloop","foreach","while","switch","bloc",""}; + +struct casetypeParser:parser +{ + void onStart(const XML_Char* el, const XML_Char** attr); + void onEnd(const char *el,parser* child); + virtual void buildAttr(const XML_Char** attr) + { + this->required("id",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "id")id(atoi(attr[i+1])); + } + } + virtual void pre () + { + _cnode=0; + _id=0; + } + virtual void id (const int& n) + { + DEBTRACE( "case_id: " << n ) + _id=n; + //store this level id + _idStack.push_back(_id); + //store this level name + std::stringstream temp; + if (_id <0) temp << "m" << -_id << "_"; + else temp << "p" << _id << "_"; + std::string fullname=currentProc->names.back()+temp.str(); + DEBTRACE( "case_fullname: " << fullname ) + currentProc->names.push_back(fullname); + } + virtual void property (const myprop& prop) + { + DEBTRACE( "property_set: " << prop._name << prop._value ) + } + virtual void inline_ (InlineNode* const& n) + { + _cnode=n; + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + currentProc->inlineMap[fullname]=n; + } + virtual void sinline (ServiceInlineNode* const& n) + { + _cnode=n; + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + currentProc->serviceMap[fullname]=n; + } + virtual void service (ServiceNode* const& n) + { + _cnode=n; + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + currentProc->serviceMap[fullname]=n; + } + virtual void node (InlineNode* const& n) + { + _cnode=n; + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + currentProc->inlineMap[fullname]=n; + } + virtual void forloop (ForLoop* const& n) + { + _cnode=n; + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + } + virtual void foreach (ForEachLoop* const& n) + { + _cnode=n; + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + fullname += ".splitter"; + currentProc->nodeMap[fullname]=n->getChildByShortName("splitter"); + } + virtual void while_ (WhileLoop* const& n) + { + _cnode=n; + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + } + virtual void switch_ (Switch* const& n) + { + _cnode=n; + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + } + virtual void bloc (Bloc* const& n) + { + _cnode=n; + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + } + virtual std::pair post() + { + DEBTRACE( "case_post" ) + minchoice(t3,1); + //get back this level id + _id=_idStack.back(); + _idStack.pop_back(); + //pop back this level name + currentProc->names.pop_back(); + return std::pair(_id,_cnode); + } + Node* _cnode; + int _id; + std::vector _idStack; +}; +static casetypeParser caseParser; + +struct defaultcasetypeParser:casetypeParser +{ + virtual void buildAttr(const XML_Char** attr) + { + for (int i = 0; attr[i]; i += 2) + { + DEBTRACE( attr[i] << "=" << attr[i + 1] ) + } + } + virtual void pre () + { + _id=0; + _cnode=0; + //store this level id + _idStack.push_back(_id); + //store this level name + std::string fullname=currentProc->names.back()+"default_"; + DEBTRACE( "case_fullname: " << fullname ) + currentProc->names.push_back(fullname); + } +}; +static defaultcasetypeParser defaultcaseParser; + +struct switchtypeParser:parser +{ + void onStart(const XML_Char* el, const XML_Char** attr); + void onEnd(const char *el,parser* child); + virtual void buildAttr(const XML_Char** attr) + { + this->required("name",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "state")state(attr[i+1]); + if(std::string(attr[i]) == "select")select(atoi(attr[i+1])); + } + } + virtual void pre (){_state="";} + virtual void case_ (const std::pair& p) + { + Switch* s=_cnodes.back(); + s->edSetNode(p.first,p.second); + } + virtual void default_ (const std::pair& p) + { + Switch* s=_cnodes.back(); + s->edSetDefaultNode(p.second); + } + virtual void name (const std::string& name) + { + Switch* s; + std::string fullname=currentProc->names.back()+name; + DEBTRACE( "switch_fullname: " << fullname ) + s=theRuntime->createSwitch(name); + _cnodes.push_back(s); + currentProc->names.push_back(fullname+'.'); + } + virtual void state (const std::string& state) + { + //state is an attribute (no order). It can be defined before name + //To be improved + Switch* s=_cnodes.back(); + if(_state == "disabled") + { + DEBTRACE( "Switch disabled: " << s->getName()) + s->exDisabledState(); + } + } + virtual void select (const int& s) + { + //select is an attribute + Switch* sw=_cnodes.back(); + InputPort *p=sw->edGetConditionPort(); + p->edInit(s); + } + virtual Switch* post () + { + DEBTRACE( "switch_post: " ) + Switch* sw=_cnodes.back(); + //pop back current level name and node + _cnodes.pop_back(); + currentProc->names.pop_back(); + return sw; + } + // stack to store switches in case of switch in switch + std::vector _cnodes; + std::string _state; +}; +static switchtypeParser switchParser; + +template +struct looptypeParser:parser +{ + void onStart(const XML_Char* el, const XML_Char** attr); + void onEnd(const char *el,parser* child); + virtual void buildAttr(const XML_Char** attr) + { + this->required("name",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "state")state(attr[i+1]); + } + } + virtual void pre () + { + _state=""; + _cnode=0; + } + virtual void name (const std::string& name) + { + DEBTRACE( "bloc_name: " << name ); + } + virtual void state (const std::string& name) + { + DEBTRACE( "bloc_state: " << name ); + _state=name; + } + virtual void property (const myprop& prop) + { + DEBTRACE( "property_set" << prop._name << prop._value ); + } + virtual void inline_ (InlineNode* const& n) + { + DEBTRACE( "loop_inline" << n->getName() ); + _cnode->edSetNode(n); + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + currentProc->inlineMap[fullname]=n; + } + virtual void sinline (ServiceInlineNode* const& n) + { + DEBTRACE( "loop_sinline" << n->getName() ) + _cnode->edSetNode(n); + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + currentProc->serviceMap[fullname]=n; + } + virtual void service (ServiceNode* const& n) + { + DEBTRACE( "loop_service" << n->getName() ) + _cnode->edSetNode(n); + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + currentProc->serviceMap[fullname]=n; + } + virtual void node (InlineNode* const& n) + { + DEBTRACE( "loop_node" << n->getName() ) + _cnode->edSetNode(n); + std::string fullname=currentProc->names.back()+ n->getName(); + currentProc->nodeMap[fullname]=n; + currentProc->inlineMap[fullname]=n; + } + virtual void forloop (ForLoop* const& b) + { + DEBTRACE( "loop_forloop" << b->getName() ) + _cnode->edSetNode(b); + std::string fullname=currentProc->names.back()+ b->getName(); + currentProc->nodeMap[fullname]=b; + } + virtual void foreach (ForEachLoop* const& b) + { + DEBTRACE("loop_foreach" << b->getName()) + _cnode->edSetNode(b); + std::string fullname=currentProc->names.back()+ b->getName(); + currentProc->nodeMap[fullname]=b; + fullname += ".splitter"; + currentProc->nodeMap[fullname]=b->getChildByShortName("splitter"); + } + virtual void while_ (WhileLoop* const& b) + { + DEBTRACE( "loop_while: " << b->getName() ) + _cnode->edSetNode(b); + std::string fullname=currentProc->names.back()+ b->getName(); + currentProc->nodeMap[fullname]=b; + } + virtual void switch_ (Switch* const& b) + { + DEBTRACE( "loop_switch: " << b->getName() ) + _cnode->edSetNode(b); + std::string fullname=currentProc->names.back()+ b->getName(); + currentProc->nodeMap[fullname]=b; + } + virtual void bloc (Bloc* const& b) + { + DEBTRACE( "loop_bloc " << b->getName() ) + _cnode->edSetNode(b); + std::string fullname=currentProc->names.back()+ b->getName(); + currentProc->nodeMap[fullname]=b; + } + + virtual void datalink (const mylink& l) + { + DEBTRACE( "loop_datalink: " << l.fromnode() << l.fromport() << l.tonode() << l.toport()) + std::string msg; + + //Try only relative name for from node + std::string fromname = currentProc->names.back()+l.fromnode(); + if(currentProc->nodeMap.count(fromname) == 0) + { + msg="from node " + l.fromnode() + " does not exist in data link: "; + msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")"; + throw Exception(msg); + } + //Try relative name for to node and then absolute one + std::string toname = currentProc->names.back()+l.tonode(); + if(currentProc->nodeMap.count(toname) == 0) + { + //It's not a relative name. Try an absolute one (I think it's not possible) + toname=l.tonode(); + if(currentProc->nodeMap.count(toname) == 0) + { + // The TO node does not exist -> error + msg="to node " + l.tonode() + " does not exist in data link: "; + msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")"; + throw Exception(msg); + } + } + // We only link local node and other nodes (relative or absolute name in this order) + DEBTRACE(fromname <<":"<edAddDFLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()), + currentProc->nodeMap[toname]->getInputPort(l.toport())); + else + _cnode->edAddLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()), + currentProc->nodeMap[toname]->getInputPort(l.toport())); + } + + std::string _state; + T _cnode; + std::vector _cnodes; +}; + +template +struct forlooptypeParser:looptypeParser +{ + virtual void buildAttr(const XML_Char** attr) + { + this->required("name",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "state")this->state(attr[i+1]); + if(std::string(attr[i]) == "nsteps")nsteps(atoi(attr[i+1])); + } + } + virtual void name (const std::string& name) + { + DEBTRACE( "forloop_name: " << name ); + std::string fullname=currentProc->names.back()+name; + this->_cnode=theRuntime->createForLoop(name); + currentProc->nodeMap[fullname]=this->_cnode; + this->_cnodes.push_back(this->_cnode); + currentProc->names.push_back(fullname+'.'); + _nsteps=0; + } + virtual void nsteps (const int& n) + { + DEBTRACE( "forloop_nsteps: " << n ) + if(!this->_cnode) + throw Exception("Node name must be defined before nsteps"); + InputPort *iNbTimes=this->_cnode->edGetNbOfTimesInputPort(); + iNbTimes->edInit(n); + } + virtual T post() + { + DEBTRACE( "forloop_post" ) + this->minchoice(t3,1); + T b=this->_cnode; + this->_cnodes.pop_back(); + currentProc->names.pop_back(); + this->_cnode=this->_cnodes.back(); + return b; + } + int _nsteps; +}; +static forlooptypeParser<> forloopParser; + +template +struct whilelooptypeParser:looptypeParser +{ + virtual void name (const std::string& name) + { + DEBTRACE( "while_name: " << name ) + std::string fullname=currentProc->names.back()+name; + this->_cnode=theRuntime->createWhileLoop(name); + currentProc->nodeMap[fullname]=this->_cnode; + this->_cnodes.push_back(this->_cnode); + currentProc->names.push_back(fullname+'.'); + } + virtual T post() + { + DEBTRACE( "while_post" << this->_cnode->getName() ) + this->minchoice(t3,1); + InputPort *cond=this->_cnode->edGetConditionPort(); + cond->edInit(true); + T b=this->_cnode; + this->_cnodes.pop_back(); + currentProc->names.pop_back(); + this->_cnode=this->_cnodes.back(); + return b; + } +}; +static whilelooptypeParser<> whileloopParser; + +template +struct foreachlooptypeParser:looptypeParser +{ + virtual void buildAttr(const XML_Char** attr) + { + this->required("name",attr); + this->required("type",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "state")this->state(attr[i+1]); + if(std::string(attr[i]) == "nbranch")nbranch(atoi(attr[i+1])); + if(std::string(attr[i]) == "type")datatype(attr[i+1]); + } + postAttr(); + } + virtual void pre () + { + _nbranch=0; + this->looptypeParser::pre(); + } + virtual void name (const std::string& name) + { + DEBTRACE("foreach_name: " << name) + _name=name; + _fullname=currentProc->names.back()+name; + } + virtual void nbranch (const int& n) + { + DEBTRACE("foreach_nbranch: " << n ) + _nbranch=n; + } + virtual void datatype (const std::string& type) + { + DEBTRACE("foreach_datatype: "<< type) + _datatype=type; + } + virtual void postAttr() + { + if(currentProc->typeMap.count(_datatype)==0) + { + std::stringstream msg; + msg << "Type "<< _datatype <<" does not exist"<<" ("<<__FILE__<<":"<<__LINE__<< ")"; + throw Exception(msg.str()); + } + this->_cnode=theRuntime->createForEachLoop(_name,currentProc->typeMap[_datatype]); + //set number of branches + if(_nbranch > 0)this->_cnode->edGetNbOfBranchesPort()->edInit(_nbranch); + this->_cnodes.push_back(this->_cnode); + currentProc->names.push_back(_fullname + '.'); + } + virtual T post() + { + DEBTRACE("foreach_post" << this->_cnode->getName()) + this->minchoice(t3,1); + T b=this->_cnode; + this->_cnodes.pop_back(); + currentProc->names.pop_back(); + if(this->_cnodes.size() == 0) + this->_cnode=0; + else + this->_cnode=this->_cnodes.back(); + return b; + } + int _nbranch; + std::string _fullname; + std::string _name; + std::string _datatype; +}; +static foreachlooptypeParser<> foreachloopParser; + +template +struct bloctypeParser:parser +{ + bloctypeParser():parser() + { + _orders["property"]=0; + _orders["inline"]=2; + _orders["service"]=2; + _orders["sinline"]=2; + _orders["node"]=2; + _orders["forloop"]=2; + _orders["foreach"]=2; + _orders["while"]=2; + _orders["switch"]=2; + _orders["bloc"]=2; + _orders["control"]=3; + _orders["datalink"]=3; + _orders["stream"]=3; + _orders["parameter"]=3; + } + virtual void onStart(const XML_Char* el, const XML_Char** attr); + virtual void onEnd(const char *el,parser* child); + virtual void buildAttr(const XML_Char** attr) + { + this->required("name",attr); + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "name")name(attr[i+1]); + if(std::string(attr[i]) == "state")state(attr[i+1]); + } + } + void name (const std::string& name) + { + } + virtual void state (const std::string& name){ + DEBTRACE( "bloc_state: " << name ) + _state=name; + if(_state == "disabled") + { + DEBTRACE( "Bloc disabled: " << _bloc->getName()) + _bloc->exDisabledState(); + } + } + virtual void property (const myprop& prop) + { + DEBTRACE( "property_set: " << prop._name << prop._value ) + _bloc->setProperty(prop._name,prop._value); + } + virtual void inline_ (InlineNode* const& n) + { + DEBTRACE( "bloc_pynode_set: " << n->getName() ) + _bloc->edAddChild(n); + std::string fullname = currentProc->names.back()+n->getName(); + currentProc->nodeMap[fullname]=n; + currentProc->inlineMap[fullname]=n; + } + virtual void sinline (ServiceInlineNode* const& n) + { + DEBTRACE( "bloc_sinline: " << n->getName() ) + _bloc->edAddChild(n); + std::string fullname = currentProc->names.back()+n->getName(); + currentProc->nodeMap[fullname]=n; + currentProc->serviceMap[fullname]=n; + } + virtual void service (ServiceNode* const& n) + { + DEBTRACE( "bloc_service_set: " << n->getName() ) + _bloc->edAddChild(n); + std::string fullname = currentProc->names.back()+n->getName(); + currentProc->nodeMap[fullname]=n; + currentProc->serviceMap[fullname]=n; + } + virtual void node (InlineNode* const& n) + { + DEBTRACE( "bloc_node_set: " << n->getName() ) + _bloc->edAddChild(n); + std::string fullname = currentProc->names.back()+n->getName(); + DEBTRACE( "bloc_node_set fullname = " << fullname ) + currentProc->nodeMap[fullname]=n; + currentProc->inlineMap[fullname]=n; + } + virtual void forloop (ForLoop* const& b) + { + DEBTRACE( "bloc_forloop_set: " << b->getName() ) + _bloc->edAddChild(b); + std::string fullname = currentProc->names.back()+b->getName(); + currentProc->nodeMap[fullname]=b; + } + virtual void foreach (ForEachLoop* const& b) + { + DEBTRACE( "bloc_foreach_set: " << b->getName() ) + _bloc->edAddChild(b); + std::string fullname = currentProc->names.back()+b->getName(); + currentProc->nodeMap[fullname]=b; + fullname += ".splitter"; + currentProc->nodeMap[fullname]=b->getChildByShortName("splitter"); + } + virtual void while_ (WhileLoop* const& b) + { + DEBTRACE( "bloc_while_set: " << b->getName() ) + _bloc->edAddChild(b); + std::string fullname = currentProc->names.back()+b->getName(); + currentProc->nodeMap[fullname]=b; + } + virtual void switch_ (Switch* const& b) + { + DEBTRACE( "bloc_switch_set: " << b->getName() ) + _bloc->edAddChild(b); + std::string fullname = currentProc->names.back()+b->getName(); + currentProc->nodeMap[fullname]=b; + } + virtual void bloc (Bloc* const& b) + { + DEBTRACE( "bloc_bloc_set: " << b->getName() ) + _bloc->edAddChild(b); + std::string fullname=currentProc->names.back()+ b->getName(); + currentProc->nodeMap[fullname]=b; + } + virtual void control (const mycontrol& l) + { + DEBTRACE( "bloc_control_set: " << l.fromnode() << " "<< l.tonode() ) + std::string msg; + + if(currentProc->nodeMap.count(currentProc->names.back()+l.fromnode()) == 0) + { + msg="from node " + l.fromnode() + " does not exist in control link: "; + msg=msg+l.fromnode()+"->"+l.tonode(); + msg=msg+ " context: "+currentProc->names.back(); + throw Exception(msg); + } + if(currentProc->nodeMap.count(currentProc->names.back()+l.tonode()) == 0) + { + msg="to node " + l.tonode() + " does not exist in control link: "; + msg=msg+l.fromnode()+"->"+l.tonode(); + msg=msg+ " context: "+currentProc->names.back(); + throw Exception(msg); + } + // We only link local nodes + _bloc->edAddCFLink(currentProc->nodeMap[currentProc->names.back()+l.fromnode()], + currentProc->nodeMap[currentProc->names.back()+l.tonode()]); + } + virtual void datalink (const mylink& l) + { + DEBTRACE( "bloc_datalink_set: "<"<names.back()+l.fromnode(); + if(currentProc->nodeMap.count(fromname) == 0) + { + msg="from node " + l.fromnode() + " does not exist in data link: "; + msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")"; + throw Exception(msg); + } + //Try relative name for to node and then absolute one + std::string toname = currentProc->names.back()+l.tonode(); + if(currentProc->nodeMap.count(toname) == 0) + { + //It's not a relative name. Try an absolute one (I think it's not possible) + toname=l.tonode(); + if(currentProc->nodeMap.count(toname) == 0) + { + // The TO node does not exist -> error + msg="to node " + l.tonode() + " does not exist in data link: "; + msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")"; + throw Exception(msg); + } + } + // We only link local node and other nodes (relative or absolute name in this order) + DEBTRACE(fromname <<":"<edAddDFLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()), + currentProc->nodeMap[toname]->getInputPort(l.toport())); + else + _bloc->edAddLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()), + currentProc->nodeMap[toname]->getInputPort(l.toport())); + } + virtual void stream (const mystream& l) + { + DEBTRACE( "bloc_stream_set: " << l.fromnode() << l.fromport() << l.tonode() << l.toport() ) + std::string msg; + std::string fromname = currentProc->names.back()+l.fromnode(); + std::string toname = currentProc->names.back()+l.tonode(); + //only relative names + if(currentProc->nodeMap.count(fromname) == 0) + { + msg="from node " + l.fromnode() + " does not exist in stream link: "; + msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")"; + throw Exception(msg); + } + if(currentProc->nodeMap.count(toname) == 0) + { + msg="to node " + l.tonode() + " does not exist in stream link: "; + msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")"; + throw Exception(msg); + } + OutputDataStreamPort* pout=currentProc->nodeMap[fromname]->getOutputDataStreamPort(l.fromport()); + InputDataStreamPort* pin=currentProc->nodeMap[toname]->getInputDataStreamPort(l.toport()); + _bloc->edAddLink(pout,pin); + // Set all properties for this link + std::map::const_iterator pt; + for(pt=l._props.begin();pt!=l._props.end();pt++) + { + pin->setProperty((*pt).first,(*pt).second); + pout->setProperty((*pt).first,(*pt).second); + } + } + virtual void parameter (const myparam& p) + { + DEBTRACE( "++++++++++++++++++++Parameter+++++++++++++++++++++" ) + std::string msg; + std::string toname = currentProc->names.back()+p._tonode; + if(currentProc->nodeMap.count(toname) == 0) + { + msg="to node " + p._tonode + " does not exist in parameter: "; + msg=msg+"->"+p._tonode+"("+p._toport+")"; + throw Exception(msg); + } + InputPort* inport=currentProc->nodeMap[toname]->getInputPort(p._toport); + //We don't know the parameter type. So we try to initialize the port + //with the value. If it's not the right type, edInit throws an exception + //std::cerr << "----------------------------- " << p.value.c_str() << std::endl; + inport->edInit("XML",p._value.c_str()); + DEBTRACE( "++++++++++++++++++++End parameter+++++++++++++++++++++" ) + } + T post() + { + DEBTRACE( "bloc_post" ) + currentProc->names.pop_back(); + T b=_bloc; + _blocs.pop_back(); + if(_blocs.empty()) + _bloc=NULL; + else + _bloc=_blocs.back(); + return b; + } + T _bloc; + std::string _state; + std::vector _blocs; +}; +static bloctypeParser<> blocParser; + +template <> +void bloctypeParser::name (const std::string& name) +{ + DEBTRACE( "bloc_name: " << name ) + std::string fullname=currentProc->names.back()+name; + _bloc=theRuntime->createBloc(name); + _blocs.push_back(_bloc); + currentProc->names.push_back(fullname+'.'); +} + +void switchtypeParser::onStart(const XML_Char* el, const XML_Char** attr) +{ + DEBTRACE( "switchtypeParser::onStart: " << el ) + std::string element(el); + this->maxcount("default",1,element); + parser* pp=&main_parser; + if(element == "case")pp=&caseParser; + else if(element == "default")pp=&defaultcaseParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); +} +void switchtypeParser::onEnd(const char *el,parser* child) +{ + DEBTRACE( "switchtypeParser::onEnd: " << el ) + std::string element(el); + if(element == "case")case_(((casetypeParser*)child)->post()); + else if(element == "default")default_(((defaultcasetypeParser*)child)->post()); +} + + +void casetypeParser::onStart(const XML_Char* el, const XML_Char** attr) +{ + DEBTRACE( "casetypeParser::onStart: " << el ) + std::string element(el); + this->maxcount("inline",1,element); + this->maxcount("sinline",1,element); + this->maxcount("service",1,element); + this->maxcount("node",1,element); + this->maxcount("forloop",1,element); + this->maxcount("foreach",1,element); + this->maxcount("while",1,element); + this->maxcount("switch",1,element); + this->maxcount("bloc",1,element); + this->maxchoice(t3,1,element); + parser* pp=&main_parser; + if(element == "property")pp=&propertyParser; + else if(element == "inline")pp=&inlineParser; + else if(element == "sinline")pp=&sinlineParser; + else if(element == "service")pp=&serviceParser; + else if(element == "node")pp=&nodeParser; + else if(element == "forloop")pp=&forloopParser; + else if(element == "foreach")pp=&foreachloopParser; + else if(element == "while")pp=&whileloopParser; + else if(element == "switch")pp=&switchParser; + else if(element == "bloc")pp=&blocParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); +} + +void casetypeParser::onEnd(const char *el,parser* child) +{ + DEBTRACE( "casetypeParser::onEnd: " << el ) + std::string element(el); + if(element == "property")property(((propertytypeParser*)child)->post()); + else if(element == "inline")inline_(((inlinetypeParser<>*)child)->post()); + else if(element == "sinline")sinline(((sinlinetypeParser<>*)child)->post()); + else if(element == "service")service(((servicetypeParser<>*)child)->post()); + else if(element == "node")node(((nodetypeParser<>*)child)->post()); + else if(element == "forloop")forloop(((forlooptypeParser<>*)child)->post()); + else if(element == "foreach")foreach(((foreachlooptypeParser<>*)child)->post()); + else if(element == "while")while_(((whilelooptypeParser<>*)child)->post()); + else if(element == "switch")switch_(((switchtypeParser*)child)->post()); + else if(element == "bloc")bloc(((bloctypeParser<>*)child)->post()); +} + +template +void looptypeParser::onStart(const XML_Char* el, const XML_Char** attr) +{ + DEBTRACE( "looptypeParser::onStart: " << el ) + std::string element(el); + this->maxcount("inline",1,element); + this->maxcount("sinline",1,element); + this->maxcount("service",1,element); + this->maxcount("node",1,element); + this->maxcount("forloop",1,element); + this->maxcount("foreach",1,element); + this->maxcount("while",1,element); + this->maxcount("switch",1,element); + this->maxcount("bloc",1,element); + this->maxchoice(t3,1,element); + parser* pp=&main_parser; + if(element == "property")pp=&propertyParser; + else if(element == "inline")pp=&inlineParser; + else if(element == "sinline")pp=&sinlineParser; + else if(element == "service")pp=&serviceParser; + else if(element == "node")pp=&nodeParser; + else if(element == "forloop")pp=&forloopParser; + else if(element == "foreach")pp=&foreachloopParser; + else if(element == "while")pp=&whileloopParser; + else if(element == "switch")pp=&switchParser; + else if(element == "bloc")pp=&blocParser; + else if(element == "datalink")pp=&linkParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); +} +template +void looptypeParser::onEnd(const char *el,parser* child) +{ + DEBTRACE( "looptypeParser::onEnd: " << el ) + std::string element(el); + if(element == "property")property(((propertytypeParser*)child)->post()); + else if(element == "inline")inline_(((inlinetypeParser<>*)child)->post()); + else if(element == "sinline")sinline(((sinlinetypeParser<>*)child)->post()); + else if(element == "service")service(((servicetypeParser<>*)child)->post()); + else if(element == "node")node(((nodetypeParser<>*)child)->post()); + else if(element == "forloop")forloop(((forlooptypeParser<>*)child)->post()); + else if(element == "foreach")foreach(((foreachlooptypeParser<>*)child)->post()); + else if(element == "while")while_(((whilelooptypeParser<>*)child)->post()); + else if(element == "switch")switch_(((switchtypeParser*)child)->post()); + else if(element == "bloc")bloc(((bloctypeParser<>*)child)->post()); + else if(element == "datalink") datalink(((linktypeParser<>*)child)->post()); +} + +template +void bloctypeParser::onStart(const XML_Char* el, const XML_Char** attr) +{ + DEBTRACE( "bloctypeParser::onStart: " << el ) + std::string element(el); + checkOrder(element); + parser* pp=&main_parser; + if(element == "property")pp=&propertyParser; + else if(element == "inline")pp=&inlineParser; + else if(element == "sinline")pp=&sinlineParser; + else if(element == "service")pp=&serviceParser; + else if(element == "node")pp=&nodeParser; + else if(element == "forloop")pp=&forloopParser; + else if(element == "foreach")pp=&foreachloopParser; + else if(element == "while")pp=&whileloopParser; + else if(element == "switch")pp=&switchParser; + else if(element == "bloc")pp=&blocParser; + else if(element == "control")pp=&controlParser; + else if(element == "datalink")pp=&linkParser; + else if(element == "stream")pp=&streamParser; + else if(element == "parameter")pp=¶mParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); +} +template +void bloctypeParser::onEnd(const char *el,parser* child) +{ + DEBTRACE( "bloctypeParser::onEnd: " << el ) + std::string element(el); + if(element == "property")property(((propertytypeParser*)child)->post()); + else if(element == "inline")inline_(((inlinetypeParser<>*)child)->post()); + else if(element == "sinline")sinline(((sinlinetypeParser<>*)child)->post()); + else if(element == "service")service(((servicetypeParser<>*)child)->post()); + else if(element == "node")node(((nodetypeParser<>*)child)->post()); + else if(element == "forloop")forloop(((forlooptypeParser<>*)child)->post()); + else if(element == "foreach")foreach(((foreachlooptypeParser<>*)child)->post()); + else if(element == "while")while_(((whilelooptypeParser<>*)child)->post()); + else if(element == "switch")switch_(((switchtypeParser*)child)->post()); + else if(element == "bloc")bloc(((bloctypeParser<>*)child)->post()); + else if(element == "control") control(((controltypeParser<>*)child)->post()); + else if(element == "datalink") datalink(((linktypeParser<>*)child)->post()); + else if(element == "stream") stream(((streamtypeParser<>*)child)->post()); + else if(element == "parameter") parameter(((parametertypeParser*)child)->post()); +} + +template +struct proctypeParser:bloctypeParser +{ + proctypeParser():bloctypeParser() + { + this->_orders["type"]=1; + this->_orders["sequence"]=1; + this->_orders["objref"]=1; + } + void onStart(const XML_Char* el, const XML_Char** attr) + { + DEBTRACE( "proctypeParser::onStart: " << el ) + std::string element(el); + this->checkOrder(element); + parser* pp=&main_parser; + if(element == "property")pp=&propertyParser; + else if(element == "type")pp=&typeParser; + else if(element == "sequence")pp=&seqParser; + else if(element == "objref")pp=&objParser; + else if(element == "struct")pp=&structParser; + else if(element == "container")pp=&containerParser; + else if(element == "inline")pp=&inlineParser; + else if(element == "sinline")pp=&sinlineParser; + else if(element == "service")pp=&serviceParser; + else if(element == "node")pp=&nodeParser; + else if(element == "forloop")pp=&forloopParser; + else if(element == "foreach")pp=&foreachloopParser; + else if(element == "while")pp=&whileloopParser; + else if(element == "switch")pp=&switchParser; + else if(element == "bloc")pp=&blocParser; + else if(element == "control")pp=&controlParser; + else if(element == "datalink")pp=&linkParser; + else if(element == "stream")pp=&streamParser; + else if(element == "parameter")pp=¶mParser; + else + { + // OCC: san -- Allow external parsers for handling of unknown elements + // and attributes. This capability is used by YACS GUI to read + // graph presentation data + if ( this->_defaultParsersMap ) + { + if((this->_defaultParsersMap)->count(element) != 0) + { + pp=(*(this->_defaultParsersMap))[element]; + } + else + { + std::cerr << "There is no parser for this element type. It will be ignored!" << std::endl; + } + } + } + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + DEBTRACE( "proctypeParser::onEnd: " << el ) + std::string element(el); + if(element == "property")this->property(((propertytypeParser*)child)->post()); + else if(element == "type")type(((typetypeParser*)child)->post()); + else if(element == "sequence")sequence(((seqtypeParser*)child)->post()); + else if(element == "objref")objref(((objtypeParser*)child)->post()); + else if(element == "struct")struct_(((structtypeParser*)child)->post()); + else if(element == "container")container(((containertypeParser*)child)->post()); + else if(element == "inline")this->inline_(((inlinetypeParser<>*)child)->post()); + else if(element == "sinline")this->sinline(((sinlinetypeParser<>*)child)->post()); + else if(element == "service")this->service(((servicetypeParser<>*)child)->post()); + else if(element == "node")this->node(((nodetypeParser<>*)child)->post()); + else if(element == "forloop")this->forloop(((forlooptypeParser<>*)child)->post()); + else if(element == "foreach")this->foreach(((foreachlooptypeParser<>*)child)->post()); + else if(element == "while")this->while_(((whilelooptypeParser<>*)child)->post()); + else if(element == "switch")this->switch_(((switchtypeParser*)child)->post()); + else if(element == "bloc")this->bloc(((bloctypeParser<>*)child)->post()); + else if(element == "control") this->control(((controltypeParser<>*)child)->post()); + else if(element == "datalink") this->datalink(((linktypeParser<>*)child)->post()); + else if(element == "stream") this->stream(((streamtypeParser<>*)child)->post()); + else if(element == "parameter") this->parameter(((parametertypeParser*)child)->post()); + } + virtual void buildAttr(const XML_Char** attr) + { + for (int i = 0; attr[i]; i += 2) + { + if(std::string(attr[i]) == "state")this->state(attr[i+1]); + } + } + virtual void pre () + { + std::string name("proc"); + currentProc=theRuntime->createProc(name); + this->_bloc=currentProc; + currentProc->names.push_back(""); + } + virtual void type (const mytype& t) + { + DEBTRACE( "type_set" ) + currentProc->typeMap[t._name]=currentProc->createType(t._name,t._kind); + } + virtual void sequence (TypeCode* const& t) + { + DEBTRACE( "sequence_set" ) + currentProc->typeMap[t->name()]=t; + } + virtual void objref (TypeCode* const& t) + { + DEBTRACE( "objref_set" ) + currentProc->typeMap[t->name()]=t; + } + virtual void struct_ (TypeCode* const& t) + { + DEBTRACE( "struct_set" ) + currentProc->typeMap[t->name()]=t; + } + virtual void container (const mycontainer& t) + { + DEBTRACE( "container_set: " << t._name ) + std::vector::const_iterator iter; + for(iter=t._machs.begin();iter!=t._machs.end();iter++) + { + DEBTRACE( "machine name: " << (*iter)._name ) + } + + if(currentProc->containerMap.count(t._name) == 0) + { + YACS::ENGINE::Container* cont=theRuntime->createContainer(); + // Set all properties for this container + std::map::const_iterator pt; + for(pt=t._props.begin();pt!=t._props.end();pt++) + cont->setProperty((*pt).first,(*pt).second); + currentProc->containerMap[t._name]=cont; + } + else + { + std::cerr << "Warning: container " << t._name << " already defined. It will be ignored" << std::endl; + } + } + + T post(){return this->_bloc;} +}; +static proctypeParser<> procParser; + +struct roottypeParser:parser +{ + void onStart(const XML_Char* el, const XML_Char** attr) + { + DEBTRACE( "roottypeParser::onStart: " << el ) + std::string element(el); + parser* pp=&main_parser; + if(element == "proc")pp=&procParser; + XML_SetUserData(p,pp); + sp.push(pp); + pp->init(); + pp->pre(); + pp->buildAttr(attr); + } + virtual void onEnd(const char *el,parser* child) + { + DEBTRACE( "roottypeParser::onEnd: " << el ) + std::string element(el); + if(element == "proc")proc(((proctypeParser<>*)child)->post()); + } + virtual void proc (Proc* const& b) + { + DEBTRACE( "root_proc_set" << b->getName() ) + _proc=b; + } + Proc* _proc; +}; +static roottypeParser rootParser; + +YACSLoader::YACSLoader() +{ + theRuntime = getRuntime(); +} + +Proc* YACSLoader::load(const char * file) +{ + FILE* fin=fopen(file,"r"); + if (! fin) + { + std::cerr << "Couldn't open schema file" << std::endl; + throw std::invalid_argument("Couldn't open schema file"); + //throw Exception("Couldn't open schema file"); + } + + p = XML_ParserCreate(NULL); + if (! p) + { + std::cerr << "Couldn't allocate memory for parser" << std::endl; + throw Exception("Couldn't allocate memory for parser"); + } + XML_SetElementHandler(p, parser::start,parser::end); + XML_SetCharacterDataHandler(p,parser::charac ); + XML_SetUserData(p,&rootParser); + sp.push(&rootParser); + // OCC: san -- Allow external parsers for handling of unknown elements + // and attributes. This capability is used by YACS GUI to read + // graph presentation data + if ( !_defaultParsersMap.empty() ) + procParser._defaultParsersMap = &_defaultParsersMap; + + try + { + for (;;) + { + int done; + int len; + + len = fread(Buff, 1, BUFFSIZE, fin); + if (ferror(fin)) + { + std::cerr << "Read error" << std::endl; + throw Exception("Read error"); + } + done = feof(fin); + + if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR) + { + throw Exception(XML_ErrorString(XML_GetErrorCode(p))); + } + + if (done) + break; + } + XML_ParserFree (p); + p=0; + return rootParser._proc; + } + catch(Exception& e) + { + //get line number from XML parser + std::cerr << "Error at line: " << XML_GetCurrentLineNumber(p) << std::endl; + delete currentProc; + currentProc=0; + throw e; + } +} + +YACSLoader::~YACSLoader() +{ +} diff --git a/src/yacsloader/parsers.hxx b/src/yacsloader/parsers.hxx new file mode 100644 index 000000000..4ae103547 --- /dev/null +++ b/src/yacsloader/parsers.hxx @@ -0,0 +1,88 @@ +#ifndef _PARSERS_HXX_ +#define _PARSERS_HXX_ + +#include + +#include + +#include "Proc.hxx" + + +struct parser +{ + parser():_level(0),_defaultParsersMap(0) + { + _counts=new std::map; + } + virtual ~parser(); + + virtual void SetUserDataAndPush(parser* pp); + virtual void onStart(const XML_Char *el, const XML_Char** attr); + static void XMLCALL start(void *data, const XML_Char* el, const XML_Char** attr); + + virtual void onEnd(const XML_Char *el,parser* child); + + static void XMLCALL end(void *data, const char *el); + + virtual void charData(const XML_Char *s, int len); + + static void XMLCALL charac(void *data, const XML_Char *s, int len); + + virtual void end (); + + virtual void init (); + + virtual void incrCount(const XML_Char *el); + + virtual void checkOrder(std::string& el); + + virtual void maxcount(std::string name, int max, std::string& el); + + virtual void mincount(std::string name,int min ); + + virtual void maxchoice(std::string *names, int max, std::string& el); + + virtual void minchoice(std::string *names, int min); + + virtual void pre(){_content="";}; + virtual void required(const std::string& name, const XML_Char** attr); + + virtual void buildAttr(const XML_Char** attr); + + template + T post() + { + std::cerr << "post" << std::endl; + } + + std::string _content; + std::map *_counts; + std::map _orders; + int _orderState; + int _level; + std::stack*> _stackCount; + std::stack _stackOrder; + // OCC: san -- Allow external parsers for handling of unknown elements + // and attributes. This capability is used by YACS GUI to read + // graph presentation data + std::map *_defaultParsersMap; +}; + +static parser main_parser; + + +namespace YACS +{ + class YACSLoader + { + public: + YACSLoader(); + virtual ~YACSLoader(); + virtual YACS::ENGINE::Proc* load(const char *); + + protected: + std::map _defaultParsersMap; + }; +} + +#endif diff --git a/src/yacsloader/resume.cxx b/src/yacsloader/resume.cxx new file mode 100644 index 000000000..8561ad634 --- /dev/null +++ b/src/yacsloader/resume.cxx @@ -0,0 +1,113 @@ + +#include "RuntimeSALOME.hxx" +#include "Proc.hxx" +#include "Exception.hxx" +#include "Executor.hxx" +#include "parsers.hxx" +#include "VisitorSaveState.hxx" +#include "LoadState.hxx" + + +#include +#include + +using YACS::YACSLoader; +using namespace YACS::ENGINE; +using namespace std; + + +int +main (int argc, char* argv[]) +{ + if (argc != 3 && argc != 4) + { + cerr << "usage: " << argv[0] << " [--display=n] schema.xml state.xml" << endl; + return 1; + } + int display=0; + int argfile=1; + int argState=2; + if(argc == 4) + { + argfile=2; + argState=3; + if(std::string(argv[1]) == "--display=1") + display=1; + else if(std::string(argv[1]) == "--display=2") + display=2; + else if(std::string(argv[1]) == "--display=3") + display=3; + } + + RuntimeSALOME::setRuntime(); + + YACSLoader loader; + Executor executor; + + try + { + Proc* p=loader.load(argv[argfile]); + p->init(); + p->exUpdateState(); + stateParser* rootParser = new stateParser(); + stateLoader myStateLoader(rootParser, p); + myStateLoader.parse(argv[argState]); + + std::ofstream f("toto"); + p->writeDot(f); + f.close(); + cerr << "+++++++++++++++++++ start calculation +++++++++++++++++++" << endl; + executor.RunW(p, display, false); + cerr << "+++++++++++++++++++ end calculation +++++++++++++++++++" << endl; + std::ofstream g("titi"); + p->writeDot(g); + g.close(); + YACS::ENGINE::VisitorSaveState vst(p); + vst.openFileDump("dumpState.xml"); + p->accept(&vst); + vst.closeFileDump(); + delete p; + YACS::ENGINE::getRuntime()->fini(); + return 0; + } + catch (YACS::Exception& e) + { + cerr << "Caught a YACS exception" << endl; + cerr << e.what() << endl; + YACS::ENGINE::getRuntime()->fini(); + return 1; + } + catch (const std::ios_base::failure&) + { + cerr << "Caught an io failure exception" << endl; + return 1; + } + catch(CORBA::SystemException& ex) + { + cerr << "Caught a CORBA::SystemException." ; + CORBA::Any tmp; + tmp <<= ex; + CORBA::TypeCode_var tc = tmp.type(); + const char *p = tc->name(); + if ( *p != '\0' ) + cerr <id(); + cerr << endl; + return 1; + } + catch(omniORB::fatalException& fe) + { + cerr << "Caught omniORB::fatalException:" << endl; + cerr << " file: " << fe.file() << endl; + cerr << " line: " << fe.line() << endl; + cerr << " mesg: " << fe.errmsg() << endl; + return 1; + } + catch(...) + { + cerr << "Caught unknown exception." << endl; + return 1; + } +} + diff --git a/src/yacsloader/samples/aschema.xml b/src/yacsloader/samples/aschema.xml new file mode 100644 index 000000000..100a549c4 --- /dev/null +++ b/src/yacsloader/samples/aschema.xml @@ -0,0 +1,447 @@ + + + + + + + + + + + + Obj + + + + + + geom + + + + + + geom + mesh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + def f(p1): + p1= p1+10. + return p1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoObjectVec + + + + + corbaname:rir:#test.my_context/Echo.Object + echoC + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDoubleVec + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDoubleVecVec + + + + + corbaname:rir:#test.my_context/Echo.Object + echoErrorLong + + + + + corbaname:rir:#test.my_context/Echo.Object + echoString + + + + + corbaname:rir:#test.my_context/Echo.Object + echoC + + + + + corbaname:rir:#test.my_context/Echo.Object + echoObj2 + + + + + corbaname:rir:#test.my_context/Echo.Object + echoC + + + + + corbaname:rir:#test.my_context/Echo.Object + echoObj2 + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + c1 n2 + c1.n2p1 + n2 p1 + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoErrorDouble + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + c1 n1 + n1 n2 + c1.n1p1 + n1 p1 + n1p1 + n2 p1 + + + node99 node98 + node1 node11 + node11 node12 + node2 node3 + node2 node31 + node2 node32 + node32 node33 + node33 node34 + node34 node35 + node3 node4 + node4 c0 + node4 c1 + node41 node42 + c0 node5 + node5 node61 + node5 node62 + c1 node63 + node13 node14 + node4 node14 + node35 node14 + node46 node47 + node47 node48 + node43 node44 + node44 node45 + + node99p1 + node98 p1 + node4p1 + c1.c1.n2 p1 + node4p1 + c0.c1.n1 p1 + + node13 p1 + node14 p1 + + + node2 p1 + node3 p1 + + + node2 p1 + node31 p1 + + + node2 p1 + node32 p1 + + + node33 p2 + node34 p1 + + + node34 p2 + node35 p1 + + + node3 p1 + node4 p1 + + + c0.n1p1 + node5 p1 + + + node5p1 + node61 p1 + + + node5p1 + node62 p1 + + + c1.n2p1 + node63 p1 + + + + node99 p1 + + corbaname:rir:#test.my_context/Obj.Object + corbaname:rir:#test.my_context/Obj.Object + + + + node33 obj + corbaname:rir:#test.my_context/Echo.Object + + + node33 p1 + corbaname:rir:#test.my_context/C.Object + + + node45 p1 + corbaname:rir:#test.my_context/C.Object + + + node46 p1 + corbaname:rir:#test.my_context/Obj.Object + + + node47 p1 + corbaname:rir:#test.my_context/C.Object + + + node48 p1 + corbaname:rir:#test.my_context/C.Object + + + node97 p1 + corbaname:rir:#test.my_context/C.Object + + + node1 p1 + 23 + + + node11 p1 + coucou + + + node4 p1 + 23 + + + node44 p1 + chris + + + node43 p1 + 23 + + + node3 p1 + 23 + + + node61 p1 + 23 + + + node12 p1 + + 23 + 45 + + + + node41 p1 + + 23 + 45 + + + + node13 p1 + + + 23.45 + 66 + + + 3.142 + 55 + + + + + node42 p1 + + + 23.45 + 66 + + + 3.142 + 55 + + + + diff --git a/src/yacsloader/samples/bid.xml b/src/yacsloader/samples/bid.xml new file mode 100644 index 000000000..70a402650 --- /dev/null +++ b/src/yacsloader/samples/bid.xml @@ -0,0 +1,46 @@ + + + + + + + + + def f(): + return "coucou" + + + + + + + def f(): + return "coucou" + + + + + + + def f(p1): + print p1;p1=2*p1 + return p1 + + + + + + node5 b2 + + + + + + + + + b1.b2.node1 p1 + coucou + + + diff --git a/src/yacsloader/samples/bloc1.xml b/src/yacsloader/samples/bloc1.xml new file mode 100644 index 000000000..6a025d8e3 --- /dev/null +++ b/src/yacsloader/samples/bloc1.xml @@ -0,0 +1,46 @@ + + + + + + + + + def f(): + return "coucou" + + + + + + + def f(): + return "coucou" + + + + + + + def f(p1): + print p1;p1=2*p1 + return p1 + + + + + + node1 b2 + + + + + + + + + b1.b2.node1 p1 + coucou + + + diff --git a/src/yacsloader/samples/bloc2.xml b/src/yacsloader/samples/bloc2.xml new file mode 100644 index 000000000..362fa01f9 --- /dev/null +++ b/src/yacsloader/samples/bloc2.xml @@ -0,0 +1,80 @@ + + + + + + + + + def f(): + return "coucou node1" + + + + + + def f(): + return "coucou node2" + + + + + + + def f(): + return "coucou b1.node1" + + + + + + def f(): + return "coucou b1.node2" + + + + + + + def f(p1): + print p1;p1=2*p1 + print "coucou b1.b2.node1" + return p1 + + + + + + + def f(): + return "coucou b1.b2.node2" + + + + + + + def f(): + return "coucou b1.b2.loop1.node1" + + + + + loop1 node2 + + node1 b2 + b2 node2 + + + + b1 node2 + + + + + + b1.b2.node1 p1 + coucou + + + diff --git a/src/yacsloader/samples/bloc3.xml b/src/yacsloader/samples/bloc3.xml new file mode 100644 index 000000000..3b9f6e9e8 --- /dev/null +++ b/src/yacsloader/samples/bloc3.xml @@ -0,0 +1,56 @@ + + + + + + + + + + def f(): + return "coucou" + + + + + + def f(): + return "coucou node2" + + + + + + + def f(): + return "coucou" + + + + + + + def f(p1): + print p1;p1=2*p1 + return p1 + + + + + + node1 b2 + + + + b1 node2 + + + + + + b1.b2.node1 p1 + coucou + + + diff --git a/src/yacsloader/samples/bloc4.xml b/src/yacsloader/samples/bloc4.xml new file mode 100644 index 000000000..146a55e9f --- /dev/null +++ b/src/yacsloader/samples/bloc4.xml @@ -0,0 +1,67 @@ + + + + + + + + + + def f(): + return "coucou" + + + + + + def f(): + s1 = [3.14, 0.5, 1.29] + return s1 + + + + + + + def f(): + return "coucou" + + + + + + def f(s1): + print s1 + return s1 + + + + + + + + def f(p1): + print p1;p1=2*p1 + return p1 + + + + + + node1 b2 + + + + node2 b1 + + + node2s1 + b1.node2 s1 + + + + b1.b2.node1 p1 + coucou + + + diff --git a/src/yacsloader/samples/bool1.xml b/src/yacsloader/samples/bool1.xml new file mode 100644 index 000000000..99089c73c --- /dev/null +++ b/src/yacsloader/samples/bool1.xml @@ -0,0 +1,278 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + xmlsh + ./xmlrun.sh + echo + + + + + corbaname:rir:#test.my_context/Echo.Object + echoBoolVec + + + + + + + + + + + xmlsh + ./xmlrun.sh + echo + + + + + corbaname:rir:#test.my_context/Echo.Object + echoBoolVec + + + + + + + + + + + + DSCCODC + prun + + + + + + + + + + DSCCODD + prun + + + + + + + + + + node0 node1 + node0 node2 + + + node0n + node1 niter + + + node0n + node2 niter + + + + + + node2 STP_EN + node1 ETP_EN + + + + node1 STP_EN + node2 ETP_EN + + + + diff --git a/src/yacsloader/samples/calcium1.xml b/src/yacsloader/samples/calcium1.xml new file mode 100644 index 000000000..1b417e210 --- /dev/null +++ b/src/yacsloader/samples/calcium1.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + DSCCODC + trun + + + + + + DSCCODD + trun + + + + + + node4 STP_RE + node3 ETP_RE + + + node3 STP_RE + node4 ETP_RE + + + node0 node3 + node0 node4 + + + node0n + node3 niter + + + node0n + node4 niter + + + + + diff --git a/src/yacsloader/samples/calcium2.xml b/src/yacsloader/samples/calcium2.xml new file mode 100644 index 000000000..74e64f964 --- /dev/null +++ b/src/yacsloader/samples/calcium2.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + DSCCODC + prun + + + + + + DSCCODD + prun + + + + + + node1 + trun + + + + + + node2 + trun + + + + + + node4 STP_RE + node3 ETP_RE + + + node3 STP_RE + node4 ETP_RE + + + node0 node1 + node0 node2 + node1 node3 + node2 node4 + + + node0n + node1 niter + + + node0n + node2 niter + + + node0n + node3 niter + + + node0n + node4 niter + + + + + + node2 STP_EN + node1 ETP_EN + + + node1 STP_EN + node2 ETP_EN + + + diff --git a/src/yacsloader/samples/calcium3.xml b/src/yacsloader/samples/calcium3.xml new file mode 100644 index 000000000..92bd44be6 --- /dev/null +++ b/src/yacsloader/samples/calcium3.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + DSCCODC + prun + + + + + + DSCCODD + prun + + + + + + node2 STP_EN + node1 ETP_EN + + + node1 STP_EN + node2 ETP_EN + + + + + + a.node1 + trun + + + + + + a.node2 + trun + + + + + + node4 STP_RE + node3 ETP_RE + + + node3 STP_RE + node4 ETP_RE + + + + + node0 a + a b + + + + node0n + a.node1 niter + + + node0n + a.node2 niter + + + node0n + b.node3 niter + + + node0n + b.node4 niter + + + + + + diff --git a/src/yacsloader/samples/calcium4.xml b/src/yacsloader/samples/calcium4.xml new file mode 100644 index 000000000..cbb9bbe25 --- /dev/null +++ b/src/yacsloader/samples/calcium4.xml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + FLUIDE + prun + + + + + + + SOLIDE + prun + + + + + + + + + NEUTRO + prun + + + + + + + INTERPI + prun + + + + + + crayon tpi + int4 tparoi + + + + int4 tpar + canal tpi + + + + canal tfi + crayon tfi + + + + crayon tempi + comb tempi + + + + comb puissi + crayon puissi + + + + crayon iconv + canal iconv + + + + crayon iconv + comb iconv + + + + + + + a.canal + trun + + + + + + + + a.crayon + trun + + + + + + + + + + a.comb + trun + + + + + + a.int4 + trun + + + + + INTERPJ + trun + + + + + + INTERPK + trun + + + + + + canal rfluide + crayon rext + + + + canal tfluide + crayon text + + + + crayon rparoi + canal rparoi + + + + crayon tparoi + int1 tparoit + + + + int1 tpart + canal tparoi + + + + crayon temperature + int2 tparoit + + + + int2 tpart + comb temperature + + + + comb puissance + int3 tparoit + + + + int3 tpart + crayon puissa + + + + + + a b + + + + + + b.canal dt + 0.8 + + + b.crayon dt + 0.8 + + + b.comb dt + 0.8 + + + + + + diff --git a/src/yacsloader/samples/cpp1.xml b/src/yacsloader/samples/cpp1.xml new file mode 100644 index 000000000..1978b535a --- /dev/null +++ b/src/yacsloader/samples/cpp1.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + Cpp + TestComponent + f + + + + + + Cpp + TestComponent + f + + + + + + Cpp + TestComponent + f + + + + + + + + + + + + + + + + + + + + + + + + + + + xmlsh + ./xmlrun.sh + echo + + + + + xmlsh + ./xmlrun.sh + echo + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + Cpp + TestComponent + f + + + + + Cpp + TestComponent + f + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + + + Cpp + TestComponent + f + + + + + + + + + + + + + pyth0 p1 + 1 + + + cpp3 p1 + 1 + + + + + pyth0p1 + cpp1 p1 + + + pyth0p1 + cpp2 p1 + + + cpp1p1 + pyth1 p1 + + + cpp1p1 + pyth3 p1 + + + cpp2p1 + pyth2 p1 + + + cpp2p1 + pyth4 p1 + + + cpp3p1 + xml0 p1 + + + cpp3p1 + xml1 p1 + + + cpp3p1 + corba0 p1 + + + corba0p1 + cpp4 p1 + + + cpp4p1 + corba1 p1 + + + cpp4p1 + cpp5 p1 + + + node0p1 + foreach1 SmplsCollection + + + foreach1SmplPrt + foreach1.cpp4 p1 + + + foreach1.cpp4p1 + pyth5 p1 + + + + diff --git a/src/yacsloader/samples/cschema.xml b/src/yacsloader/samples/cschema.xml new file mode 100644 index 000000000..f1fa7147b --- /dev/null +++ b/src/yacsloader/samples/cschema.xml @@ -0,0 +1,36 @@ + + + + + + + + PYHELLO + makeBanner + + + + + + node1 + makeBanner + + + + + + node1 node2 + + + + node1p1 + node2 p1 + + + + + node1 p1 + coucou + + + diff --git a/src/yacsloader/samples/double1.xml b/src/yacsloader/samples/double1.xml new file mode 100644 index 000000000..6854d8f33 --- /dev/null +++ b/src/yacsloader/samples/double1.xml @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + xmlsh + ./xmlrun.sh + echo + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDoubleVec + + + + + + + + + + + xmlsh + ./xmlrun.sh + echo + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDoubleVec + + + + + + + + + + + + + + + + node1 node2 + + + + node1p1 + node2 p1 + + + + + node1 p1 + coucou + + + diff --git a/src/yacsloader/samples/foreach1.xml b/src/yacsloader/samples/foreach1.xml new file mode 100644 index 000000000..5bc2b2333 --- /dev/null +++ b/src/yacsloader/samples/foreach1.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print a + return p1 + + + + + + + + + + + + node0 b1 + b1 node1 + + + + node0p1 + b1 SmplsCollection + + + b1SmplPrt + b1.node2 p1 + + + b1.node2p1 + node1 p1 + + + + + diff --git a/src/yacsloader/samples/foreach2.xml b/src/yacsloader/samples/foreach2.xml new file mode 100644 index 000000000..b7cee9d4a --- /dev/null +++ b/src/yacsloader/samples/foreach2.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print a + return p1 + + + + + + + b1SmplPrt + b1.node2 p1 + + + + + + + + + node0 b + b node1 + + + + node0p1 + b.b1 SmplsCollection + + + b.b1.node2p1 + node1 p1 + + + + + diff --git a/src/yacsloader/samples/foreach3.xml b/src/yacsloader/samples/foreach3.xml new file mode 100644 index 000000000..61d87918c --- /dev/null +++ b/src/yacsloader/samples/foreach3.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print a + return p1 + + + + + + + + + + + + node0 b1 + b1 node1 + + + + node0p1 + b1 SmplsCollection + + + b1SmplPrt + b1.node2 p1 + + + b1.node2p1 + node1 p1 + + + + + diff --git a/src/yacsloader/samples/foreach4.xml b/src/yacsloader/samples/foreach4.xml new file mode 100644 index 000000000..496f0af0f --- /dev/null +++ b/src/yacsloader/samples/foreach4.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + + + + + + + node0 b1 + b1 node1 + + + + node0p1 + b1 SmplsCollection + + + b1SmplPrt + b1.node2 p1 + + + b1.node2p1 + node1 p1 + + + + + diff --git a/src/yacsloader/samples/foreach5.xml b/src/yacsloader/samples/foreach5.xml new file mode 100644 index 000000000..dcfbea123 --- /dev/null +++ b/src/yacsloader/samples/foreach5.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDoubleVec + + + + b1 node3 + b1 node4 + + b1SmplPrt + b1.node2 p1 + + + b1.node2p1 + node4 p1 + + + + + + + + + node0 b + b node1 + + + + node0p1 + b.b1 SmplsCollection + + + b.b1.node2p1 + node1 p1 + + + + + diff --git a/src/yacsloader/samples/foreach6.xml b/src/yacsloader/samples/foreach6.xml new file mode 100644 index 000000000..c5fb93f57 --- /dev/null +++ b/src/yacsloader/samples/foreach6.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoLong + + + + + + + + + + + + + + + + + + node0 b1 + b1 node1 + + + + node0p1 + b1 SmplsCollection + + + b1SmplPrt + b1.b2 SmplsCollection + + + b1.b2SmplPrt + b1.b2.node2 p1 + + + b1.b2.node2p1 + node1 p1 + + + node1p1 + node3 p1 + + + + + diff --git a/src/yacsloader/samples/foreach_LongCorba.xml b/src/yacsloader/samples/foreach_LongCorba.xml new file mode 100644 index 000000000..ac704da5f --- /dev/null +++ b/src/yacsloader/samples/foreach_LongCorba.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + sleepLong + + + + + + + + + + + node0 b1 + b1 node1 + + + + node0p1 + b1 SmplsCollection + + + b1SmplPrt + b1.node2 p1 + + + b1.node2p1 + node1 p1 + + + + + diff --git a/src/yacsloader/samples/foreach_LongPython.xml b/src/yacsloader/samples/foreach_LongPython.xml new file mode 100644 index 000000000..8c072fee5 --- /dev/null +++ b/src/yacsloader/samples/foreach_LongPython.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + import time + def f(p1): + print "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ start ", p1 + time.sleep(0.1) + print "----------------------------------------- stop ", p1 + return p1 + + + + + + + + + + + + node0 b1 + b1 node1 + + + + node0p1 + b1 SmplsCollection + + + b1SmplPrt + b1.node2 p1 + + + b1.node2p1 + node1 p1 + + + + + diff --git a/src/yacsloader/samples/forloop1.xml b/src/yacsloader/samples/forloop1.xml new file mode 100644 index 000000000..f07cf791b --- /dev/null +++ b/src/yacsloader/samples/forloop1.xml @@ -0,0 +1,28 @@ + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print a + return p1 + + + + + + + + + b1.node2 p1 + 23 + + + diff --git a/src/yacsloader/samples/forloop2.xml b/src/yacsloader/samples/forloop2.xml new file mode 100644 index 000000000..c417632e0 --- /dev/null +++ b/src/yacsloader/samples/forloop2.xml @@ -0,0 +1,32 @@ + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print "a=",a + a=a+p1 + print "a=",a + return p1 + + + + + + + + + b1.node2 p1 + 23 + + + b1 nsteps + 5 + + + diff --git a/src/yacsloader/samples/forloop3.xml b/src/yacsloader/samples/forloop3.xml new file mode 100644 index 000000000..c29d3016f --- /dev/null +++ b/src/yacsloader/samples/forloop3.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print a + return p1 + + + + + + + n b1 + + nnstep + b1 nsteps + + + b1.node2 p1 + 23 + + + diff --git a/src/yacsloader/samples/forloop4.xml b/src/yacsloader/samples/forloop4.xml new file mode 100644 index 000000000..3cebf588a --- /dev/null +++ b/src/yacsloader/samples/forloop4.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print a + return p1 + + + + + + + + n b + + nnstep + b.b1 nsteps + + + b.b1.node2 p1 + 23 + + + diff --git a/src/yacsloader/samples/forloop5.xml b/src/yacsloader/samples/forloop5.xml new file mode 100644 index 000000000..3800492b9 --- /dev/null +++ b/src/yacsloader/samples/forloop5.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print a + return p1 + + + + + + + + + n b + + nnstep + b.b1 nsteps + + + b.b1.c.node2 p1 + 23 + + + diff --git a/src/yacsloader/samples/forloop6.xml b/src/yacsloader/samples/forloop6.xml new file mode 100644 index 000000000..52bfd03fc --- /dev/null +++ b/src/yacsloader/samples/forloop6.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print a + return p1 + + + + + + + + + + n b + + nnstep + b.b1 nsteps + + + b.b1.c.l.node2 p1 + 23 + + + diff --git a/src/yacsloader/samples/forloop7.xml b/src/yacsloader/samples/forloop7.xml new file mode 100644 index 000000000..7cdb1faee --- /dev/null +++ b/src/yacsloader/samples/forloop7.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print a + return p1 + + + + + + + + + n b + + nnstep + b.b1 nsteps + + + b.b1.l.node2 p1 + 23 + + + diff --git a/src/yacsloader/samples/forwhile1.xml b/src/yacsloader/samples/forwhile1.xml new file mode 100644 index 000000000..a43fb1fec --- /dev/null +++ b/src/yacsloader/samples/forwhile1.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print "a:",a + a=a+p1 + print "p1:",p1 + + return p1,condition + + + + + + node2condition + b.b1.l condition + node2p1 + node2 p1 + + + + + + nnstep + b.b1 nsteps + + + b.b1.l.node2 p1 + 23 + + + b.b1.l condition + true + + + diff --git a/src/yacsloader/samples/fschema.xml b/src/yacsloader/samples/fschema.xml new file mode 100644 index 000000000..5c091dcfa --- /dev/null +++ b/src/yacsloader/samples/fschema.xml @@ -0,0 +1,35 @@ + + + + + + + + + def f(p1): + print p1;p1=2*p1 + return p1 + + + + + + + + + + node1 node2 + + + + node1p1 + node2 p1 + + + + + node1 p1 + coucou + + + diff --git a/src/yacsloader/samples/integer1.xml b/src/yacsloader/samples/integer1.xml new file mode 100644 index 000000000..754ae2f0c --- /dev/null +++ b/src/yacsloader/samples/integer1.xml @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + xmlsh + ./xmlrun.sh + echo + + + + + corbaname:rir:#test.my_context/Echo.Object + echoIntVec + + + + + + + + + + + xmlsh + ./xmlrun.sh + echo + + + + + corbaname:rir:#test.my_context/Echo.Object + echoIntVec + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + iter1 iter2 + + iter1Pn + iter2Pnm1 + iter1n + iter2n + + + deuxIter.iter1Pn + deuxIter.iter1Pnm2 + deuxIter.iter2Pn + deuxIter.iter2Pnm2 + deuxIter.iter2n + deuxIter.iter1n + deuxIter.iter2Pn + deuxIter.iter1Pnm1 + + + + iter_0 iter_1 + iter_1 loopIter + + iter_1n + loopIter.deuxIter.iter1n + iter_0Pn + loopIter.deuxIteriter1.Pnm2 + iter_1Pn + loopIterdeuxIter.iter1.Pnm1 + iter_1Pn + loopIterdeuxIter.iter2.Pnm2 + + + + + + init poly_7 + init Legendre + Legendre poly_7 + + + initx + poly_7x + + initnsteps + Legendre.loopIternsteps + + initx + Legendre.iter_1x + initx + Legendre.loopIter.deuxIter.iter1x + initx + Legendre.loopIter.deuxIter.iter2x + + + + diff --git a/src/yacsloader/samples/objref1.xml b/src/yacsloader/samples/objref1.xml new file mode 100644 index 000000000..0b5a4c890 --- /dev/null +++ b/src/yacsloader/samples/objref1.xml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoObjectVec + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoObj2 + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoObjectVec + + + + + + + + + + + + + + + + + + + + + xmlsh + ./xmlrun.sh + echo + + + + + + + xmlsh + ./xmlrun.sh + echo + + + + + + + + pyth0 p1 + corbaname:rir:#test.my_context/Obj.Object + + + corba0 p1 + corbaname:rir:#test.my_context/Obj.Object + + + pyth6 p1 + + corbaname:rir:#test.my_context/Obj.Object + corbaname:rir:#test.my_context/Obj.Object + + + + corba6 p1 + + corbaname:rir:#test.my_context/Obj.Object + corbaname:rir:#test.my_context/Obj.Object + + + + + + pyth0p1 + pyth1 p1 + + + + corba0p1 + corba1 p1 + + + + pyth0p1 + corba2 p1 + + + corba1p1 + pyth3 p1 + + + corba6p1 + foreach3 SmplsCollection + + + foreach3SmplPrt + foreach3.corba4 p1 + + + foreach3.corba4p1 + corba7 p1 + + + + corba6p1 + foreach4 SmplsCollection + + + foreach4SmplPrt + foreach4.pyth p1 + + + foreach4.pythp1 + pyth7 p1 + + + + corba6p1 + foreach5 SmplsCollection + + + foreach5SmplPrt + foreach5.xml5 p1 + + + foreach5.xml5p1 + xml6 p1 + + + diff --git a/src/yacsloader/samples/oschema.xml b/src/yacsloader/samples/oschema.xml new file mode 100644 index 000000000..f2ecb3e0d --- /dev/null +++ b/src/yacsloader/samples/oschema.xml @@ -0,0 +1,106 @@ + + + + + + + + + geom + + + + + + geom + mesh + + + + + + + + + + + + + corbaname::localhost#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + no1 + no2 + p1 + p1 + + + + node2 node3 + + node2 p1 + node3 p1 + + + node3 p1 + node4 p1 + + + node4 p1 + node5 p1 + + diff --git a/src/yacsloader/samples/pschema.xml b/src/yacsloader/samples/pschema.xml new file mode 100644 index 000000000..bf1bdcb60 --- /dev/null +++ b/src/yacsloader/samples/pschema.xml @@ -0,0 +1,418 @@ + + + + + + + + + + + + Obj + + + + + + geom + + + + + + geom + mesh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + def f(p1): + p1= p1+10. + return p1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoObjectVec + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDoubleVec + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDoubleVecVec + + + + + corbaname:rir:#test.my_context/Echo.Object + echoLong + + + + + corbaname:rir:#test.my_context/Echo.Object + echoString + + + + + corbaname:rir:#test.my_context/Echo.Object + echoC + + + + + corbaname:rir:#test.my_context/Echo.Object + echoObj2 + + + + + corbaname:rir:#test.my_context/Echo.Object + echoC + + + + + corbaname:rir:#test.my_context/Echo.Object + echoObj2 + + + + + PYHELLO + makeBanner + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + c1 n1 + c1 n2 + c1.n1p1 + n1 p1 + c1.n2p1 + n2 p1 + + node1 node11 + node11 node12 + node2 node3 + node2 node31 + node2 node32 + node32 node33 + node33 node34 + node34 node35 + node3 node4 + node4 c0 + node4 node41 + node4 node42 + c0 node5 + node5 node61 + node5 node62 + node5 node63 + node13 node14 + node4 node14 + node35 node14 + node46 node47 + node47 node48 + node43 node44 + node44 node45 + + node4p1 + c0.c1.n2 p1 + node4p1 + c0.c1.n1 p1 + + node13 p1 + node14 p1 + + + node2 p1 + node3 p1 + + + node2 p1 + node31 p1 + + + node2 p1 + node32 p1 + + + node33 p2 + node34 p1 + + + node34 p2 + node35 p1 + + + node3 p1 + node4 p1 + + + c0.n1p1 + node5 p1 + + + node5p1 + node61 p1 + + + node5p1 + node62 p1 + + + node5p1 + node63 p1 + + +node52nomtoto + + node99 p1 + + corbaname:rir:#test.my_context/Obj.Object + corbaname:rir:#test.my_context/Obj.Object + corbaname:rir:#test.my_context/Obj.Object + corbaname:rir:#test.my_context/Obj.Object + + + + node33 obj + corbaname:rir:#test.my_context/Echo.Object + + + node33 p1 + corbaname:rir:#test.my_context/C.Object + + + node45 p1 + corbaname:rir:#test.my_context/C.Object + + + node46 p1 + corbaname:rir:#test.my_context/Obj.Object + + + node47 p1 + corbaname:rir:#test.my_context/C.Object + + + node48 p1 + corbaname:rir:#test.my_context/C.Object + + + node1 p1 + 23 + + + node11 p1 + coucou + + + node4 p1 + 23 + + + node44 p1 + chris + + + node43 p1 + 23 + + + node3 p1 + 23 + + + node61 p1 + 23 + + + node12 p1 + + 23 + 45 + + + + node41 p1 + + 23 + 45 + + + + node13 p1 + + + 23.45 + 66 + + + 3.142 + 55 + + + + + node42 p1 + + + 23.45 + 66 + + + 3.142 + 55 + + + + diff --git a/src/yacsloader/samples/refcnt1.xml b/src/yacsloader/samples/refcnt1.xml new file mode 100644 index 000000000..68339a250 --- /dev/null +++ b/src/yacsloader/samples/refcnt1.xml @@ -0,0 +1,84 @@ + + + + + + + a=1 + def f(p1): + global a + a=a+1 + print a + return p1 + + + + + + + def f(p1): + return p1 + + + + + + + def f(p1): + return p1 + + + + + + + def f(p1): + return p1 + + + + + + + def f(p1): + return p1 + + + + + + + + def f(p1): + return p1 + + + + + + + + node1 node2 + node1 node3 + node2 node4 + node3 node5 + node1 c + + node1p1 + node3 p1 + node1p1 + node2 p1 + node2p1 + node4 p1 + node3p1 + node5 p1 + node1p1 + c.node1 p1 + + node1 p1 + 32356 + + + + + diff --git a/src/yacsloader/samples/refcnt2.xml b/src/yacsloader/samples/refcnt2.xml new file mode 100644 index 000000000..7baf3bcf2 --- /dev/null +++ b/src/yacsloader/samples/refcnt2.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + node1 node2 + node1 node3 + node2 node4 + node3 node5 + node1 c + + node1p1 + node3 p1 + node1p1 + node2 p1 + node2p1 + node4 p1 + node3p1 + node5 p1 + node1p1 + c.node1 p1 + + node1 p1 + 32356 + + + + + diff --git a/src/yacsloader/samples/schema.xml b/src/yacsloader/samples/schema.xml new file mode 100644 index 000000000..b4f8f2e16 --- /dev/null +++ b/src/yacsloader/samples/schema.xml @@ -0,0 +1,60 @@ + + + + + + + geom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + no1 + no2 + p1 + p1 + + + + node1 node2 + + node1 + node2 + p1 + p1 + + diff --git a/src/yacsloader/samples/schema2.xml b/src/yacsloader/samples/schema2.xml new file mode 100644 index 000000000..0d6e39ab6 --- /dev/null +++ b/src/yacsloader/samples/schema2.xml @@ -0,0 +1,467 @@ + + + + + + + + + + + Obj + + + + + + geom + + + + + + geom + mesh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + def f(p1): + p1= p1+10. + return p1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VISU + ScalarMapOnField + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDoubleVec + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDoubleVecVec + + + + + corbaname:rir:#test.my_context/Echo.Object + echoLong + + + + + corbaname:rir:#test.my_context/Echo.Object + echoString + + + + + corbaname:rir:#test.my_context/Echo.Object + echoC + + + + + corbaname:rir:#test.my_context/Echo.Object + echoObj2 + + + + + corbaname:rir:#test.my_context/Echo.Object + echoC + + + + + corbaname:rir:#test.my_context/Echo.Object + echoObj2 + + + + + GEOM_Superv + MakeBox + + + + + + + + + + GEOM_Superv + MakeCopy + + + + + GEOM_Superv + SetStudyID + + + + PYHELLO + makeBanner + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + c1 n1 + + c1.n1p1 + n1 p1 + + + node2 node3 + node2 node31 + node2 node32 + node32 node33 + node33 node34 + node34 node35 + node3 node4 + node4 c0 + node4 node41 + node4 node42 + c0 node5 + node5 node61 + node5 node62 + node5 node63 + node13 node14 + node44 node51 + node51 node49 + node49 node50 + node36 node37 + + node36 myResult + node37 p1 + node49 box + node50 box + + node13 p1 + node14 p1 + + + node2 p1 + node3 p1 + + + node2 p1 + node31 p1 + + + node2 p1 + node32 p1 + + + node33 p2 + node34 p1 + + + node34 p2 + node35 p1 + + + node3 p1 + node4 p1 + + + node4p1 + c0.c1.n1 p1 + + + c0.n1p1 + node5 p1 + + + node5p1 + node61 p1 + + + node5p1 + node62 p1 + + + node5p1 + node63 p1 + + +node37p2dom +node37p30 +node37p4vitesse +node37p50. +node52nomtoto +node51id1 +node49 x10 +node49 y10 +node49 z10 +node49 x25 +node49 y25 +node49 z25 + + node33 obj + corbaname:rir:#test.my_context/Echo.Object + + + node33 p1 + corbaname:rir:#test.my_context/C.Object + + + node45 p1 + corbaname:rir:#test.my_context/C.Object + + + node46 p1 + corbaname:rir:#test.my_context/Obj.Object + + + node47 p1 + corbaname:rir:#test.my_context/C.Object + + + node48 p1 + corbaname:rir:#test.my_context/C.Object + + + node1 p1 + 23 + + + node11 p1 + coucou + + + node4 p1 + 23 + + + node44 p1 + chris + + + node43 p1 + 23 + + + node3 p1 + 23 + + + node61 p1 + 23 + + + node12 p1 + + 23 + 45 + + + + node41 p1 + + 23 + 45 + + + + node13 p1 + + + 23.45 + 66 + + + 3.142 + 55 + + + + + node42 p1 + + + 23.45 + 66 + + + 3.142 + 55 + + + + diff --git a/src/yacsloader/samples/sinline1.xml b/src/yacsloader/samples/sinline1.xml new file mode 100644 index 000000000..d27ff79b3 --- /dev/null +++ b/src/yacsloader/samples/sinline1.xml @@ -0,0 +1,97 @@ + + + + + + + import salome + salome.salome_init() + import PYHELLO_ORB + def f(p1): + print __container__from__YACS__ + machine,container=__container__from__YACS__.split('/') + param={} + param['hostname']=machine + param['container_name']=container + compo=salome.lcc.LoadComponent(param, "PYHELLO") + print compo.makeBanner(p1) + print p1 + + + + + + + + import salome + salome.salome_init() + import HELLO_ORB + def f(p1): + print __container__from__YACS__ + machine,container=__container__from__YACS__.split('/') + param={} + param['hostname']=machine + param['container_name']=container + compo=salome.lcc.LoadComponent(param, "HELLO") + print compo.makeBanner(p1) + print p1 + + + + + + + import salome + salome.salome_init() + import PYHELLO_ORB + def f(p1): + print __container__from__YACS__ + machine,container=__container__from__YACS__.split('/') + param={} + param['hostname']=machine + param['container_name']=container + compo=salome.lcc.LoadComponent(param, "PYHELLO") + print compo.makeBanner(p1) + print p1 + + + + + + + import salome + salome.salome_init() + import HELLO_ORB + def f(p1): + print __container__from__YACS__ + machine,container=__container__from__YACS__.split('/') + param={} + param['hostname']=machine + param['container_name']=container + compo=salome.lcc.LoadComponent(param, "HELLO") + print compo.makeBanner(p1) + print p1 + + + + + + + + node1 p1 + chris + + + node2 p1 + chris + + + node3 p1 + chris + + + node4 p1 + chris + + + diff --git a/src/yacsloader/samples/sinline2.xml b/src/yacsloader/samples/sinline2.xml new file mode 100644 index 000000000..bb85304b1 --- /dev/null +++ b/src/yacsloader/samples/sinline2.xml @@ -0,0 +1,33 @@ + + + + + + + + import salome + salome.salome_init() + import PYHELLO_ORB + def f(p1): + print __container__from__YACS__ + machine,container=__container__from__YACS__.split('/') + param={} + param['hostname']=machine + param['container_name']=container + compo=salome.lcc.LoadComponent(param, "PYHELLO") + print compo.makeBanner(p1) + print p1 + + + + + + + + + + b1.node1 p1 + chris + + + diff --git a/src/yacsloader/samples/sinline3.xml b/src/yacsloader/samples/sinline3.xml new file mode 100644 index 000000000..f25a3e2eb --- /dev/null +++ b/src/yacsloader/samples/sinline3.xml @@ -0,0 +1,33 @@ + + + + + + + + import salome + salome.salome_init() + import PYHELLO_ORB + print __container__from__YACS__ + machine,container=__container__from__YACS__.split('/') + param={} + param['hostname']=machine + param['container_name']=container + compo=salome.lcc.LoadComponent(param, "PYHELLO") + def f(p1): + print compo.makeBanner(p1) + print p1 + + + + + + + + + + b1.node1 p1 + chris + + + diff --git a/src/yacsloader/samples/sinline4.xml b/src/yacsloader/samples/sinline4.xml new file mode 100644 index 000000000..57788d767 --- /dev/null +++ b/src/yacsloader/samples/sinline4.xml @@ -0,0 +1,101 @@ + + + + + + + + + import salome + salome.salome_init() + import PYHELLO_ORB + def f(p1): + print __container__from__YACS__ + machine,container=__container__from__YACS__.split('/') + param={} + param['hostname']=machine + param['container_name']=container + compo=salome.lcc.LoadComponent(param, "PYHELLO") + print compo.makeBanner(p1) + print p1 + + + + + + + + import salome + salome.salome_init() + import HELLO_ORB + def f(p1): + print __container__from__YACS__ + machine,container=__container__from__YACS__.split('/') + param={} + param['hostname']=machine + param['container_name']=container + compo=salome.lcc.LoadComponent(param, "HELLO") + print compo.makeBanner(p1) + print p1 + + + + + + + import salome + salome.salome_init() + import PYHELLO_ORB + def f(p1): + print __container__from__YACS__ + machine,container=__container__from__YACS__.split('/') + param={} + param['hostname']=machine + param['container_name']=container + compo=salome.lcc.LoadComponent(param, "PYHELLO") + print compo.makeBanner(p1) + print p1 + + + + + + + import salome + salome.salome_init() + import HELLO_ORB + def f(p1): + print __container__from__YACS__ + machine,container=__container__from__YACS__.split('/') + param={} + param['hostname']=machine + param['container_name']=container + compo=salome.lcc.LoadComponent(param, "HELLO") + print compo.makeBanner(p1) + print p1 + + + + + + + + + + b1.b1.node1 p1 + chris + + + b1.b1.node2 p1 + chris + + + b1.b1.node3 p1 + chris + + + b1.b1.node4 p1 + chris + + + diff --git a/src/yacsloader/samples/sinline5.xml b/src/yacsloader/samples/sinline5.xml new file mode 100644 index 000000000..5d386bb31 --- /dev/null +++ b/src/yacsloader/samples/sinline5.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + import salome + salome.salome_init() + import PYHELLO_ORB + print __container__from__YACS__ + machine,container=__container__from__YACS__.split('/') + param={} + param['hostname']=machine + param['container_name']=container + compo=salome.lcc.LoadComponent(param, "PYHELLO") + def f(p1): + print compo.makeBanner(p1) + print p1 + return p1 + + + + + + + + + + + + + + node0 b1 + + + + node0p1 + b1 SmplsCollection + + + b1SmplPrt + b1.node2 p1 + + + b1.node2p1 + node1 p1 + + + + diff --git a/src/yacsloader/samples/stream1.xml b/src/yacsloader/samples/stream1.xml new file mode 100644 index 000000000..3ea1b7c43 --- /dev/null +++ b/src/yacsloader/samples/stream1.xml @@ -0,0 +1,32 @@ + + + + + + + + + COMPONENT_B + S2 + + + + + COMPONENT_C + S3 + + + + + + + + + + + + node1 S2_data_uses_port + node2 S3_data_provides_port + + + diff --git a/src/yacsloader/samples/stream2.xml b/src/yacsloader/samples/stream2.xml new file mode 100644 index 000000000..6b1c733e7 --- /dev/null +++ b/src/yacsloader/samples/stream2.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + DSCCODA + prun + + + + + + DSCCODB + prun + + + + + + node0 node1 + node0 node2 + + + node0n + node1 niter + + + node0n + node2 niter + + + + + + node1 prun_out_port + node2 prun_in_port + + + node2 prun_out_port + node1 prun_in_port + + + diff --git a/src/yacsloader/samples/stream3.xml b/src/yacsloader/samples/stream3.xml new file mode 100644 index 000000000..7e267803d --- /dev/null +++ b/src/yacsloader/samples/stream3.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + DSCCODA + prun + + + + + + DSCCODB + prun + + + + + + node1 + trun + + + + + + node2 + trun + + + + + + node0 node1 + node0 node2 + node1 node3 + node2 node4 + node1 node4 + node2 node3 + + + node0n + node1 niter + + + node0n + node2 niter + + + node0n + node3 niter + + + node0n + node4 niter + + + + + + node1 prun_out_port + node2 prun_in_port + + + node2 prun_out_port + node1 prun_in_port + + + node3 trun_out_port + node4 trun_in_port + + + node4 trun_out_port + node3 trun_in_port + + + diff --git a/src/yacsloader/samples/stream4.xml b/src/yacsloader/samples/stream4.xml new file mode 100644 index 000000000..e2456f0d9 --- /dev/null +++ b/src/yacsloader/samples/stream4.xml @@ -0,0 +1,153 @@ + + + + + + + + + + + + DSCCODA + prun + + + + + + DSCCODB + prun + + + + + + node1 + trun + + + + + + node2 + trun + + + + + + node1 + trun + + + + + + node2 + prun + + + + + + node1 + prun + + + + + + node2 + trun + + + + + + node0 node1 + node0 node2 + node1 node3 + node2 node4 + node1 node4 + node2 node3 + node3 node5 + node4 node6 + node3 node6 + node4 node5 + node5 node7 + node6 node8 + node5 node8 + node6 node7 + + + node0n + node1 niter + + + node0n + node2 niter + + + node0n + node3 niter + + + node0n + node4 niter + + + node0n + node5 niter + + + node0n + node6 niter + + + node0n + node7 niter + + + node0n + node8 niter + + + + + + node1 prun_out_port + node2 prun_in_port + + + node2 prun_out_port + node1 prun_in_port + + + node3 trun_out_port + node4 trun_in_port + + + node4 trun_out_port + node3 trun_in_port + + + node5 trun_out_port + node6 prun_in_port + + + node6 prun_out_port + node5 trun_in_port + + + node7 prun_out_port + node8 trun_in_port + + + node8 trun_out_port + node7 prun_in_port + + + diff --git a/src/yacsloader/samples/string1.xml b/src/yacsloader/samples/string1.xml new file mode 100644 index 000000000..7be5ba4a3 --- /dev/null +++ b/src/yacsloader/samples/string1.xml @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + xmlsh + ./xmlrun.sh + echo + + + + + corbaname:rir:#test.my_context/Echo.Object + echoStrVec + + + + + + + + + + + xmlsh + ./xmlrun.sh + echo + + + + + corbaname:rir:#test.my_context/Echo.Object + echoStrVec + + + + + + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoStruct + + + + + + xmlsh + ./xmlrun.sh + echo + + + + + + + + + + + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDouble + + + + + + corbaname:rir:#test.my_context/Echo.Object + echoDoubleVec + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + b1.p1_n2 p1 + 23 + + + b1.p3_n2 p1 + 54 + + + b1.default_n2 p1 + 54 + + + diff --git a/src/yacsloader/samples/switch2.xml b/src/yacsloader/samples/switch2.xml new file mode 100644 index 000000000..eb91cabb1 --- /dev/null +++ b/src/yacsloader/samples/switch2.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + b1.p1_n2 p1 + 23 + + + b1.p3_n2 p1 + 54 + + + b1.default_n2 p1 + 54 + + + b1 select + 3 + + + + diff --git a/src/yacsloader/samples/switch3.xml b/src/yacsloader/samples/switch3.xml new file mode 100644 index 000000000..565b50134 --- /dev/null +++ b/src/yacsloader/samples/switch3.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + n b1 + + nselect + b1 select + + + b1.p1_n2 p1 + 23 + + + b1.p3_n2 p1 + 54 + + + b1.default_n2 p1 + 54 + + + + diff --git a/src/yacsloader/samples/switch4.xml b/src/yacsloader/samples/switch4.xml new file mode 100644 index 000000000..61d525921 --- /dev/null +++ b/src/yacsloader/samples/switch4.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + n b1 + b1 n2 + + nselect + b1 select + b1.p1_n2p1 + n2 p1 + b1.p3_n2p1 + n2 p1 + b1.default_n2p1 + n2 p1 + + + b1.p1_n2 p1 + 23 + + + b1.p3_n2 p1 + 54 + + + b1.default_n2 p1 + 67 + + + diff --git a/src/yacsloader/samples/switch5.xml b/src/yacsloader/samples/switch5.xml new file mode 100644 index 000000000..c3c34025d --- /dev/null +++ b/src/yacsloader/samples/switch5.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + n b1 + b1 n2 + + nselect + b1 select + b1.p1_n2p1 + n2 p1 + b1.p3_b.n2p1 + n2 p1 + b1.default_n2p1 + n2 p1 + + + b1.p1_n2 p1 + 23 + + + b1.p3_b.n2 p1 + 54 + + + b1.default_n2 p1 + 67 + + + diff --git a/src/yacsloader/samples/switch6.xml b/src/yacsloader/samples/switch6.xml new file mode 100644 index 000000000..c0d4e3f0f --- /dev/null +++ b/src/yacsloader/samples/switch6.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + n b + b n2 + + nselect + b.b1 select + b.b1.p1_n2p1 + n2 p1 + b.b1.p3_n2p1 + n2 p1 + b.b1.default_n2p1 + n2 p1 + + + b.b1.p1_n2 p1 + 23 + + + b.b1.p3_n2 p1 + 54 + + + b.b1.default_n2 p1 + 67 + + + diff --git a/src/yacsloader/samples/switch7.xml b/src/yacsloader/samples/switch7.xml new file mode 100644 index 000000000..fb1fb684d --- /dev/null +++ b/src/yacsloader/samples/switch7.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + n b1 + b1 n2 + + nselect + b1 select + b1.p1_n2p1 + n2 p1 + b1.p3_b.n2p1 + n2 p1 + b1.default_n2p1 + n2 p1 + + + b1.p1_n2 p1 + 23 + + + b1.p3_b.n2 p1 + 54 + + + b1.default_n2 p1 + 67 + + + diff --git a/src/yacsloader/samples/switch8.xml b/src/yacsloader/samples/switch8.xml new file mode 100644 index 000000000..bacb8ad59 --- /dev/null +++ b/src/yacsloader/samples/switch8.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + n2p1 + n2 p1 + n2condition + b1.m3_b condition + + + + + + + + + + + + + nselect + b1 select + b1.p1_n2p1 + n2 p1 + b1.m3_b.n2p1 + n2 p1 + b1.default_n2p1 + n2 p1 + + + b1.p1_n2 p1 + 23 + + + b1.m3_b.n2 p1 + 54 + + + b1.default_n2 p1 + 67 + + + diff --git a/src/yacsloader/samples/switch9.xml b/src/yacsloader/samples/switch9.xml new file mode 100644 index 000000000..6c97fbb9e --- /dev/null +++ b/src/yacsloader/samples/switch9.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + n b1 + b1 n2 + + nselect + b1 select + b1.p1_n2p1 + n2 p1 + b1.p3_b.p1_n2p1 + n2 p1 + b1.default_n2p1 + n2 p1 + + + b1.p1_n2 p1 + 23 + + + b1.p3_b.p1_n2 p1 + 54 + + + b1.default_n2 p1 + 67 + + + diff --git a/src/yacsloader/samples/while1.xml b/src/yacsloader/samples/while1.xml new file mode 100644 index 000000000..bfb900560 --- /dev/null +++ b/src/yacsloader/samples/while1.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print "p1:",p1 + + return p1,condition + + + + + + node2condition + b1 condition + node2p1 + node2 p1 + + + + ncondition + b1 condition + + + b1.node2 p1 + 23 + + + diff --git a/src/yacsloader/samples/while2.xml b/src/yacsloader/samples/while2.xml new file mode 100644 index 000000000..6b18ca970 --- /dev/null +++ b/src/yacsloader/samples/while2.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + b.node2condition + b1 condition + b.node2p1 + b.node2 p1 + + + + ncondition + b1 condition + + + b1.b.node2 p1 + 23 + + + diff --git a/src/yacsloader/samples/while3.xml b/src/yacsloader/samples/while3.xml new file mode 100644 index 000000000..f7acc299f --- /dev/null +++ b/src/yacsloader/samples/while3.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + a=0 + def f(p1): + global a + p1= p1+10. + print a + a=a+p1 + print "p1:",p1 + + return p1,condition + + + + + + node2condition + b0.b1 condition + node2p1 + node2 p1 + + b1.node2condition + b0 condition + + + + ncondition + b0.b1 condition + + + b0.b1.node2 p1 + 23 + + + diff --git a/src/yacsloader/schema.xsd b/src/yacsloader/schema.xsd new file mode 100644 index 000000000..6d2c5a126 --- /dev/null +++ b/src/yacsloader/schema.xsd @@ -0,0 +1,281 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/yacsloader/xmlParserBase.cxx b/src/yacsloader/xmlParserBase.cxx new file mode 100644 index 000000000..d7345172a --- /dev/null +++ b/src/yacsloader/xmlParserBase.cxx @@ -0,0 +1,481 @@ + +#include "xmlParserBase.hxx" +#include "Exception.hxx" + +#include +#include +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +// --- specific part for libxml2 ---------------------------------------------- + +#ifdef USE_LIBXML2 +extern "C" +{ +#include // for xmlCreateFileParserCtxt +} +_xmlParserCtxt* xmlParserBase::_xmlParser; +void xmlParserBase::XML_SetUserData(_xmlParserCtxt* ctxt, + xmlParserBase* parser) +{ + ctxt->userData = parser; +} +#endif + +// --- specific part for expat ------------------------------------------------ + +#ifdef USE_EXPAT +XML_Parser xmlParserBase::_xmlParser; +#endif + +// --- generic part ----------------------------------------------------------- + +using namespace std; +using YACS::Exception; + +std::stack xmlParserBase::_stackParser; +std::list xmlParserBase::_garbage; + +/*! callback usable only with libxml2 + */ + +void XMLCALL xmlParserBase::start_document(void* userData) +{ + //DEBTRACE("xmlParserBase::start_document"); + xmlParserBase *currentParser = static_cast (userData); +} + +/*! callback usable only with libxml2 + */ + +void XMLCALL xmlParserBase::end_document (void* userData) +{ + //DEBTRACE("xmlParserBase::end_document"); + xmlParserBase *currentParser = static_cast (userData); +} + +/*! callback called on start of an xml element: + */ + +void XMLCALL xmlParserBase::start_element (void* userData, + const xmlChar* name, + const xmlChar** p) +{ + //DEBTRACE("xmlParserBase::start_element " << name); + cleanGarbage(); + xmlParserBase *currentParser = static_cast (userData); + const XML_Char *aName = tochar(name); + currentParser->incrCount(aName); + currentParser->onStart(aName, p); +} + + +/*! callback called on end of an xml element: + */ + +void XMLCALL xmlParserBase::end_element (void* userData, + const xmlChar* name) +{ + //DEBTRACE("xmlParserBase::end_element"); + const XML_Char *aName = tochar(name); + xmlParserBase *childParser = static_cast (userData); + _garbage.push_back(_stackParser.top()); + DEBTRACE("xmlParserBase::end_element " << _garbage.size()); + _stackParser.pop(); + XML_SetUserData(_xmlParser, _stackParser.top()); + childParser->onEnd(aName); + childParser->end(); + } + + +/*! callback called for significant characters inside tags: content + * or outside tags, like space or new line. + * with expat get also the CDATA tags: ![CDATA[content]]> + */ + +void XMLCALL xmlParserBase::characters (void* userData, + const xmlChar* ch, + int len) +{ + //DEBTRACE("xmlParserBase::characters " << len); + xmlParserBase *currentParser = (xmlParserBase *) (userData); + string data((char*)ch,len); + currentParser->charData(data); +} + + +/*! callback usable only with libxml2 + */ + +void XMLCALL xmlParserBase::comment (void* userData, + const xmlChar* value) +{ + //DEBTRACE("xmlParserBase::comment"); + xmlParserBase *currentParser = static_cast (userData); +} + + +/*! callback usable only with libxml2 + */ + +void XMLCALL xmlParserBase::warning (void* userData, + const char* fmt, ...) +{ + DEBTRACE("xmlParserBase::warning"); + xmlParserBase *currentParser = static_cast (userData); + va_list args; + va_start(args, fmt); + string format = "%s"; + if (format == fmt) + { + char* parv; + parv = va_arg(args, char*); + cerr << parv ; + } + else cerr << __FILE__ << " [" << __LINE__ << "] : " + << "error format not taken into account: " << fmt << endl; + va_end(args); +} + + +/*! callback usable only with libxml2 + */ + +void XMLCALL xmlParserBase::error (void* userData, + const char* fmt, ...) +{ + DEBTRACE("xmlParserBase::error"); + xmlParserBase *currentParser = static_cast (userData); + va_list args; + va_start(args, fmt); + string format = "%s"; + if (format == fmt) + { + char* parv; + parv = va_arg(args, char*); + cerr << parv ; + xmlParserBase *currentParser = (xmlParserBase *) userData; + //cerr << currentParser->element << endl; + } + else cerr << __FILE__ << " [" << __LINE__ << "] : " + << "error format not taken into account: " << fmt << endl; + va_end(args); +} + + +/*! callback usable only with libxml2 + */ + +void XMLCALL xmlParserBase::fatal_error (void* userData, + const char* fmt, ...) +{ + DEBTRACE("xmlParserBase::fatal_error"); + xmlParserBase *currentParser = static_cast (userData); + va_list args; + va_start(args, fmt); + string format = "%s"; + if (format == fmt) + { + char* parv; + parv = va_arg(args, char*); + cerr << parv ; + } + else cerr << __FILE__ << " [" << __LINE__ << "] : " + << "error format not taken into account: " << fmt << endl; + va_end(args); +} + +/*! callback called for CDATA inside tags: ![CDATA[content]]> + * used only by libxml2 + */ + +void XMLCALL xmlParserBase::cdata_block (void* userData, + const xmlChar* value, + int len) +{ + //DEBTRACE("xmlParserBase::cdata_block"); + xmlParserBase *currentParser = static_cast (userData); + string data((char*)value,len); + currentParser->charData(data); +} + +void xmlParserBase::cleanGarbage() +{ + while (!_garbage.empty()) + { + delete (_garbage.front()); + _garbage.pop_front(); + } +} + +/*! Stores the tag attributes on a map. The map is an attribute of the parser + * object dedicated to the current xml tag + */ + +void xmlParserBase::getAttributes(const xmlChar** p) +{ + if (p) while (*p) + { + string attributeName = (char*)*p; + //cerr << "attribute name " << attributeName << endl; + p++; + string attributeValue = (char*)*p; + //cerr << "attribute value " << attributeValue << endl; + p++; + _mapAttrib[attributeName] = attributeValue; + } +} + +/*! Stores an attribute (key, value) on the map attribute. + * used for attributes defined at another tag level (child tags). + */ + +void xmlParserBase::setAttribute(std::string key, std::string value) +{ + _mapAttrib[key] = value; +} + +/*! Gets an attribute value given a string key. + * If the key does not exist, throws an Exception. + */ + +std::string xmlParserBase::getAttribute(std::string key) +{ + if (_mapAttrib.find(key) == _mapAttrib.end()) + { + string what = "Attribute does not exist: " + key; + throw Exception(what); + } + return _mapAttrib[key]; +} + +/*! Add data on the data attribute of the parser object dedicated to an xml tag + */ + +void xmlParserBase::addData(std::string value) +{ + // DEBTRACE("xmlParserBase::addData()"); + _data += value; +} + +/*! all parsers must know their father parser (father tag), in order + * to set values or attributes in father. + */ + +void xmlParserBase::init (const xmlChar** p, xmlParserBase* father) +{ + _father = father; +} + +/*! to be specialized for each kind of xml tag + */ + +void xmlParserBase::onStart (const XML_Char* elem, const xmlChar** p) +{ +} + +/*! to be specialized for each kind of xml tag + */ + +void xmlParserBase::onEnd (const XML_Char* name) +{ +} + +/*! to be specialized following the kind of xml tag + */ + +void xmlParserBase::charData (std::string data) +{ +} + +/*! May be specialized for each kind of xml tag. + * Counts the number of tag occurences of a given type inside a context. + */ + +void xmlParserBase::incrCount(const XML_Char *elem) +{ + if(counts.find(elem)==counts.end()) + counts[elem]=1; + else + counts[elem]=counts[elem]+1; +} + +/*! to be specialized for each kind of xml tag + */ + +void xmlParserBase::end() +{ +} + +/*! Throws an exception. different implementation with libxml2 and expat + */ + +void xmlParserBase::stopParse(std::string what) +{ +#ifdef USE_LIBXML2 + xmlStopParser(_xmlParser); +#endif +#ifdef USE_EXPAT + throw Exception(what); +#endif +} + +// ---------------------------------------------------------------------------- + +#ifdef USE_LIBXML2 + +/*! libxml2 parser initialisation + * \param parser dedicated parser + */ + +xmlReader::xmlReader(xmlParserBase* parser): _rootParser(parser) +{ +} + +/*! libxml2 parse + * \param xmlFile file to parse + */ + +void xmlReader::parse(std::string xmlFile) +{ + _rootParser->init(0); + _rootParser->_stackParser.push(_rootParser); + + xmlSAXHandler baseHandler = + { + 0, // internal_subset, + 0, // isStandalone + 0, // hasInternalSubset + 0, // hasExternalSubset + 0, // resolveEntity + 0, // getEntity + 0, // entityDecl + 0, // notationDecl + 0, // attributeDecl + 0, // elementDecl + 0, // unparsedEntityDecl + 0, // setDocumentLocator + xmlParserBase::start_document, // startDocument + xmlParserBase::end_document, // endDocument + xmlParserBase::start_element, // startElement + xmlParserBase::end_element, // endElement + 0, // reference + xmlParserBase::characters, // characters + 0, // ignorableWhitespace + 0, // processingInstruction + xmlParserBase::comment, // comment + xmlParserBase::warning, // warning + xmlParserBase::error, // error + xmlParserBase::fatal_error, // fatalError + 0, // getParameterEntity + xmlParserBase::cdata_block, // cdataBlock + 0 // externalSubset + }; + + // --- sequence from libxml++, to have a libxml context + + _xmlParserCtxt* saxContext; + saxContext = xmlCreateFileParserCtxt(xmlFile.c_str()); + if (!saxContext) + { + _rootParser->cleanGarbage(); + string what = "problem while trying to open the file for parsing " + xmlFile; + throw Exception(what); + } + xmlSAXHandlerPtr old_sax = saxContext->sax; + saxContext->sax = &baseHandler; + _rootParser->_xmlParser = saxContext; + saxContext->userData = _rootParser; + + xmlParseDocument(saxContext); + _rootParser->cleanGarbage(); + DEBTRACE("xmlParserBase::end of parse, garbage size = " << _rootParser->getGarbageSize()); +} +#endif + +// ---------------------------------------------------------------------------- + +#ifdef USE_EXPAT + +#define SIZEBUF 8192 +char Buffer[SIZEBUF]; + +/*! expat parser initialisation + * \param parser dedicated parser + */ + +xmlReader::xmlReader(xmlParserBase* parser): _rootParser(parser) +{ + xmlParserBase::_xmlParser= XML_ParserCreate(NULL); + if (! _rootParser ) + { + cerr << "Couldn't allocate memory for parser" << endl; + throw Exception("Couldn't allocate memory for parser"); + } +} + +/*! expat parse + * \param xmlFile file to parse + */ + +void xmlReader::parse(std::string xmlFile) +{ + FILE* fin=fopen(xmlFile.c_str(),"r"); + if (! fin) + { + std::cerr << "Couldn't open schema file" << std::endl; + throw std::invalid_argument("Couldn't open schema file"); + //throw Exception("Couldn't open schema file"); + } + + XML_SetElementHandler(xmlParserBase::_xmlParser, + xmlParserBase::start_element, + xmlParserBase::end_element); + XML_SetCharacterDataHandler(xmlParserBase::_xmlParser, + xmlParserBase::characters ); + XML_SetUserData(xmlParserBase::_xmlParser, _rootParser); + _rootParser->init(0); + _rootParser->_stackParser.push(_rootParser); + + try + { + for (;;) + { + int done; + int len; + + len = fread(Buffer, 1, SIZEBUF, fin); + if (ferror(fin)) + { + std::cerr << "Read error" << std::endl; + throw Exception("Read error"); + } + done = feof(fin); + + if (XML_Parse(xmlParserBase::_xmlParser, Buffer, len, done) == XML_STATUS_ERROR) + { + throw Exception(XML_ErrorString(XML_GetErrorCode(xmlParserBase::_xmlParser))); + } + + if (done) + break; + } + XML_ParserFree (xmlParserBase::_xmlParser); + xmlParserBase::_xmlParser=0; + _rootParser->cleanGarbage(); + DEBTRACE("xmlParserBase::end of parse, garbage size = " << _rootParser->getGarbageSize()); + } + catch(Exception& e) + { + _rootParser->cleanGarbage(); + //get line number from XML parser + cerr << "Error at line: " << XML_GetCurrentLineNumber(xmlParserBase::_xmlParser) << endl; + throw e; + } +} +#endif + +// ---------------------------------------------------------------------------- diff --git a/src/yacsloader/xmlParserBase.hxx b/src/yacsloader/xmlParserBase.hxx new file mode 100644 index 000000000..066b11cc7 --- /dev/null +++ b/src/yacsloader/xmlParserBase.hxx @@ -0,0 +1,125 @@ +#ifndef __XMLPARSERBASE_HXX_ +#define __XMLPARSERBASE_HXX_ + + +// --- select only one of the following packages ------------------------------ +// - libxml2 comes with gnome, so it's almost always already installed, +// but may not not work (see below). +// - libexpat is a less common package, but light, and works fine. + +// With standard installation of libxml2, C++ exception cannot be catched +// during the parse process. This is required for normal use of yacs. +// libxml2 must be generated with configure --with-fexceptions ... +// (to be tested) +// Developpement and tests are done with libexpat. + +//#define USE_LIBXML2 +#define USE_EXPAT + +// --- specific part for libxml2 ---------------------------------------------- + +#ifdef USE_LIBXML2 +extern "C" +{ +#include +} +#define XMLCALL +#define XML_Char char +inline XML_Char* tochar(const xmlChar *c) { return (XML_Char*)c; }; +#endif + +// --- specific part for expat ------------------------------------------------ + +#ifdef USE_EXPAT + #include +#define xmlChar XML_Char +inline const XML_Char* tochar(const xmlChar *c) { return c; }; +#endif + + +// --- generic part ----------------------------------------------------------- + +#include +#include +#include +#include + +class xmlParserBase; + +//! \brief base class for parse an xml file, use a dedicated parser, runtime independant. + +class xmlReader +{ +public: + xmlReader(xmlParserBase* parser); + virtual void parse(std::string xmlFile); +protected: + xmlParserBase* _rootParser; +}; + +//! \brief base class for xml parsers, runtime independant + +class xmlParserBase +{ +public: + static void XMLCALL start_document(void* userData); + static void XMLCALL end_document (void* userData); + static void XMLCALL start_element (void* userData, + const xmlChar* name, + const xmlChar** p); + static void XMLCALL end_element (void* userData, + const xmlChar* name); + static void XMLCALL characters (void* userData, + const xmlChar* ch, + int len); + static void XMLCALL comment (void* userData, + const xmlChar* value); + static void XMLCALL warning (void* userData, + const char* fmt, ...); + static void XMLCALL error (void* userData, + const char* fmt, ...); + static void XMLCALL fatal_error (void* userData, + const char* fmt, ...); + static void XMLCALL cdata_block (void* userData, + const xmlChar* value, + int len); + static void cleanGarbage(); + static int getGarbageSize() {return _garbage.size(); }; +public: + void setAttribute(std::string key, std::string value); + std::string getAttribute(std::string key); + virtual void addData(std::string value); + virtual void init (const xmlChar** p, xmlParserBase* father=0); + + std::map< std::string, int > counts; + +#ifdef USE_LIBXML2 + static _xmlParserCtxt* _xmlParser; + static void XML_SetUserData(_xmlParserCtxt* ctxt, + xmlParserBase* parser); +#endif + +#ifdef USE_EXPAT + static XML_Parser _xmlParser; +#endif + + static std::stack _stackParser; + +protected: + void getAttributes(const xmlChar** p); + + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + virtual void charData (std::string data); + virtual void incrCount(const XML_Char *elem); + virtual void end(); + virtual void stopParse(std::string what); + +protected: + std::map _mapAttrib; + static std::list _garbage; + std::string _data; + xmlParserBase *_father; +}; + +#endif diff --git a/src/yacsorb/Makefile.am b/src/yacsorb/Makefile.am new file mode 100644 index 000000000..52b29980d --- /dev/null +++ b/src/yacsorb/Makefile.am @@ -0,0 +1,85 @@ +include $(top_srcdir)/adm/unix/make_begin.am + +IDL_FILES = yacs.idl +IDL_SOURCES = yacsSK.cc +BUILT_SOURCES = $(IDL_SOURCES) yacs_idl.py + +OMNIORB_IDL+= -I$(KERNEL_ROOT_DIR)/idl/salome -I$(GUI_ROOT_DIR)/idl/salome + +lib_LTLIBRARIES = libYACSorb.la + +nodist_libYACSorb_la_SOURCES = $(IDL_SOURCES) + +bin_PROGRAMS=yacsSrv yacs_clt + +yacsSrv_SOURCES = yacsSrv.cxx $(IDL_SOURCES) + +if SALOME_KERNEL +SALOME_LIBS=-L$(KERNEL_ROOT_DIR)/lib/salome -lSalomeLifeCycleCORBA -lSalomeDSCContainer +endif + +AM_CXXFLAGS= \ + -I$(KERNEL_ROOT_DIR)/include/salome \ + -I$(GUI_ROOT_DIR)/include/salome + +IDLPYFLAGS = \ + -I$(KERNEL_ROOT_DIR)/idl/salome + +yacsSrv_CXXFLAGS = -g -DYACS_PTHREAD \ + $(PYTHON_CPPFLAGS) \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CXXFLAGS) \ + -I$(KERNEL_ROOT_DIR)/include/salome \ + -I$(GUI_ROOT_DIR)/include/salome \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + -I$(srcdir)/../yacsloader \ + -I$(srcdir)/../runtime + +yacsSrv_LDFLAGS = $(PYTHON_EXTRA_LDFLAGS) -lexpat -pthread -lxml2 + +yacsSrv_LDADD = ../yacsloader/libYACSloader.la \ + ../runtime/libYACSRuntimeSALOME.la \ + ../engine/libYACSEngine.la \ + $(SALOME_LIBS) \ + $(OMNIORB_LIBS) \ + $(PYTHON_LDFLAGS) \ + $(PYTHON_EXTRA_LIBS) + +yacs_clt_SOURCES = yacs_clt.cxx $(IDL_SOURCES) + +yacs_clt_CXXFLAGS = \ + $(PYTHON_CPPFLAGS) \ + -I$(srcdir)/../bases \ + -I$(srcdir)/../engine \ + -I$(srcdir)/../yacsloader \ + -I$(srcdir)/../runtime \ + -I$(KERNEL_ROOT_DIR)/include/salome \ + -I$(GUI_ROOT_DIR)/include/salome \ + $(OMNIORB_INCLUDES) \ + $(OMNIORB_CXXFLAGS) + +yacs_clt_LDFLAGS = $(PYTHON_EXTRA_LDFLAGS) -lexpat -pthread -lxml2 + +yacs_clt_LDADD = ../yacsloader/libYACSloader.la \ + ../runtime/libYACSRuntimeSALOME.la \ + ../engine/libYACSEngine.la \ + $(SALOME_LIBS) \ + $(OMNIORB_LIBS) \ + $(PYTHON_LDFLAGS) \ + $(PYTHON_EXTRA_LIBS) + +pkgpython_PYTHON = YACSGui.py + +install-exec-local: install-pyidl + +install-pyidl: $(IDL_FILES) + $(INSTALL) -d $(pkgpythondir) + @for file in $^ dummy; do \ + if [ $$file != "dummy" ]; then \ + $(OMNIORB_IDL) -bpython $(IDLPYFLAGS) -C$(pkgpythondir) $$file ; \ + fi ; \ + done ; + + +include $(top_srcdir)/adm/unix/make_end.am diff --git a/src/yacsorb/README.txt b/src/yacsorb/README.txt new file mode 100644 index 000000000..38669f299 --- /dev/null +++ b/src/yacsorb/README.txt @@ -0,0 +1,15 @@ +How to use yacsorb: + + 1- install yacs : ./configure;make;make install + 2- go to Install directory + 3- set environment : python, omniorb, ... + 4- launch demo calculation server : ./bin/echoSrv& (need omniorb name server) + 4 objects are registered in name server : Echo, Obj, C, D + 5- launch supervisor server : ./bin/yacsSrv & + supervisor object is registered in name server : Yacs + 6- launch the supervisor client : ./bin/yacs_clt + This client load the aschema.xml schema in supervisor and + requests its execution. An observer is registered to be notified about + status changes of all nodes in the schema. + When the observer is notified the status is printed. + The client can be launched many times without reinitializing the supervisor. diff --git a/src/yacsorb/YACSGui.py b/src/yacsorb/YACSGui.py new file mode 100644 index 000000000..f47876f82 --- /dev/null +++ b/src/yacsorb/YACSGui.py @@ -0,0 +1,185 @@ +# Copyright (C) 2005 CEA/DEN, EDF R&D +# +# 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 +# +import YACSGui_ORB__POA +import YACSGui_ORB +import SALOME_ComponentPy +import SALOME_DriverPy + +import threading +import tempfile + +import SALOMERuntime +import loader +import salomeloader +import pilot + +class proc_i(YACSGui_ORB__POA.ProcExec): + def __init__(self, xmlFile): + self.l = loader.YACSLoader() + self.e = pilot.ExecutorSwig() + self.p = self.l.load(xmlFile) + self.e.setExecMode(1) # YACS::STEPBYSTEP + self.run1 = None + pass + + def getNodeState(self,numid): + return self.p.getNodeState(numid) + + def getXMLState(self, numid): + return self.p.getXMLState(numid) + + def getExecutorState(self): + return self.e.getExecutorState() + + def getIds(self): + numids = self.p.getNumIds() + ids = self.p.getIds() + return (numids,ids) + + def getNumIds(self): + return self.p.getNumIds() + + def getNames(self): + return self.p.getIds() + + def Run(self): + execState = self.e.getExecutorState() + if execState >= 305: + # --- not clean, value from define.hxx + self.run1.join() + self.run1 = None + pass + if self.run1 is None: + self.run1 = threading.Thread(None, self.e.RunPy, "CORBAExec", (self.p,0)) + self.run1.start() + pass + pass + + def addObserver(self, obs, numid, event): + disp = SALOMERuntime.SALOMEDispatcher_getSALOMEDispatcher() + disp.addObserver(obs, numid, event) + pass + + def setExecMode(self, mode): + if mode == YACSGui_ORB.CONTINUE: + self.e.setExecMode(0) + pass + if mode == YACSGui_ORB.STEPBYSTEP: + self.e.setExecMode(1) + pass + if mode == YACSGui_ORB.STOPBEFORENODES: + self.e.setExecMode(2) + pass + pass + + def setListOfBreakPoints(self, listOfBreakPoints): + self.e.setListOfBreakPoints(listOfBreakPoints) + pass + + def getTasksToLoad(self): + return self.e.getTasksToLoad() + + def setStepsToExecute(self, listToExecute): + return self.e.setStepsToExecute(listToExecute) + + def resumeCurrentBreakPoint(self): + return self.e.resumeCurrentBreakPoint() + + def isNotFinished(self): + return self.e.isNotFinished() + + def stopExecution(self): + self.e.stopExecution() + pass + + def saveState(self, xmlFile): + return self.e.saveState(xmlFile) + + def setStopOnError(self, dumpRequested, xmlFile): + self.e.setStopOnError(dumpRequested, xmlFile) + pass + + pass + + +class YACSGui(YACSGui_ORB__POA.YACSGui_Gen, + SALOME_ComponentPy.SALOME_ComponentPy_i, + SALOME_DriverPy.SALOME_DriverPy_i): + """ + To be a SALOME component, this Python class must have the component name + (YACSGui) and inherit the YACSGui_Gen class build from idl compilation + with omniidl and also the class SALOME_ComponentPy_i which defines general + SALOME component behaviour. + """ + def __init__ ( self, orb, poa, contID, containerName, instanceName, + interfaceName ): + print "YACSGui.__init__: ", containerName, ';', instanceName + SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa, contID, + containerName, instanceName, + interfaceName, 0) + SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName) + + # --- store a naming service interface instance in _naming_service atribute + self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb ) + + + SALOMERuntime.RuntimeSALOME_setRuntime(1) + SALOMERuntime.SALOMEDispatcher_setSALOMEDispatcher() + pass + + def LoadProc(self,xmlFile): + """ + load an XML graph in a YACS::ENGINE::proc, create a CORBA servant + associated to the proc, and return a ref on the servant. + """ + try: + procExec_i = proc_i(xmlFile) + except IOError, ex: + print "IO Error: ", ex + return None + except ValueError,ex: + print "Caught ValueError Exception:",ex + return None + except pilot.Exception,ex: + print ex.what() + return None + except: + print "Unknown exception!" + return None + procExec_o = procExec_i._this() + return procExec_o + + def convertSupervFile(self,xmlFile): + """ + load a SUPERV xml graph, convert it and return the new filename. + """ + try: + r = pilot.getRuntime() + lo = salomeloader.SalomeLoader() + e = pilot.ExecutorSwig() + p = lo.load(xmlFile) + s = pilot.SchemaSave(p) + hnd, convertedFile = tempfile.mkstemp(".xml","yacs_","/tmp") + s.save(convertedFile) + return convertedFile + except (IndexError): + return "" + + pass + diff --git a/src/yacsorb/yacs.idl b/src/yacsorb/yacs.idl new file mode 100644 index 000000000..07b23ff4b --- /dev/null +++ b/src/yacsorb/yacs.idl @@ -0,0 +1,32 @@ +#ifndef __YACS_IDL__ +#define __YACS_IDL__ + +module YACS_ORB +{ + enum executionMode { CONTINUE, STEPBYSTEP, STOPBEFORENODES }; + + typedef sequence stringArray; + typedef sequence longArray; + + interface Observer + { + void notifyObserver(in long numid , in string event); + }; + + interface Proc + { + long getState(in long numid); + string getXMLState(in long numid); + void getIds(out longArray numids,out stringArray names); + }; + + interface YACS_Gen + { + Proc Load(in string xmlFile); + void Run(in Proc p); + void addObserver(in Observer obs,in long numid, in string event); + }; + +}; + +#endif diff --git a/src/yacsorb/yacsSrv.cxx b/src/yacsorb/yacsSrv.cxx new file mode 100644 index 000000000..c77de47f7 --- /dev/null +++ b/src/yacsorb/yacsSrv.cxx @@ -0,0 +1,290 @@ +#include +#include "RuntimeSALOME.hxx" +#include "Proc.hxx" +#include "Exception.hxx" +#include "Executor.hxx" +#include "Dispatcher.hxx" +#include "parsers.hxx" + +#include +#include +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; + +YACS::YACSLoader::YACSLoader* loader; +CORBA::ORB_ptr orb; +YACS_ORB::YACS_Gen_var myyacsref; + +class MyDispatcher:public YACS::ENGINE::Dispatcher +{ +public: + void dispatch(YACS::ENGINE::Node* object, const std::string& event) + { + std::cerr << "dispatch " << object->getNumId() << std::endl; + typedef std::set::iterator jt; + std::pair key(object->getNumId(),event); + for(jt iter=_observers[key].begin();iter!=_observers[key].end();iter++) + { + (*iter)->notifyObserver((CORBA::Long)object->getNumId(),event.c_str()); + } + } + + void addObserver(YACS_ORB::Observer_ptr observer,int numid, const std::string& event) + { + _observers[std::pair(numid,event)].insert(YACS_ORB::Observer::_duplicate(observer)); + // printObservers(); + } +protected: + std::map< std::pair , std::set > _observers; +}; + +class Yacs_i : public POA_YACS_ORB::YACS_Gen, + public PortableServer::RefCountServantBase +{ +public: + inline Yacs_i() {} + virtual ~Yacs_i() {} + YACS_ORB::Proc_ptr Load(const char* xmlFile); + void Run(YACS_ORB::Proc_ptr p); + void addObserver(YACS_ORB::Observer_ptr observer, CORBA::Long numid,const char* event); +}; + +class Proc_i : public POA_YACS_ORB::Proc, + public PortableServer::RefCountServantBase +{ +public: + inline Proc_i(YACS::ENGINE::Proc* p) {_proc=p;}; + virtual ~Proc_i() {}; + virtual void RunW(); + CORBA::Long getState(CORBA::Long numid); + char * getXMLState(CORBA::Long numid); + void getIds(YACS_ORB::longArray_out numids,YACS_ORB::stringArray_out names); +protected: + YACS::ENGINE::Executor _executor; + YACS::ENGINE::Proc* _proc; +}; + +void Proc_i::RunW() +{ + _executor.RunW(_proc,0); +} + +CORBA::Long Proc_i::getState(CORBA::Long numid) +{ + if(YACS::ENGINE::Node::idMap.count(numid) == 0) + { + std::cerr << "Unknown node id " << numid << std::endl; + return (CORBA::Long)-1; + } + YACS::ENGINE::Node* node= YACS::ENGINE::Node::idMap[numid]; + CORBA::Long state=node->getEffectiveState(); + return state; +} + +char * Proc_i::getXMLState(CORBA::Long numid) +{ + if(YACS::ENGINE::Node::idMap.count(numid) == 0) + { + std::cerr << "Unknown node id " << numid << std::endl; + return "unknown"; + } + YACS::ENGINE::Node* node= YACS::ENGINE::Node::idMap[numid]; + std::stringstream msg; + msg << "" << node->getEffectiveState() << ""; + msg << "" << node->getQualifiedName() << ""; + msg << "" << numid << ""; + return CORBA::string_dup(msg.str().c_str()); +} + +void Proc_i::getIds(YACS_ORB::longArray_out numids,YACS_ORB::stringArray_out names) +{ + std::set nodes=_proc->getAllRecursiveNodes(); + int len=nodes.size(); + names=new YACS_ORB::stringArray; + numids=new YACS_ORB::longArray; + names->length(len); + numids->length(len); + int i=0; + for(set::const_iterator iter=nodes.begin();iter!=nodes.end();iter++,i++) + { + (*names)[i]=CORBA::string_dup((*iter)->getQualifiedName().c_str()); + (*numids)[i]=(*iter)->getNumId(); + } +} + +YACS_ORB::Proc_ptr Yacs_i::Load(const char* xmlFile) +{ + YACS::ENGINE::Proc* proc=loader->load(xmlFile); + Proc_i* p=new Proc_i(proc); + YACS_ORB::Proc_ptr pp = p->_this(); + return pp; +} + +void Yacs_i::addObserver(YACS_ORB::Observer_ptr observer, CORBA::Long numid,const char* event) +{ + ((MyDispatcher*)YACS::ENGINE::Dispatcher::getDispatcher())->addObserver(observer,numid,event); +} + +void Yacs_i::Run(YACS_ORB::Proc_ptr p) +{ + Proc_i *servant=dynamic_cast (PortableServer::POA::_the_root_poa()->reference_to_servant(p)); + servant->RunW(); +} + +static CORBA::Boolean bindObjectToName(CORBA::ORB_ptr, CORBA::Object_ptr,const char*); +static ostream& operator<<(ostream& os, const CORBA::Exception& e); + +int main(int argc, char** argv) +{ + YACS::ENGINE::RuntimeSALOME::setRuntime(); + loader= new YACS::YACSLoader::YACSLoader(); + MyDispatcher* disp=new MyDispatcher(); + YACS::ENGINE::Dispatcher::setDispatcher(disp); + + 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 and activate servant + Yacs_i* myyacs = new Yacs_i(); + // Obtain a reference to the object, and print it out as a + // stringified IOR. + obj = myyacs->_this(); + CORBA::String_var sior(orb->object_to_string(obj)); + DEBTRACE("'" << (char*)sior << "'"); + myyacsref = YACS_ORB::YACS_Gen::_narrow(obj); + + if( !bindObjectToName(orb, myyacsref,"Yacs") ) 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. + myyacs->_remove_ref(); + } + orb->run(); + } + catch(CORBA::SystemException&) { + DEBTRACE("Caught CORBA::SystemException."); + } + catch(CORBA::Exception& ex) { + DEBTRACE("Caught CORBA::Exception." << ex); + } + catch(omniORB::fatalException& fe) { + DEBTRACE("Caught omniORB::fatalException:"); + DEBTRACE(" file: " << fe.file()); + DEBTRACE(" line: " << fe.line()); + DEBTRACE(" mesg: " << fe.errmsg()); + } + catch(...) { + DEBTRACE("Caught unknown exception." ); + } + + return 0; +} + + +////////////////////////////////////////////////////////////////////// + +static CORBA::Boolean +bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref,const char *name) +{ + 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) ) { + DEBTRACE("Failed to narrow the root naming context."); + return 0; + } + } + catch(CORBA::ORB::InvalidName& ex) { + // This should not happen! + DEBTRACE("Service required is invalid [does not exist]." ); + 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) ) { + DEBTRACE("Failed to narrow naming context."); + return 0; + } + } + + // Bind objref with name name to the testContext: + CosNaming::Name objectName; + objectName.length(1); + objectName[0].id = name; // string copied + objectName[0].kind = (const char*) "Object"; // string copied + + try { + testContext->bind(objectName, objref); + } + catch(CosNaming::NamingContext::AlreadyBound& ex) { + testContext->rebind(objectName, objref); + } + } + catch(CORBA::COMM_FAILURE& ex) { + DEBTRACE("Caught system exception COMM_FAILURE -- unable to contact the " + << "naming service."); + return 0; + } + catch(CORBA::SystemException&) { + DEBTRACE("Caught a CORBA::SystemException while using the naming service."); + return 0; + } + + return 1; +} + +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; +} diff --git a/src/yacsorb/yacs_clt.cxx b/src/yacsorb/yacs_clt.cxx new file mode 100644 index 000000000..d74014c51 --- /dev/null +++ b/src/yacsorb/yacs_clt.cxx @@ -0,0 +1,109 @@ +#include +#include "RuntimeSALOME.hxx" +#include "Proc.hxx" +#include "parsers.hxx" + +#include +#include +#include +#include + +YACS::YACSLoader::YACSLoader* loader; + +class Obs_i : public POA_YACS_ORB::Observer, + public PortableServer::RefCountServantBase +{ +public: + inline Obs_i(YACS_ORB::Proc_ptr proc) {_server_proc=proc;} + virtual ~Obs_i() {} + void notifyObserver(CORBA::Long numid, const char* event); +protected: + YACS_ORB::Proc_ptr _server_proc; +}; + +void Obs_i::notifyObserver(CORBA::Long numid, const char* event) +{ + std::cerr << "Obs_i::notifyObserver " << numid << event << std::endl; + std::cerr << "Obs_i::notifyObserver:state= " << _server_proc->getState(numid) << std::endl; + std::cerr << "Obs_i::notifyObserver:XMLstate= " << _server_proc->getXMLState(numid) << std::endl; +} + +YACS_ORB::YACS_Gen_var yacsref; +YACS_ORB::Proc_ptr server_proc; + +void * run(void *obj) +{ + yacsref->Run(server_proc); +} + +int main(int argc, char** argv) +{ + YACS::ENGINE::RuntimeSALOME::setRuntime(); + loader= new YACS::YACSLoader::YACSLoader(); + + try + { + CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); + CORBA::Object_var obj = orb->string_to_object("corbaname:rir:#test.my_context/Yacs.Object"); + yacsref = YACS_ORB::YACS_Gen::_narrow(obj); + if( CORBA::is_nil(yacsref) ) + { + std::cerr << "Can't narrow reference to type yacs (or it was nil)." << std::endl; + return 1; + } + + //Activate POA + CORBA::Object_var poa = orb->resolve_initial_references("RootPOA"); + PortableServer::POA_var root_poa = PortableServer::POA::_narrow(poa); + PortableServer::POAManager_var poa_man = root_poa->the_POAManager(); + poa_man->activate(); + + char* xmlFile="/local/chris/SALOME2/SUPERV/YACS/BR_CC/YACS_SRC/src/yacsloader/samples/aschema.xml"; + //Load XML file in client + YACS::ENGINE::Proc* local_proc=loader->load(xmlFile); + //Load xml file in server + server_proc = yacsref->Load(xmlFile); + //Create an observer for server_proc + Obs_i* obs=new Obs_i(server_proc); + YACS_ORB::Observer_ptr obs_ptr = obs->_this(); + //Get ids and names + YACS_ORB::stringArray_var names; + YACS_ORB::longArray_var ids; + server_proc->getIds(ids.out(),names.out()); + //Register it + int len=ids->length(); + int numid; + for(int i=0;iaddObserver(obs_ptr,numid,"status"); + } + //Execute Proc in thread ?? + pthread_t th; + //pthread_create(&th,NULL,run,0); + yacsref->Run(server_proc); + + //orb->run(); + orb->destroy(); + } + catch(CORBA::COMM_FAILURE& ex) { + std::cerr << "Caught system exception COMM_FAILURE -- unable to contact the " + << "object." << std::endl; + } + catch(CORBA::SystemException&) { + std::cerr << "Caught a CORBA::SystemException." << std::endl; + } + catch(CORBA::Exception&) { + std::cerr << "Caught CORBA::Exception." << std::endl; + } + catch(omniORB::fatalException& fe) { + std::cerr << "Caught omniORB::fatalException:" << std::endl; + std::cerr << " file: " << fe.file() << std::endl; + std::cerr << " line: " << fe.line() << std::endl; + std::cerr << " mesg: " << fe.errmsg() << std::endl; + } + catch(...) { + std::cerr << "Caught unknown exception." << std::endl; + } + return 0; +} -- 2.30.2