From 073a4cf9832011ca30f834a9171ce4cb0bdb1b79 Mon Sep 17 00:00:00 2001 From: Dan King Date: Fri, 6 Aug 2021 14:25:13 -0400 Subject: [PATCH 01/14] first commit of Modern C++17 conversion. --- ChocolateFactory/.gitignore | 4 + .../cmake/ConnextDdsArgumentChecks.cmake | 32 + .../ExampleCode/cmake/ConnextDdsCodegen.cmake | 794 +++++++ .../ExampleCode/cmake/FindRTIConnextDDS.cmake | 1939 +++++++++++++++++ .../ExampleCode/make/Makefile.common | 194 -- .../make/Makefile.x64Linux3gcc5.4.0 | 32 - .../make/Makefile.x64Linux4gcc7.3.0 | 32 - .../scripts/AllStationControllers.sh | 17 +- ChocolateFactory/ExampleCode/scripts/MES.sh | 7 +- .../ExampleCode/scripts/RecipeGenerator.sh | 7 +- .../ExampleCode/scripts/StationController.sh | 7 +- .../ExampleCode/src/CMakeLists.txt | 87 + .../ChocolateLotStateEntities.cxx | 589 ++--- .../ChocolateLotStateEntities.h | 143 -- .../ChocolateLotStateEntities.hpp | 121 + .../CommonInfrastructure/DDSCommunicator.cxx | 393 +--- .../CommonInfrastructure/DDSCommunicator.h | 216 -- .../CommonInfrastructure/DDSCommunicator.hpp | 77 + .../src/CommonInfrastructure/DDSTypeWrapper.h | 95 - .../CommonInfrastructure/EnumPrintHelpers.cxx | 169 +- .../CommonInfrastructure/EnumPrintHelpers.h | 64 - .../CommonInfrastructure/EnumPrintHelpers.hpp | 63 + .../src/CommonInfrastructure/InputParser.cxx | 35 + .../src/CommonInfrastructure/InputParser.hpp | 29 + .../src/CommonInfrastructure/OSAPI.cxx | 77 - .../src/CommonInfrastructure/OSAPI.h | 111 - .../src/Config/base_profile_multicast.xml | 97 +- .../src/Config/base_profile_no_multicast.xml | 100 +- .../src/Config/recipe_profiles_multicast.xml | 158 +- .../Config/recipe_profiles_no_multicast.xml | 158 +- .../ExampleCode/src/Idl/ChocolateFactory.idl | 2 +- .../MESInterface.cxx | 170 +- .../MESInterface.h | 110 - .../MESInterface.hpp | 99 + .../ManufacturingExecutionSystem.cxx | 427 ++-- .../src/RecipeGenerator/RecipeGenerator.cxx | 312 ++- .../RecipePublisherInterface.cxx | 168 +- .../RecipePublisherInterface.h | 82 - .../RecipePublisherInterface.hpp | 74 + .../StationController/StationController.cxx | 643 +++--- .../src/StationController/StationController.h | 48 - .../StationController/StationController.hpp | 40 + .../StationControllerInterface.cxx | 353 +-- .../StationControllerInterface.h | 248 --- .../StationControllerInterface.hpp | 179 ++ .../ExampleCode/win/MES_vs2017.vcxproj | 32 +- .../win/RecipeGenerator_vs2017.vcxproj | 28 +- .../win/SharedDataTypes_vs2017.vcxproj | 22 +- .../win/StationController_vs2017.vcxproj | 26 +- ChocolateFactory/README.md | 63 +- 50 files changed, 4889 insertions(+), 4084 deletions(-) create mode 100644 ChocolateFactory/.gitignore create mode 100644 ChocolateFactory/ExampleCode/cmake/ConnextDdsArgumentChecks.cmake create mode 100644 ChocolateFactory/ExampleCode/cmake/ConnextDdsCodegen.cmake create mode 100644 ChocolateFactory/ExampleCode/cmake/FindRTIConnextDDS.cmake delete mode 100644 ChocolateFactory/ExampleCode/make/Makefile.common delete mode 100644 ChocolateFactory/ExampleCode/make/Makefile.x64Linux3gcc5.4.0 delete mode 100644 ChocolateFactory/ExampleCode/make/Makefile.x64Linux4gcc7.3.0 create mode 100644 ChocolateFactory/ExampleCode/src/CMakeLists.txt delete mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.h create mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.hpp delete mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.h create mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp delete mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSTypeWrapper.h delete mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/EnumPrintHelpers.h create mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/EnumPrintHelpers.hpp create mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/InputParser.cxx create mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/InputParser.hpp delete mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/OSAPI.cxx delete mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/OSAPI.h delete mode 100644 ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.h create mode 100644 ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp delete mode 100644 ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.h create mode 100644 ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp delete mode 100644 ChocolateFactory/ExampleCode/src/StationController/StationController.h create mode 100644 ChocolateFactory/ExampleCode/src/StationController/StationController.hpp delete mode 100644 ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.h create mode 100644 ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp diff --git a/ChocolateFactory/.gitignore b/ChocolateFactory/.gitignore new file mode 100644 index 00000000..574e9b6a --- /dev/null +++ b/ChocolateFactory/.gitignore @@ -0,0 +1,4 @@ +# Folders # +########### +win/ +build/ \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/cmake/ConnextDdsArgumentChecks.cmake b/ChocolateFactory/ExampleCode/cmake/ConnextDdsArgumentChecks.cmake new file mode 100644 index 00000000..bcd4dd82 --- /dev/null +++ b/ChocolateFactory/ExampleCode/cmake/ConnextDdsArgumentChecks.cmake @@ -0,0 +1,32 @@ +# (c) 2017 Copyright, Real-Time Innovations, Inc. All rights reserved. +# No duplications, whole or partial, manual or electronic, may be made +# without express written permission. Any such copies, or revisions thereof, +# must display this notice unaltered. +# This code contains trade secrets of Real-Time Innovations, Inc. + +#[[.rst: +.. _connextdds_argument_checks: + +ConnextDdsArgumentChecks +------------------------ + +Function helpers to check function arguments + +``connextdds_check_required_arguments`` + Checks that all of the arguments are present and defined + +#]] + +function(connextdds_check_required_arguments) + foreach(arg ${ARGN}) + if(NOT ${arg}) + message(FATAL_ERROR "Argument ${arg} is missing") + endif() + endforeach() +endfunction() + +macro(connextdds_check_no_extra_arguments) + if(ARGN) + message(FATAL_ERROR "Function has more arguments than expected") + endif() +endmacro() diff --git a/ChocolateFactory/ExampleCode/cmake/ConnextDdsCodegen.cmake b/ChocolateFactory/ExampleCode/cmake/ConnextDdsCodegen.cmake new file mode 100644 index 00000000..ccab2daa --- /dev/null +++ b/ChocolateFactory/ExampleCode/cmake/ConnextDdsCodegen.cmake @@ -0,0 +1,794 @@ +# (c) 2017 Copyright, Real-Time Innovations, Inc. All rights reserved. +# No duplications, whole or partial, manual or electronic, may be made +# without express written permission. Any such copies, or revisions thereof, +# must display this notice unaltered. +# This code contains trade secrets of Real-Time Innovations, Inc. + +#[[.rst: +.. _connextdds_codegen: + +ConnextDdsCodegen +----------------- + +CodeGen usage functions. + + +.. _connextdds_rtiddsgen_run: + +Code generation +^^^^^^^^^^^^^^^ + +Generate a source files using RTI Codegen:: + + connextdds_rtiddsgen_run( + LANG + OUTPUT_DIRECTORY + IDL_FILE + [VAR variable] + [NOT_REPLACE] + [PACKAGE package] + [DISABLE_PREPROCESSOR] + [INCLUDE_DIRS ...] + [DEFINES ...] + [UNBOUNDED] + [NO_TYPECODE] + [IGNORE_ALIGNMENT] + [USE42_ALIGNMENT] + [OPTIMIZE_ALIGNMENT] + [LEGACY_PLUGIN] + [STANDALONE] + [EXTRA_ARGS ...] + [USE_CODEGEN1] + [GENERATE_EXAMPLE] + ) + +This function calls ``codegen`` (rtiddsgen) to generates source files for the +language ``LANG`` passed as an argument to the function. + +Arguments: + +``IDL_FILE`` (mandatory) + The IDL filename that will be used to generate code + +``OUTPUT_DIRECTORY`` (mandatory) + The directory where to put generated files + +``LANG`` (mandatory) + The language to generate source files for. Expected values are: + C, C++, C++03, C++11, C++/CLI, C# and Java. + +``VAR`` + Use ``VAR`` as a prefix instead of using the IDL basename to name return + values. + +``NOT_REPLACE`` (optional) + By default, we call ``codegen`` with the ``-replace`` argument, so every time + the input IDL file has changed, we regenerate the source files. Passing this + argument disables the flag. + +``UNBOUNDED`` (optional) + Generate type files with unbounded support (``-unboundedSupport``) flag. + +``PACKAGE`` (optional) + Specify the package name for Java source type files. + +``IGNORE_ALIGNMENT`` (optional) + Generate type files with -ignoreAlignment flag enabled + +``USE42_ALIGNMENT`` (optional) + Generate type files with 4.2 compatible alignment (``-use42eAlignment`` flag) + +``OPTIMIZE_ALIGNMENT`` (optional) + Generate code with optimized alignment + +``NO_TYPECODE`` (optional) + Do not generate TypeCode in generated files + +``DISABLE_PREPROCESSOR`` (optional) + Disable the use of a preprocessor in Codegen + +``LEGACY_PLUGIN`` (optional) + Use the legacy types for C++ 03 and C++ 11. + +``STANDALONE`` (optional) + Generate typecode files independant to RTI Connext DDS libraries. + +``INCLUDE_DIRS`` (optional) + List of include directories passed to Codegen (-I flag) + +``DEFINES`` (optional) + List of definitions passed to Codegen as arguments (-D flag) + +``EXTRA_ARGS`` (optional) + Extra arguments added to the Codegen command line + +``USE_CODEGEN1`` (optional) + Use rtiddsgen1. + +``GENERATE_EXAMPLE`` (optional) + Generate the source code for the publisher and subscriber. + +Output values: +The language variable is sanitized according to +:ref:`connextdds_sanitize_language` for the variable name. + +``__SOURCES`` + The list of generated source files. Empty for Java (see note below). + +``__HEADERS`` + The list of generated header files. Empty for Java (see note below). + +``__TIMESTAMP`` + Only used when generating code for Java. This is a dummy empty file that + triggers the code generation when it doesn't exist or its modification + time is before the IDL file. CMake will touch this file after each call to + rtiddsgen. + +If ``VAR`` is passed as a parameter, the variable name will be named like this: + +``__SOURCES`` + The list of the generated source files for the types. Empty for Java (see + note below). + +``__HEADERS`` + The list of generated header files. Empty for Java (see note below). + +``__GENERATED_SOURCES`` + The list of generated source files. Empty for Java (see note below). + +``__PUBLISHER_SOURCE`` + Source code for the publisher if the example code was generated (see note + below). + +``__SUBSCRIBER_SOURCE`` + Source code for the subscriber if the example code was generated (see note + below). + +``__TIMESTAMP`` + Only used when generating code for Java. This is a dummy empty file that + triggers the code generation when it doesn't exist or its modification + time is before the IDL file. CMake will touch this file after each call to + rtiddsgen. + +.. note:: + + In the case of Java the function won't return the list of source and + header files. Instead, it will set the timestamp variable to a dummy file. + A CMake target must depend on this file to trigger and handle the code + generation. The reason is that to get the full list of Java generated + files the function would need to get this information from CodeGen. + Otherwise it would need to know the full IDL structure because for each + IDL type a new file Java is created and for each module a new subfolder. + +.. _connextdds_rtiddsgen_convert: + +Convert +^^^^^^^ +:: + + connextdds_rtiddsgen_convert( + INPUT inputFile + FROM format + TO format + [VAR variable] + [OUTPUT_DIRECTORY outputPath] + [NOT_REPLACE] + [INCLUDE_DIRS ...] + [DEFINES ...] + [EXTRA_ARGS ...] + [DEPENDS ...] + [USE_CODEGEN1] + ) + +Call rtiddsgen to convert the format of the type representation +(IDL, XML or XSD). + +``INPUT`` (required): + The path to the input file. + +``FROM`` (required) + The input format. Accepted values are ``IDL``, ``XML`` and ``XSD``. + +``TO`` (required) + The output format. Accepted values are ``IDL``, ``XML`` and ``XSD``. + +``VAR`` (optional) + The name of the variable to set the output file. + +``OUTPUT_DIRECTORY`` (optional) + The directory to save the output file. + +``NOT_REPLACE`` (optional) + By default the command will overwrite any existing file. Set this file to + skip converting if the output exists. + +``INCLUDE_DIRS`` (optional) + Additional include directory for the Codegen preprocessor. + +``DEFINES`` (optional) + Additional definitions for the Codegen preprocessor. + +``EXTRA_ARGS`` (optional) + Additional flags for Codegen. + +``DEPENDS`` (optional) + CMake dependencies for this command. + +``USE_CODEGEN1`` (optional) + Use rtiddsgen1. + + +.. _connextdds_sanitize_language: + +Sanitize Language +^^^^^^^^^^^^^^^^^ +:: + + connextdds_sanitize_language( + LANG language + VAR variable + ) + +Get the sanitized version of the language to use in variable names. This output +is used by the CodeGen functions to create the default variable names. It will +make the following replacement: + +* Replace ``+`` with ``X`` (i.e.: C++11 --> CXX11) +* Replace ``#`` with ``Sharp`` (i.e.: C# --> CSharp) +* Remove ``/`` (i.e.: C++/CLI --> CXXCLI) +#]] + +include(CMakeParseArguments) +include(ConnextDdsArgumentChecks) + +macro(_connextdds_codegen_find_codegen use_codegen1) + if(WIN32) + set(script_ext ".bat") + else() + set(script_ext "") + endif() + + if(${use_codegen1}) + # CodeGen 1 doesn't support server mode. + set(script_name "rtiddsgen1") + elseif(CONNEXTDDS_USE_CODEGEN_SERVER) + set(script_name "rtiddsgen_server") + else() + set(script_name "rtiddsgen") + endif() + + set(CODEGEN_PATH "${RTICODEGEN_DIR}/${script_name}${script_ext}") + + # Get the absolute path to avoid problems during build time. + # Otherwise the relative path will go into the module makefiles where + # the working directory is different. + get_filename_component(CODEGEN_PATH "${CODEGEN_PATH}" + ABSOLUTE + BASE_DIR "${CMAKE_BINARY_DIR}" + ) + + # We assume that external RTICODEGEN_DIR provides their own JRE because. + # The same for the JNI JVM libraries: a Codegen staging + # allows to rticommon.sh to find and update the path with the library. + set(additional_env) + set(lib_search_def) + if(TARGET rtiddsgen2) + get_filename_component(JRE_BIN_DIR ${Java_JAVA_EXECUTABLE} DIRECTORY) + get_filename_component(JREHOME ${JRE_BIN_DIR} DIRECTORY) + list(APPEND additional_env "JREHOME=${JREHOME}") + + # For CodeGen server we need JNI JVM + if(CONNEXTDDS_USE_CODEGEN_SERVER) + connextdds_get_library_search_path_definition( + OUTPUT lib_search_def + DIRECTORIES + ${JNI_LIBRARY_DIRS} + ) + endif() + endif() + + # For CodeGen 1 we need to set also the Xalan path + if(${use_codegen1}) + list(APPEND additional_env "XALANHOME=${XALANJ_LIBRARIES_DIR}") + endif() + + if(additional_env OR codegen_ld_env) + set(CODEGEN_COMMAND + ${CMAKE_COMMAND} -E env + "\"${lib_search_def}\"" + ${additional_env} + ${CODEGEN_PATH} + ) + else() + set(CODEGEN_COMMAND ${CODEGEN_PATH}) + endif() + + if(NOT RTICODEGEN_DIR) + message(FATAL_ERROR + "Missing RTICODEGEN_DIR variable. Please, call the find_package" + "CMake built-in macro for the RTIConnextDDS package" + ) + elseif(NOT EXISTS ${RTICODEGEN_DIR}) + message(FATAL_ERROR + "RTICODEGEN_DIR dir doesn't exist: ${RTICODEGEN_DIR}") + endif() +endmacro() + +# Helper function to determine the generated files based on the language +# Supported languages are: C C++ Java C++/CLI C++03 C++11 C# +function(_connextdds_codegen_get_generated_file_list) + set(options LEGACY_PLUGIN STANDALONE DEBUG NO_CODE_GENERATION GENERATE_EXAMPLE) + set(single_value_args VAR LANG PACKAGE IDL_BASENAME OUTPUT_DIR) + set(multi_value_args "") + cmake_parse_arguments(_CODEGEN + "${options}" + "${single_value_args}" + "${multi_value_args}" + ${ARGN} + ) + + set(path_base "${_CODEGEN_OUTPUT_DIR}/${_CODEGEN_IDL_BASENAME}") + set(timestamp_dir ${_CODEGEN_OUTPUT_DIR}) + + if("${_CODEGEN_LANG}" STREQUAL "C") + set(sources "${path_base}.c") + set(headers "${path_base}.h") + if(NOT _CODEGEN_STANDALONE) + list(APPEND sources "${path_base}Plugin.c" "${path_base}Support.c") + list(APPEND headers "${path_base}Plugin.h" "${path_base}Support.h") + endif() + + # Set in the parent scope + set(${_CODEGEN_VAR}_HEADERS ${headers} PARENT_SCOPE) + + if(_CODEGEN_GENERATE_EXAMPLE) + set(${_CODEGEN_VAR}_PUBLISHER_SOURCE + "${path_base}_publisher.c" + PARENT_SCOPE) + set(${_CODEGEN_VAR}_SUBSCRIBER_SOURCE + "${path_base}_subscriber.c" + PARENT_SCOPE) + set(${_CODEGEN_VAR}_SOURCES + ${sources} + PARENT_SCOPE) + set(${_CODEGEN_VAR}_GENERATED_SOURCES + ${sources} + "${path_base}_publisher.c" + "${path_base}_subscriber.c" + PARENT_SCOPE) + else() + set(${_CODEGEN_VAR}_SOURCES ${sources} PARENT_SCOPE) + set(${_CODEGEN_VAR}_GENERATED_SOURCES ${sources} PARENT_SCOPE) + set(${_CODEGEN_VAR}_PUBLISHER_SOURCE PARENT_SCOPE) + set(${_CODEGEN_VAR}_SUBSCRIBER_SOURCE PARENT_SCOPE) + endif() + + elseif("${_CODEGEN_LANG}" STREQUAL "C++") + set(sources "${path_base}.cxx") + set(headers "${path_base}.h") + + if(NOT _CODEGEN_STANDALONE) + list(APPEND sources "${path_base}Plugin.cxx" "${path_base}Support.cxx") + list(APPEND headers "${path_base}Plugin.h" "${path_base}Support.h") + endif() + + if(${_CODEGEN_GENERATE_EXAMPLE}) + set(${_CODEGEN_VAR}_PUBLISHER_SOURCE + "${path_base}_publisher.cxx" + ${sources} + PARENT_SCOPE) + set(${_CODEGEN_VAR}_SUBSCRIBER_SOURCE + "${path_base}_subscriber.cxx" + ${sources} + PARENT_SCOPE) + set(${_CODEGEN_VAR}_SOURCES + ${sources} + PARENT_SCOPE) + set(${_CODEGEN_VAR}_GENERATED_SOURCES + ${sources} + "${path_base}_publisher.cxx" + "${path_base}_subscriber.cxx" + PARENT_SCOPE) + else() + # Set in the parent scope + set(${_CODEGEN_VAR}_SOURCES ${sources} PARENT_SCOPE) + set(${_CODEGEN_VAR}_HEADERS ${headers} PARENT_SCOPE) + endif() + + elseif("${_CODEGEN_LANG}" STREQUAL "C#" + OR "${_CODEGEN_LANG}" STREQUAL "C++/CLI") + set(${_CODEGEN_VAR}_SOURCES + "${path_base}.cpp" + "${path_base}Plugin.cpp" + "${path_base}Support.cpp" + PARENT_SCOPE) + set(${_CODEGEN_VAR}_HEADERS + "${path_base}.h" + "${path_base}Plugin.h" + "${path_base}Support.h" + PARENT_SCOPE) + + if(${_CODEGEN_GENERATE_EXAMPLE}) + set(${_CODEGEN_VAR}_PUBLISHER_SOURCE + "${path_base}_publisher.cpp" + PARENT_SCOPE) + set(${_CODEGEN_VAR}_SUBSCRIBER_SOURCE + "${path_base}_subscriber.cpp" + PARENT_SCOPE) + set(${_CODEGEN_VAR}_GENERATED_SOURCES + ${${_CODEGEN_VAR}_SOURCES} + "${path_base}_publisher.cpp" + "${path_base}_subscriber.cpp" + PARENT_SCOPE) + endif() + elseif("${_CODEGEN_LANG}" STREQUAL "C++03" + OR "${_CODEGEN_LANG}" STREQUAL "C++11") + if(_CODEGEN_LEGACY_PLUGIN) + set(sources + "${path_base}.cxx" + "${path_base}Impl.cxx" + "${path_base}ImplPlugin.cxx" + ) + set(${_CODEGEN_VAR}_HEADERS + "${path_base}.hpp" + "${path_base}Impl.h" + "${path_base}ImplPlugin.h" + PARENT_SCOPE) + else() + set(sources + "${path_base}.cxx" + "${path_base}Plugin.cxx" + ) + set(${_CODEGEN_VAR}_HEADERS + "${path_base}.hpp" + "${path_base}Plugin.hpp" + PARENT_SCOPE) + endif() + + if(${_CODEGEN_GENERATE_EXAMPLE}) + set(${_CODEGEN_VAR}_PUBLISHER_SOURCE + "${path_base}_publisher.cxx" + PARENT_SCOPE) + set(${_CODEGEN_VAR}_SUBSCRIBER_SOURCE + "${path_base}_subscriber.cxx" + PARENT_SCOPE) + set(${_CODEGEN_VAR}_SOURCES ${sources} PARENT_SCOPE) + set(${_CODEGEN_VAR}_GENERATED_SOURCES ${sources} PARENT_SCOPE) + else() + # Set in the parent scope + set(${_CODEGEN_VAR}_GENERATED_SOURCES ${sources} PARENT_SCOPE) + set(${_CODEGEN_VAR}_SOURCES ${sources} PARENT_SCOPE) + set(${_CODEGEN_VAR}_HEADERS ${headers} PARENT_SCOPE) + set(${_CODEGEN_VAR}_PUBLISHER_SOURCE PARENT_SCOPE) + set(${_CODEGEN_VAR}_SUBSCRIBER_SOURCE PARENT_SCOPE) + endif() + elseif("${_CODEGEN_LANG}" STREQUAL "Java") + # Avoid conflicts generating the same IDL but different package flag. + # For instance, this happens with corbaInterop in CodeGen 1. + if(_CODEGEN_PACKAGE) + set(timestamp_dir "${_CODEGEN_OUTPUT_DIR}/${_CODEGEN_PACKAGE}") + endif() + else() + message(FATAL_ERROR "Language ${_CODEGEN_LANG} is not supported") + endif() + + # Java File names depends on struct names to generate files, not on + # IDL file name. IDL usually contains more than one structure so we + # can't guess the source files if we don't know the structure names. + # For that reason we use a timestamp file. We create the timestamp file + # for all the languages to avoid complex logic. + set(TIMESTAMP_DIR ${timestamp_dir} PARENT_SCOPE) + set(TIMESTAMP + "${timestamp_dir}/${_CODEGEN_IDL_BASENAME}_timestamp.cmake" + PARENT_SCOPE) + + if(_CODEGEN_DEBUG) + set(${_CODEGEN_VAR}_SOURCES + ${${_CODEGEN_VAR}_SOURCES} + "${path_base}.idl.rawxml" + "${path_base}.idl.simplifiedxml" + PARENT_SCOPE) + endif() +endfunction() + +function(connextdds_sanitize_language) + cmake_parse_arguments(_LANG "" "LANG;VAR" "" ${ARGN}) + connextdds_check_required_arguments(_LANG_LANG _LANG_VAR) + + # Replaces C++ by CXX and C# by CSharp. Removes / for C++/CLI + string(TOUPPER ${_LANG_LANG} lang_var) + string(REPLACE "+" "X" lang_var ${lang_var}) + string(REPLACE "/" "" lang_var ${lang_var}) + string(REPLACE "#" "Sharp" lang_var ${lang_var}) + + # Define variable in the caller + set(${_LANG_VAR} ${lang_var} PARENT_SCOPE) +endfunction() + +function(connextdds_rtiddsgen_run) + set(options + NOT_REPLACE UNBOUNDED IGNORE_ALIGNMENT USE42_ALIGNMENT + OPTIMIZE_ALIGNMENT NO_TYPECODE DISABLE_PREPROCESSOR LEGACY_PLUGIN + STANDALONE USE_CODEGEN1 DEBUG NO_CODE_GENERATION GENERATE_EXAMPLE + ) + set(single_value_args LANG OUTPUT_DIRECTORY IDL_FILE VAR PACKAGE) + set(multi_value_args INCLUDE_DIRS DEFINES EXTRA_ARGS) + cmake_parse_arguments(_CODEGEN + "${options}" + "${single_value_args}" + "${multi_value_args}" + ${ARGN} + ) + connextdds_check_required_arguments( + _CODEGEN_IDL_FILE + _CODEGEN_LANG + _CODEGEN_OUTPUT_DIRECTORY + ) + + if(_CODEGEN_DEBUG AND NOT _CODEGEN_USE_CODEGEN1) + message(FATAL_ERROR "The debug option is only available in rtiddsgen1") + endif() + if(_CODEGEN_NO_CODE_GENERATION AND NOT _CODEGEN_USE_CODEGEN1) + message(FATAL_ERROR + "The noCodeGeneration option is only available in rtiddsgen1" + ) + endif() + + if(_CODEGEN_USE_CODEGEN1) + set(use_codegen1 TRUE) + else() + set(use_codegen1 FALSE) + endif() + _connextdds_codegen_find_codegen(${use_codegen1}) + + file(MAKE_DIRECTORY "${_CODEGEN_OUTPUT_DIRECTORY}") + get_filename_component(idl_basename "${_CODEGEN_IDL_FILE}" NAME_WE) + + set(list_extra_args) + if(_CODEGEN_LEGACY_PLUGIN) + list(APPEND list_extra_args LEGACY_PLUGIN) + endif() + if(_CODEGEN_STANDALONE) + list(APPEND list_extra_args STANDALONE) + endif() + if(_CODEGEN_DEBUG) + list(APPEND list_extra_args DEBUG) + endif() + if(_CODEGEN_NO_CODE_GENERATION) + list(APPEND list_extra_args NO_CODE_GENERATION) + endif() + + if(_CODEGEN_GENERATE_EXAMPLE) + set(generate_example GENERATE_EXAMPLE) + endif() + + _connextdds_codegen_get_generated_file_list( + VAR IDL + IDL_BASENAME ${idl_basename} + LANG ${_CODEGEN_LANG} + OUTPUT_DIR "${_CODEGEN_OUTPUT_DIRECTORY}" + PACKAGE ${_CODEGEN_PACKAGE} + ${generate_example} + ${list_extra_args} + ) + + set(include_dirs) + foreach(dir ${_CODEGEN_INCLUDE_DIRS}) + list(APPEND include_dirs -I "${dir}") + endforeach() + + set(defines) + foreach(def ${_CODEGEN_DEFINES}) + list(APPEND defines -D${def}) + endforeach() + + # Create the extra / optional arguments + set(extra_flags "${_CODEGEN_EXTRA_ARGS}") + if(_CODEGEN_IGNORE_ALIGNMENT) + list(APPEND extra_flags "-ignoreAlignment") + endif() + + if(_CODEGEN_LEGACY_PLUGIN) + list(APPEND extra_flags "-legacyPlugin") + endif() + + if(_CODEGEN_USE42_ALIGNMENT) + list(APPEND extra_flags "-use42eAlignment") + endif() + + if(_CODEGEN_OPTIMIZE_ALIGNMENT) + list(APPEND extra_flags "-optimizeAlignment") + endif() + + if(_CODEGEN_NO_TYPECODE OR _CODEGEN_STANDALONE) + list(APPEND extra_flags "-noTypeCode") + endif() + + if(_CODEGEN_UNBOUNDED) + list(APPEND extra_flags "-unboundedSupport") + endif() + + if(_CODEGEN_DISABLE_PREPROCESSOR) + list(APPEND extra_flags "-ppDisable") + endif() + + if(_CODEGEN_PACKAGE) + list(APPEND extra_flags "-package" "${_CODEGEN_PACKAGE}") + endif() + + if(_CODEGEN_DEBUG) + list(APPEND extra_flags "-debug") + endif() + + if(_CODEGEN_NO_CODE_GENERATION) + list(APPEND extra_flags "-noCodeGeneration") + endif() + + # By default we overwrite all the generated files + if(NOT _CODEGEN_NOT_REPLACE) + list(APPEND extra_flags "-replace") + endif() + + if(_CODEGEN_GENERATE_EXAMPLE) + list(APPEND extra_flags "-example" ${CONNEXTDDS_ARCH}) + endif() + + # Call CodeGen + add_custom_command( + OUTPUT + ${IDL_SOURCES} + ${IDL_HEADERS} + ${TIMESTAMP} + ${IDL_PUBLISHER_SOURCE} + ${IDL_SUBSCRIBER_SOURCE} + COMMAND + ${CMAKE_COMMAND} -E make_directory ${_CODEGEN_OUTPUT_DIRECTORY} + COMMAND + ${CODEGEN_COMMAND} + ${include_dirs} ${defines} + ${extra_flags} + -language ${_CODEGEN_LANG} + -d ${_CODEGEN_OUTPUT_DIRECTORY} + ${_CODEGEN_IDL_FILE} + # For the case of Java where we can't guess the source files. + # It shouldn't harm in other cases. + COMMAND + ${CMAKE_COMMAND} -E make_directory ${TIMESTAMP_DIR} + COMMAND + ${CMAKE_COMMAND} -E touch ${TIMESTAMP} + DEPENDS + "${_CODEGEN_IDL_FILE}" + ) + + # Get the name of the language variables (i.e.: C++/CLI -> CXXCLI). + connextdds_sanitize_language(LANG ${_CODEGEN_LANG} VAR lang_var) + + if(_CODEGEN_VAR) + set(var_prefix "${_CODEGEN_VAR}") + else() + set(var_prefix "${idl_basename}") + endif() + + # Exports the files generated by Codegen + set(${var_prefix}_${lang_var}_SOURCES ${IDL_SOURCES} PARENT_SCOPE) + set(${var_prefix}_${lang_var}_GENERATED_SOURCES ${IDL_GENERATED_SOURCES} PARENT_SCOPE) + set(${var_prefix}_${lang_var}_PUBLISHER_SOURCE ${IDL_PUBLISHER_SOURCE} PARENT_SCOPE) + set(${var_prefix}_${lang_var}_SUBSCRIBER_SOURCE ${IDL_SUBSCRIBER_SOURCE} PARENT_SCOPE) + set(${var_prefix}_${lang_var}_HEADERS ${IDL_HEADERS} PARENT_SCOPE) + set(${var_prefix}_${lang_var}_TIMESTAMP ${TIMESTAMP} PARENT_SCOPE) + + + message(STATUS " idl gen sources: ${IDL_GENERATED_SOURCES}") + message(STATUS " idl gen sources: ${var_prefix}_${lang_var}_PUBLISHER_SOURCE") + +endfunction() + +function(connextdds_rtiddsgen_convert) + set(options NOT_REPLACE USE_CODEGEN1) + set(single_args VAR FROM TO INPUT OUTPUT_DIRECTORY) + set(multi_args INCLUDE_DIRS DEFINES EXTRA_ARGS DEPENDS) + cmake_parse_arguments(_CODEGEN "${options}" "${single_args}" "${multi_args}" ${ARGN}) + connextdds_check_required_arguments(_CODEGEN_INPUT _CODEGEN_FROM _CODEGEN_TO) + + if(_CODEGEN_USE_CODEGEN1) + set(use_codegen1 TRUE) + else() + set(use_codegen1 FALSE) + endif() + _connextdds_codegen_find_codegen(${use_codegen1}) + + if(_CODEGEN_USE_CODEGEN1) + # For CodeGen 1, it is not possible specify the input as full path. + # We need to specify just the file name and chdir to the path. + get_filename_component(input_dir ${_CODEGEN_INPUT} DIRECTORY) + get_filename_component(input_name ${_CODEGEN_INPUT} NAME) + else() + # CodeGen 2 has the other bug, it can't parse a file from the + # working directory. Reference: CODEGENII-877 + set(input_dir) + set(input_name ${_CODEGEN_INPUT}) + endif() + + # Build the conversion related arguments + if(_CODEGEN_FROM STREQUAL "IDL") + set(input_arg -inputIdl "${input_name}") + elseif(_CODEGEN_FROM STREQUAL "XML") + set(input_arg -inputXml "${input_name}") + elseif(_CODEGEN_FROM STREQUAL "XSD") + set(input_arg -inputXsd "${input_name}") + elseif(_CODEGEN_FROM STREQUAL "WSDL") + set(input_arg -inputWsdl ${input_name}) + else() + message(FATAL_ERROR "Invalid FROM type: ${_CODEGEN_FROM}") + endif() + + set(output_ext) + if(_CODEGEN_TO STREQUAL "IDL") + set(output_arg "-convertToIdl") + set(output_ext "idl") + elseif(_CODEGEN_TO STREQUAL "XML") + set(output_arg "-convertToXml") + set(output_ext "xml") + elseif(_CODEGEN_TO STREQUAL "XSD") + set(output_arg "-convertToXsd") + set(output_ext "xsd") + elseif(_CODEGEN_TO STREQUAL "WSDL") + set(output_arg "-convertToWsdl") + set(output_ext "wsdl") + else() + message(FATAL_ERROR "Invalid TO type: ${_CODEGEN_TO}") + endif() + + # Build the preprocessor arguments + set(include_dirs) + foreach(dir ${_CODEGEN_INCLUDE_DIRS}) + list(APPEND include_dirs -I "${dir}") + endforeach() + + set(defines) + foreach(def ${_CODEGEN_DEFINES}) + list(APPEND defines -D${def}) + endforeach() + + # Build the optional arguments + set(optional_args ${_CODEGEN_EXTRA_ARGS}) + if(NOT _CODEGEN_NOT_REPLACE) + list(APPEND optional_args "-replace") + endif() + + # Set the output directory + # We create the directory at run-time in case it was deleted + set(output_dir) + if(_CODEGEN_OUTPUT_DIRECTORY) + set(output_dir "${_CODEGEN_OUTPUT_DIRECTORY}") + else() + get_filename_component(output_dir "${_CODEGEN_INPUT}" DIRECTORY) + endif() + + # Define the output file in the variable + get_filename_component(input_name_we "${_CODEGEN_INPUT}" NAME_WE) + set(output_file "${output_dir}/${input_name_we}.${output_ext}") + if(_CODEGEN_VAR) + set(${_CODEGEN_VAR} "${output_file}" PARENT_SCOPE) + endif() + + # Run CodeGen + add_custom_command( + OUTPUT + "${output_file}" + COMMENT "Generating from ${_CODEGEN_FROM}: ${output_file}" + COMMAND + ${CMAKE_COMMAND} -E make_directory ${output_dir} + COMMAND + ${CODEGEN_COMMAND} + ${input_arg} ${output_arg} + ${include_dirs} ${defines} + -d ${output_dir} + ${optional_args} + WORKING_DIRECTORY ${input_dir} + DEPENDS + ${CODEGEN_DEPENDS} + "${_CODEGEN_INPUT}" + ${_CODEGEN_DEPENDS} + ) +endfunction() diff --git a/ChocolateFactory/ExampleCode/cmake/FindRTIConnextDDS.cmake b/ChocolateFactory/ExampleCode/cmake/FindRTIConnextDDS.cmake new file mode 100644 index 00000000..c22cf04f --- /dev/null +++ b/ChocolateFactory/ExampleCode/cmake/FindRTIConnextDDS.cmake @@ -0,0 +1,1939 @@ +#.rst: +# (c) 2017 Copyright, Real-Time Innovations, Inc. All rights reserved. +# RTI grants Licensee a license to use, modify, compile, and create derivative +# works of this file solely for use with RTI Connext DDS.  Licensee may +# redistribute copies of this file provided that all such copies are subject +# to this license. +# +# FindRTIConnextDDS +# ----------------- +# +# Find RTI Connext DDS libraries. +# +# Components +# ^^^^^^^^^^ +# This module sets variables for the following components that are part of RTI +# Connext DDS: +# +# - core (default, always provided) +# - messaging_api +# - security_plugins +# - routing_service +# - monitoring_libraries +# - distributed_logger +# +# Core is always selected, because the rest of components depend on it. +# However, the rest of components must be explicitly selected in the +# find_package invocation for this module to set variables for the different +# libraries associated with them. +# +# Also, the version consistency across all the requested components can be +# checked. If the version between the components missmatch, +# `RTIConnextDDS_FOUND` will be set to `FALSE`. This feature can be enabled +# setting `CONNEXTDDS_ENABLE_VERSION_CHECK` to `TRUE`. +# +# Imported Targets +# ^^^^^^^^^^^^^^^^ +# This module defines the following `IMPORTED` targets: +# +# - ``RTIConnextDDS::c_api`` +# The nddsc library if found (nddscore will be linked as part of this target). +# - ``RTIConnextDDS::cpp_api`` +# The nddscpp library if found (nddscore and nddsc will be linked as part of +# this target). +# - ``RTIConnextDDS::cpp2_api`` +# The nddscpp2 library if found (nddscore and nddsc will be linked as part +# of this target). +# - ``RTIConnextDDS::distributed_logger_c`` +# The C API library for Distributed Logger if found. +# - ``RTIConnextDDS::distributed_logger_cpp`` +# The CPP API library for Distributed Logger if found. +# - ``RTIConnextDDS::metp`` +# The METP library if found (nddsmetp). +# - ``RTIConnextDDS::routing_service_infrastructure`` +# The infrastructure library for Routing Service if found. +# - ``RTIConnextDDS::routing_service_c`` +# The C API library for Routing Service if found (includes +# rtiroutingservice, rtirsinfrastructure, rtixml2 and rticonnextmsgc. Also +# nddsmetp and rticonnextmsgc if found). +# - ``RTIConnextDDS::routing_service`` +# The same as RTIConnextDDS::routing_service_c. Maintained for backward +# compatibility. +# - ``RTIConnextDDS::assign_transformation`` +# The assign transformation library if found (includes rtirsassigntransf and +# rtiroutingservice). +# - ``RTIConnextDDS::monitoring`` +# The Monitoring library if found. +# - ``RTIConnextDDS::security_plugins`` +# The security plugins libraries if found (nddssecurity). +# - ``RTIConnextDDS::messaging_c_api`` +# The Request Reply C API library if found (rticonnextmsgc). +# - ``RTIConnextDDS::messaging_cpp_api`` +# The Request Reply CPP API library if found (rticonnextmsgcpp). +# - ``RTIConnextDDS::messaging_cpp2_api`` +# The Request Reply C API library if found (rticonnextmsgcpp2). +# - ``RTIConnextDDS::nddstls`` +# The tls library if found (nddstls). +# - ``RTIConnextDDS::transport_tcp`` +# The Transport TCP library if found (nddstransporttcp). +# - ``RTIConnextDDS::transport_tls`` +# The Transport TLS library if found (nddstransporttls). +# - ``RTIConnextDDS::transport_wan`` +# The Transport WAN library if found (nddstransportwan). +# - ``RTIConnextDDS::recording_service`` +# The Recording Service library if found (includes rtirecordingservice, +# rtiroutingservice, rtirsinfrastructure, nddscpp2, rtidlc, nddsmetp, +# rticonnextmsgc and rtixml2). +# - ``RTIConnextDDS::rtixml2`` +# The RTI XML2 library if found (rtixml2). +# - ``RTIConnextDDS::low_bandwidth_discovery_static`` +# The Discovery Static library for Low Bandwidth Plugins if found +# (nddsdiscoverystatic). +# - ``RTIConnextDDS::low_bandwidth_edisc`` +# The edisc library for Low Bandwidth Plugins if found (rtilbedisc). +# - ``RTIConnextDDS::low_bandwidth_pdisc`` +# The pdisc library for Low Bandwidth Plugins if found (rtilbpdisc). +# - ``RTIConnextDDS::low_bandwidth_rtps`` +# The rtps library for Low Bandwidth Plugins if found (rtilbrtps). +# - ``RTIConnextDDS::low_bandwidth_sm`` +# The sm library for Low Bandwidth Plugins if found (rtilbsm). +# - ``RTIConnextDDS::low_bandwidth_st`` +# The st library for Low Bandwidth Plugins if found (rtilbst). +# - ``RTIConnextDDS::rtizrtps`` +# The rtizrtps library if found (rtizrtps). +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# This module will set the following variables in your project: +# +# - ``CONNEXTDDS_COMPILE_DEFINITIONS`` +# RTI Connext DDS Compiler definitions as a list. +# - ``CONNEXTDDS_DEFINITIONS`` +# RTI Connext DDS Compiler definitions as a string (deprecated). +# - ``CONNEXTDDS_EXTERNAL_LIBS`` +# RTI Connext DDS external dependencies. +# - ``CONNEXTDDS_INCLUDE_DIRS`` +# RTI Connext DDS include directories. +# - ``CONNEXTDDS_DLL_EXPORT_MACRO`` +# Macros to compile against RTI Connext DDS shared libraries on Windows. +# - ``RTICODEGEN_DIR`` +# Path to the directory where RTI Codegen is placed. +# - ``RTICODEGEN`` +# Path to the RTI Codegen executable. +# - ``RTICODEGEN_VERSION`` +# RTI Codegen version. +# +# This module will set the following variables for all the different libraries +# that are part of the components selected at configuration time. +# +# - ``_LIBRARIES_RELEASE_STATIC`` +# Release static libraries for . +# (e.g., ``CONNEXTDDS_C_API_LIBRARIES_RELEASE_STATIC``). +# - ``_LIBRARIES_RELEASE_SHARED`` +# Release shared libraries for . +# (e.g., ``CONNEXTDDS_C_API_LIBRARIES_RELEASE_SHARED``). +# - ``_LIBRARIES_DEBUG_STATIC`` +# Debug static libraries for . +# (e.g., ``CONNEXTDDS_C_API_LIBRARIES_DEBUG_STATIC``). +# - ``_LIBRARIES_DEBUG_SHARED`` +# Debug shared libraries for . +# (e.g., ``CONNEXTDDS_C_API_LIBRARIES_DEBUG_SHARED``). +# - ``_LIBRARIES`` +# Depending on the value of CMAKE_BUILD_TYPE and BUILD_SHARED_LIBS, +# this variable will be set with the requested value. +# (e.g., if ``CMAKE_BUILD_TYPE`` is ``Release`` and ``BUILD_SHARED_LIBS`` is +# ``OFF``, will have the same value as +# ``CONNEXTDDS_C_API_LIBRARIES_RELEASE_STATIC``). +# +# Also, the ``_FOUND`` variable is set for each one of the previous +# variables. +# +# The list of libraries for each component is the following: +# +# - ``core`` component (always set by this module): +# - ``CONNEXTDDS_C_API`` +# (e.g., ``CONNEXTDDS_C_API_LIBRARIES_RELEASE_STATIC``) +# - ``CONNEXTDDS_CPP_API`` +# (e.g., ``CONNEXTDDS_CPP_API_LIBRARIES_RELEASE_STATIC``) +# - ``CONNEXTDDS_CPP2_API`` +# (e.g., ``CONNEXTDDS_CPP2_API_LIBRARIES_RELEASE_STATIC``) +# +# - ``messaging_api`` component: +# - ``MESSAGING_C`` +# (e.g., ``MESSAGING_C_API_LIBRARIES_RELEASE_STATIC``) +# - ``MESSAGING_CPP`` +# (e.g., ``MESSAGING_CPP_API_LIBRARIES_RELEASE_STATIC``) +# - ``MESSAGING_CPP2`` +# (e.g, ``MESSAGING_CPP2_API_LIBRARIES_RELEASE_STATIC``) +# +# - ``distributed_loger`` component: +# - ``DISTRIBUTED_LOGGER_C`` +# (e.g., ``DISTRIBUTED_LOGGER_C_LIBRARIES_RELEASE_STATIC) +# - ``DISTRIBUTED_LOGGER_CPP`` +# (e.g., ``DISTRIBUTED_LOGGER_CPP_LIBRARIES_RELEASE_STATIC) +# +# - ``metp`` component: +# - ``METP`` +# (e.g., ``METP_LIBRARIES_RELEASE_STATIC``) +# +# - ``routing_service`` component: +# - ``ROUTING_SERVICE_API`` +# (e.g., ``ROUTING_SERVICE_API_LIBRARIES_RELEASE_STATIC``) +# - ``ROUTING_SERVICE_INFRASTRUCTURE`` +# (e.g., ``ROUTING_SERVICE_INFRASTRUCTURE_LIBRARIES_RELEASE_STATIC``) +# +# - ``assign_transformation`` component: +# - ``ASSIGN_TRANSFORMATION`` +# (e.g., ``ASSIGN_TRANSFORMATION_LIBRARIES_RELEASE_STATIC``) +# +# - ``security_plugins`` component: +# - ``SECURITY_PLUGINS`` +# (e.g., ``SECURITY_PLUGINS_LIBRARIES_RELEASE_STATIC``) +# +# - ``monitoring_libraries`` component: +# - ``MONITORING_LIBRARIES`` +# (e.g., ``MONITORING_LIBRARIES_RELEASE_STATIC``) +# +# - ``nddstls`` component: +# - ``NDDSTLS`` +# (e.g., ``NDDSTLS_LIBRARIES_RELEASE_STATIC``) +# +# - ``transport_tcp`` component: +# - ``TRANSPORT_TCP`` +# (e.g., ``TRANSPORT_TCP_LIBRARIES_RELEASE_STATIC``) +# +# - ``transport_tls`` component: +# - ``TRANSPORT_TLS`` +# (e.g., ``TRANSPORT_TLS_LIBRARIES_RELEASE_STATIC``) +# +# - ``transport_wan`` component: +# - ``TRANSPORT_WAN`` +# (e.g., ``TRANSPORT_WAN_LIBRARIES_RELEASE_STATIC``) +# +# - ``recording_service`` component: +# - ``RECORDING_SERVICE_API`` +# (e.g., ``RECORDING_SERVICE_API_LIBRARIES_RELEASE_STATIC``) +# +# - ``rtixml2`` component: +# - ``RTIXML2`` +# (e.g., ``RTIXML2_LIBRARIES_RELEASE_STATIC``) +# +# - ``low_bandwidth_plugins`` component: +# - ``LOW_BANDWIDTH_DISCOVERY_STATIC`` +# (e.g., ``LOW_BANDWIDTH_DISCOVERY_STATIC_LIBRARIES_RELEASE_STATIC``) +# - ``LOW_BANDWIDTH_EDISC`` +# (e.g., ``LOW_BANDWIDTH_EDISC_LIBRARIES_RELEASE_STATIC``) +# - ``LOW_BANDWIDTH_PDISC`` +# (e.g., ``LOW_BANDWIDTH_PDISC_LIBRARIES_RELEASE_STATIC``) +# - ``LOW_BANDWIDTH_RTPS`` +# (e.g., ``LOW_BANDWIDTH_RTPS_LIBRARIES_RELEASE_STATIC``) +# - ``LOW_BANDWIDTH_SM`` +# (e.g., ``LOW_BANDWIDTH_SM_LIBRARIES_RELEASE_STATIC``) +# - ``LOW_BANDWIDTH_ST`` +# (e.g., ``LOW_BANDWIDTH_ST_LIBRARIES_RELEASE_STATIC``) +# +# - ``rtizrtps`` component: +# - ``RTIZRTPS`` +# (e.g., ``RTIZRTPS_LIBRARIES_RELEASE_STATIC``) +# +# Also, the ``_FOUND`` variable is set for each one of the previous +# variables (e.g., ``MONITORING_LIBRARIES_RELEASE_STATIC_FOUND`` and +# ``MONITORING_LIBRARIES_FOUND`` are set). +# +# If you are building a simple ConnextDDS application (you are only using +# the core libraries), use the following variables: +# +# - For a C application: CONNEXTDDS_C_API +# - For a Traditional C++ application: CONNEXTDDS_CPP_API +# - For a Modern C++ application: CONNEXTDDS_CPP2_API +# +# +# Lastly, if you want to use the security plugins (or any other component), +# add the appropriate variables to your CMake script. +# +# Hints +# ^^^^^ +# If the find_package invocation specifies a version, this module will try +# to find your Connext DDS installation in the default installation +# directories. Likewise, the module will try to guess the name of the +# architecture you are trying to build against, by looking for it under the +# rti_connext_dds-x.y.z/lib. +# +# However, in some cases you must provide the following hints by defining some +# variables in your cmake invocation: +# +# - If you don't specify a version or you have installed Connext DDS in a +# non-default location, you must set the ``CONNEXTDDS_DIR`` pointing to your +# RTI Connext DDS installation folder. For example: +# cmake -DCONNEXTDDS_DIR=/home/rti/rti_connext_dds-x.y.z +# +# - If you have installed more than one architecture on your system (i.e., more +# than one target rtipkg), you must set the ``CONNEXTDDS_ARCH`` to provide +# the name of the architecture. For example: +# cmake -DCONNEXTDDS_ARCH=x64Linux3gcc5.4.0 +# +# - If you are building against the security_plugins component, this module +# will try to find OpenSSL in your system using find_package(OpenSSL). If you +# want to build against a specific installation of OpenSSL, you must set the +# ``CONNEXTDDS_OPENSSL_DIR`` to provide this module with the path to your +# installation of OpenSSL. +# +# - Likewise, if you are building against the security_plugins component and +# you want to ensure that you are using a specific OpenSSL version, you must +# set the ``CONNEXTDDS_OPENSSL_VERSION`` so that it can be added to the +# find_package(OpenSSL) invocation. +# +# - If you want to build against debug versions of imported targets, you must +# enable ``CONNEXTDDS_IMPORTED_TARGETS_DEBUG``. Example: +# cmake -DCONNEXTDDS_IMPORTED_TARGETS_DEBUG=ON +# +# Note +# ^^^^ +# Some flags related to the compiler, like (-std=c++11 needed when linking +# against the CPP2 libraries) will not be provided by this script. These flags +# should be provided by the build system. +# +# Examples +# ^^^^^^^^ +# Simple Connext DDS application +# :: +# cmake_minimum_required(VERSION 3.3.2) +# project (example) +# set(CMAKE_MODULE_PATH +# ${CMAKE_MODULE_PATH} +# "/home/rti/rti_connext_dds-5.3.0/resource/cmake") +# +# find_package(RTIConnextDDS EXACT "5.3.0" REQUIRED) +# add_definitions(${CONNEXTDDS_COMPILE_DEFINITIONS}) +# include_directories("src" ${CONNEXTDDS_INCLUDE_DIRS}) +# +# set(SOURCES_PUB +# src/HelloWorld_publisher.c +# src/HelloWorld.c +# src/HelloWorldPlugin.c +# src/HelloWorldSupport.c) +# +# add_executable(HelloWorld_c_publisher ${SOURCES_PUB}) +# target_link_libraries(HelloWorld_c_publisher +# PUBLIC +# RTIConnextDDS::c_api) +# +# +# Simple Routing Service adapter +# :: +# cmake_minimum_required(VERSION 3.3.0) +# project (example) +# set(CMAKE_MODULE_PATH +# ${CMAKE_MODULE_PATH} +# "/home/rti/rti_connext_dds-5.3.0/resource/cmake") +# +# find_package(RTIConnextDDS +# EXACT "5.3.0" +# REQUIRED +# COMPONENTS +# routing_service) +# add_definitions("${CONNEXTDDS_COMPILE_DEFINITIONS}") +# include_directories("src" ${CONNEXTDDS_INCLUDE_DIRS}) +# +# set(LIBRARIES +# ${ROUTING_SERVICE_API_LIBRARIES_RELEASE_STATIC} +# ${CONNEXTDDS_EXTERNAL_LIBS}) +# +# set(SOURCES_LIB src/FileAdapter.c src/LineConversion.c src/osapi.c) +# +# add_library(shapestransf ${SOURCES_LIB}) +# target_link_libraries(shapestransf +# PUBLIC +# RTIConnextDDS::routing_service) +# +# Supported platforms +# ^^^^^^^^^^^^^^^^^^^ +# It is compatible with the following platforms listed in the +# RTI Connext DDS Core Libraries Platform Notes: +# - All the Linux i86 and x64 platforms +# - Raspbian Wheezy 7.0 (3.x kernel) on ARMv6 (armv6vfphLinux3.xgcc4.7.2) +# - Android 5.0 and 5.1 (armv7aAndroid5.0gcc4.9ndkr10e) +# - All the Windows i86 and x64 platforms +# - All the Darwin platforms (OS X 10.11-10.13) +# +# Logging in versions lower than CMake 3.15 +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# For versions lower than CMake 3.15 ``CMAKE_MINOR_VERSION`` variable should be +# use to define lower logging levels than ``STATUS`` mode. All this modes will +# show messages of current level and higher. The following modes are available: +# +# - ``STATUS`` +# Default mode. This will olnly show messages with same or higher logging +# level than CMake ``STATUS``. +# - ``VERBOSE`` +# This mode will show all messages from ``VERBOSE`` level and higher. +# - ``DEBUG`` +# This last mode will show messages from all previous levels and ``DEBUG``. + +include(CMakeParseArguments) + +##################################################################### +# Logging Macros # +##################################################################### + +# These two macros allow better code tracing with debug and verbose messages +# using new CMake 3.15 message types. If cmake 3.14 or lower is in use, default +# messages will be displayed starting with ``DEBUG`` or ``VERBOSE`` instead. +# +# Arguments: +# - message: provides the text message +if("${CMAKE_MINOR_VERSION}" GREATER_EQUAL "15") + macro(connextdds_log_verbose message) + message(VERBOSE "VERBOSE ${message}") + endmacro() + + macro(connextdds_log_debug message) + message(DEBUG " DEBUG ${message}") + endmacro() +else() + set(CONNEXTDDS_LOG_LEVEL_LIST "STATUS" "VERBOSE" "DEBUG") + + if(NOT CONNEXTDDS_LOG_LEVEL) + set(CONNEXTDDS_LOG_LEVEL "STATUS") + endif() + + if(NOT CONNEXTDDS_LOG_LEVEL IN_LIST CONNEXTDDS_LOG_LEVEL_LIST) + string(REPLACE ";" + " " LOG_LEVELS_STRING + "${CONNEXTDDS_LOG_LEVEL_LIST}") + message(FATAL_ERROR "Log level must be one of: ${LOG_LEVELS_STRING}. " + "It's default value is STATUS.") + endif() + + macro(connextdds_log_verbose message) + if("${CONNEXTDDS_LOG_LEVEL}" MATCHES "VERBOSE|DEBUG") + message(STATUS "VERBOSE ${message}") + endif() + endmacro() + + macro(connextdds_log_debug message) + if("${CONNEXTDDS_LOG_LEVEL}" STREQUAL "DEBUG") + message(STATUS " DEBUG ${message}") + endif() + endmacro() +endif() + +# This macro allow xml login with previous ``VERBOSE`` loger macros. +# +# Arguments: +# - XML_NAME: provides the name of the xml +# - XML: provides the xml contents +macro(connextdds_log_xml XML_NAME XML) + string(REPLACE "\n" + ";" lines + ${XML}) + + connextdds_log_verbose("~~~~~~~START ${XML_NAME}~~~~~~~") + foreach(line ${lines}) + connextdds_log_verbose("\t${line}") + endforeach() + connextdds_log_verbose("~~~~~~~FINISH ${XML_NAME}~~~~~~~") +endmacro() + +##################################################################### +# Preconditions Check # +##################################################################### +# +# Find RTI Connext DDS installation. We provide some hints that include the +# CONNEXTDDS_DIR variable, the $NDDSHOME environment variable, and the +# default installation directories. + +if(NOT CONNEXTDDS_DIR) + connextdds_log_verbose("CONNEXTDDS_DIR not specified") + + # Is a patch + if(PACKAGE_FIND_VERSION_COUNT EQUAL 4) + set(folder_version + "${PACKAGE_FIND_VERSION_MAJOR}.${PACKAGE_FIND_VERSION_MINOR}.${PACKAGE_FIND_VERSION_PATCH}") + connextdds_log_debug("The required ConnextDDS version is a patch") + else() + set(folder_version ${RTIConnextDDS_FIND_VERSION}) + endif() + connextdds_log_verbose("ConnextDDS version ${folder_version}") + + if (CMAKE_HOST_SYSTEM_NAME MATCHES "Linux") + set(connextdds_root_hints + "$ENV{HOME}/rti_connext_dds-${folder_version}" + ) + set(connextdds_root_paths + "$ENV{HOME}/rti_connext_dds-*" + ) + + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + set(connextdds_root_hints + "C:/Program Files (x86)/rti_connext_dds-${folder_version}" + "C:/Program Files/rti_connext_dds-${folder_version}" + "C:/rti_connext_dds-${folder_version}" + ) + set(connextdds_root_paths + "C:/Program Files (x86)/rti_connext_dds-*" + "C:/Program Files/rti_connext_dds-*" + "C:/rti_connext_dds-*" + ) + + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") + set(connextdds_root_hints + "/Applications/rti_connext_dds-${folder_version}" + ) + set(connextdds_root_paths + "/Applications/rti_connext_dds-*" + ) + endif() + + file(GLOB connextdds_root_paths_expanded + LIST_DIRECTORIES TRUE + ${connextdds_root_paths} + ) + + connextdds_log_debug("Root hints: ${connextdds_root_hints}") + connextdds_log_debug("Root paths: ${connextdds_root_paths_expanded}") +endif() + +# We require having an rti_versions file under the installation directory +# as we will use it to verify that the version is appropriate. +find_path(CONNEXTDDS_DIR + NAMES rti_versions.xml + HINTS + ENV NDDSHOME + "${NDDSHOME}" + ${connextdds_root_hints} + PATHS + ${connextdds_root_paths_expanded} + +) + +if(NOT CONNEXTDDS_DIR) + set(error + "CONNEXTDDS_DIR not specified. Please set -DCONNEXTDDS_DIR= to " + "your RTI Connext DDS installation directory") + message(FATAL_ERROR ${error}) +endif() + +message(STATUS "RTI Connext DDS installation directory: ${CONNEXTDDS_DIR}") + +set(codegen_name "rtiddsgen") +if(WIN32) + set(codegen_name "${codegen_name}.bat") +endif() +connextdds_log_debug("Codegen script ${codegen_name}") + +find_path(RTICODEGEN_DIR + NAME "${codegen_name}" + HINTS + "${CONNEXTDDS_DIR}/bin") + +if(NOT RTICODEGEN_DIR) + set(warning + "Codegen was not found. Please, check if rtiddsgen is under your " + "NDDSHOME/bin directory or provide it to CMake using -DRTICODEGEN_DIR" + ) + message(WARNING ${warning}) +else() + set(RTICODEGEN + "${RTICODEGEN_DIR}/${codegen_name}" + CACHE PATH + "Path to RTI Codegen") + + # Execute RTI Code Generator to get the version + connextdds_log_debug("Get the Codegen version: '${RTICODEGEN} -version'") + execute_process(COMMAND ${RTICODEGEN} -version + OUTPUT_VARIABLE codegen_version_string) + connextdds_log_debug("Command output:") + connextdds_log_debug("${codegen_version_string}") + + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" + RTICODEGEN_VERSION "${codegen_version_string}") + connextdds_log_verbose("Codegen version: ${RTICODEGEN_VERSION}") +endif() + +# Find RTI Connext DDS architecture if CONNEXTDDS_ARCH is unset +if(NOT CONNEXTDDS_ARCH) + connextdds_log_verbose("CONNEXTDDS_ARCH was not provided") + # Guess the RTI Connext DDS architecture + + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") + string(REGEX REPLACE "^([0-9]+).*$" "\\1" + major_version + ${CMAKE_CXX_COMPILER_VERSION}) + set(version_compiler "${major_version}.0") + connextdds_log_debug("Compiler version: ${version_compiler}") + + string(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" + kernel_version "${CMAKE_SYSTEM_VERSION}") + connextdds_log_debug("Kernel version: ${kernel_version}") + + set(guessed_architecture + "x64Darwin${kernel_version}${version_compiler}") + + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86") + set(connextdds_host_arch "i86Win32") + elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "AMD64") + set(connextdds_host_arch "x64Win64") + + else() + message(FATAL_ERROR + "${CMAKE_HOST_SYSTEM} is not supported as host architecture") + endif() + connextdds_log_debug("Host architecture: ${connextdds_host_arch}") + + string(REGEX MATCH "[0-9][0-9][0-9][0-9]" + vs_year + "${CMAKE_GENERATOR}") + connextdds_log_debug("Visual Studio year: ${vs_year}") + set(guessed_architecture "${connextdds_host_arch}VS${vs_year}") + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux") + if(CMAKE_COMPILER_VERSION VERSION_EQUAL "4.6.3") + set(kernel_version "3.x") + else() + string(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" + kernel_version + "${CMAKE_SYSTEM_VERSION}") + endif() + + connextdds_log_debug("Kernel version: ${kernel_version}") + + if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64") + set(connextdds_host_arch "x64Linux") + + elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i686") + set(connextdds_host_arch "i86Linux") + endif() + + connextdds_log_debug("Host architecture: ${connextdds_host_arch}") + set(guessed_architecture + "${connextdds_host_arch}${kernel_version}gcc${CMAKE_C_COMPILER_VERSION}") + endif() + + connextdds_log_verbose("Guessed RTI architecture: ${guessed_architecture}") + + if(ENV{CONNEXTDDS_ARCH}) + set(CONNEXTDDS_ARCH $ENV{CONNEXTDDS_ARCH}) + elseif(EXISTS "${CONNEXTDDS_DIR}/lib/${guessed_architecture}") + set(CONNEXTDDS_ARCH "${guessed_architecture}") + connextdds_log_debug("${CONNEXTDDS_DIR}/lib/${guessed_architecture} exists") + else() + # If CONNEXTDDS_ARCH is unspecified, the module tries uses the first + # architecture installed by looking under $CONNEXTDDS_DIR/lib. + file(GLOB architectures_installed + RELATIVE "${CONNEXTDDS_DIR}/lib" + "${CONNEXTDDS_DIR}/lib/*") + + foreach(architecture_name ${architectures_installed}) + # Because the lib folder contains both target libraries and + # java jar files, here we exclude the "java" in our algorithm + # to guess the appropriate CONNEXTDDS_ARCH variable. + if(architecture_name STREQUAL "java") + continue() + elseif("${architecture_name}" MATCHES ${CMAKE_HOST_SYSTEM_NAME}) + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") + # Get the installed Darwin + set(CONNEXTDDS_ARCH "${architecture_name}") + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86" AND + "${architecture_name}" MATCHES "Win32") + # Get the x86Win32 architecture + set(CONNEXTDDS_ARCH "${architecture_name}") + elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "AMD64" AND + "${architecture_name}" MATCHES "Win64") + # Get the x64Win64 architecture + set(CONNEXTDDS_ARCH "${architecture_name}") + endif() + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux") + if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i686" AND + "${architecture_name}" MATCHES "x86Linux") + # Get the x86Linux architecture + set(CONNEXTDDS_ARCH "${architecture_name}") + + elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64" AND + "${architecture_name}" MATCHES "x64Linux") + # Get the x64Linux architecture + set(CONNEXTDDS_ARCH "${architecture_name}") + endif() + endif() + endif() + + if(CONNEXTDDS_ARCH) + break() + endif() + endforeach() + + if(NOT CONNEXTDDS_ARCH) + message(WARNING + "CONNEXTDDS_ARCH not specified. Please set " + "-DCONNEXTDDS_ARCH= to specify your RTI Connext DDS " + " architecture") + endif() + endif() +endif() + +message(STATUS "RTI Connext DDS architecture: ${CONNEXTDDS_ARCH}") + +##################################################################### +# Helper Functions # +##################################################################### + +# Checks that a certain field associated with a component is installed under +# CONNEXTDDS_DIR and that its version is consistent with the version required +# for the rest of modules. If RTICONNEXTDDS_VERSION, the version variable, is +# specified, then it checks that the value is consistent. Otherwise, +# it sets the value of RTICONNEXTDDS_VERSION so that it can be checked in +# future calls of this function to validate that its value is consistent +# accross fields and components. +# +# At the end of the script CMake will check that RTICONNEXTDDS_VERSION is +# consistent with the version specified by the user in the find_package +# invocation, acording to the matching rules defined by CMake. +# +# Arguments: +# - field_name: provides the name of the +# Returns: +# - A warning is shown and the `rtiversion_error` variable will be set if the +# component field is not present in rti_versions.xml or the version does not +# match RTICONNEXTDDS_VERSION. +function(connextdds_check_component_field_version + field_name + rti_versions_file + rti_architectures) + connextdds_log_debug("connextdds_check_component_field_version called") + connextdds_log_debug( + "====================================================================") + connextdds_log_debug("\tfield_name: ${field_name}") + connextdds_log_debug("\trti_architectures: [${${rti_architectures}}]") + connextdds_log_verbose("Checking version for ${field_name}") + + # Get the component info + set(field_section_regex "<${field_name}>.*") + string(REGEX MATCH ${field_section_regex} field_xml "${rti_versions_file}") + + connextdds_log_xml("Component info:" "${field_xml}") + + # Check all the architectures defined in the component + foreach(architecture IN LISTS ${rti_architectures}) + # Ignore java fro routing_service_host + if(architecture STREQUAL "java" AND + field_name STREQUAL "routing_service_host") + continue() + endif() + + string(CONCAT field_arch_regex + "[\n\r\t ]*" + "${architecture}.*" + "[\n\r\t ]*[0-9]+\\.[0-9]+\\.[0-9]+(\\.[0-9]+)?" + "") + string(REGEX MATCH ${field_arch_regex} field_arch "${field_xml}") + if(field_arch) + connextdds_log_xml("Field arch:" "${field_arch}") + break() + endif() + endforeach() + + if(NOT field_arch) + message(WARNING + "${field_name} is not installed for ${CONNEXTDDS_ARCH} " + "under ${CONNEXTDDS_DIR}") + set(rtiversion_error TRUE PARENT_SCOPE) + endif() + + # Get the tag from the component + set(field_version_regex + "[0-9]+\\.[0-9]+\\.[0-9]+(\\.[0-9]+(\\.[0-9]+)?)?") + string(REGEX MATCH ${field_version_regex} field_version "${field_arch}") + connextdds_log_xml("Component version tag:" "${field_version}") + + if(NOT field_version) + set(rtiversion_error TRUE PARENT_SCOPE) + message(WARNING + "The version tag was not extracted from ${field_name} and " + "${CONNEXTDDS_ARCH} under ${CONNEXTDDS_DIR}") + return() + endif() + + # Extract the version string from the tag + set(field_version_number_regex + "[0-9]+\\.[0-9]+\\.[0-9]+(\\.[0-9]+(\\.[0-9]+)?)?") + string(REGEX MATCH + ${field_version_number_regex} + field_version_number + ${field_version}) + + connextdds_log_xml("Component version:" "${field_version_number}") + + if(NOT field_version_number) + set(rtiversion_error TRUE PARENT_SCOPE) + message(WARNING + "The version number was not extracted from ${field_name} and " + "${CONNEXTDDS_ARCH} under ${CONNEXTDDS_DIR}") + return() + endif() + + if(NOT "${RTICONNEXTDDS_VERSION}" VERSION_EQUAL "${field_version_number}") + # Otherwise, if the detected version is inconsistent with the previous + # value of RTICONNEXTDDS_VERSION, we throw an error. + set(warning + "The version of ${field} is ${field_version_number}, which " + "is incosistent with the expected version... " + "${RTICONNEXTDDS_VERSION}") + message(WARNING ${warning}) + set(rtiversion_error TRUE PARENT_SCOPE) + else() + connextdds_log_verbose("${field_name} version.........OK") + endif() + connextdds_log_debug( + "====================================================================") +endfunction() + +# This method searches the libraries indicated in `library_names` under +# `/lib/. If one of the libraries in +# one of the modes is not found, the variable _FOUND is set +# to `FALSE`. +# +# After finding the libraries, the libraries are stored in different variables +# following the structure __. Each +# variable contain the libraries for a build and link mode. If one of the +# libraries is not found, the ___FOUND +# is set to `FALSE`. +# +# Arguments: +# - library_names: names of the libraries to find (sorted) +# - result_var_name: name of the variable to set with the found libraries +# Returns: +# - _RELEASE_STATIC: containing the release/static libraries +# - _RELEASE_SHARED: containing the release/shared libraries +# - _DEBUG_STATIC: containing the debug/static libraries +# - _DEBUG_SHARED: containing the debug/shared libraries +# - _FOUND: `True` if all the libraries were found +function(get_all_library_variables + library_names + result_var_name) + connextdds_log_debug("get_all_library_variables called") + connextdds_log_debug( + "====================================================================") + connextdds_log_debug("\tlibrary_names: ${library_names}") + connextdds_log_debug("\tresult_var_name: ${result_var_name}") + + set(mode_library_found TRUE) + set(${result_var_name}_FOUND TRUE PARENT_SCOPE) + + foreach(build_mode "release" "debug") + foreach(link_mode "static" "shared") + set(libraries) + foreach(library_name ${library_names}) + if(${link_mode} STREQUAL "static") + set(name "${library_name}z") + else() + set(name "${library_name}") + endif() + + if(${build_mode} STREQUAL "debug") + set(name "${name}d") + else() + set(name "${name}") + endif() + connextdds_log_debug( + "\t\t[${build_mode}/${link_mode}]Library name: ${name}") + + find_library(lib${library_name}_${build_mode}_${link_mode} + NAMES + ${name} + PATHS + "${CONNEXTDDS_DIR}/lib/${CONNEXTDDS_ARCH}" + NO_DEFAULT_PATH + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH + ) + + if(lib${library_name}_${build_mode}_${link_mode}-NOTFOUND) + set(mode_library_found FALSE) + break() + else() + list(APPEND libraries + ${lib${library_name}_${build_mode}_${link_mode}}) + endif() + endforeach() + + string(TOUPPER ${link_mode} upper_link_mode) + string(TOUPPER ${build_mode} upper_build_mode) + + if(${mode_library_found}) + set(lib_var "${result_var_name}_LIBRARIES_${upper_build_mode}_${upper_link_mode}") + set(${lib_var} ${libraries} PARENT_SCOPE) + connextdds_log_debug("\t${lib_var} = ${libraries}") + set(${lib_var}_FOUND TRUE PARENT_SCOPE) + else() + set(${lib_var}_FOUND FALSE PARENT_SCOPE) + set(${result_var_name}_FOUND FALSE PARENT_SCOPE) + endif() + unset(lib${library_name}_${build_mode}_${link_mode} CACHE) + endforeach() + endforeach() + + if(CMAKE_BUILD_TYPE) + string(TOUPPER "${CMAKE_BUILD_TYPE}" build_mode) + else() + set(build_mode "DEBUG") + endif() + + if(${BUILD_SHARED_LIBS}) + set(link_mode "SHARED") + else() + set(link_mode "STATIC") + endif() + + set(${result_var_name}_LIBRARIES + ${result_var_name}_LIBRARIES_${build_mode}_${link_mode}) + connextdds_log_debug( + "====================================================================") +endfunction() + + +# This function helps to create a ConnextDDS CMake imported target. +# Arguments: +# - TARGET: the name of the target to be created. Note that the prefix +# `RTIConnextDDS::` will be added. +# - VAR: name of the variable where the library and its dependencies were +# stored. The library we want to use for the imported target must be at the +# 0 position. Note the dependencies included in this variable will not be +# used for the creation of the imported target. The `DEPENDENCIES` argument +# is for that purpose. +# - DEPENDENCIES: other imported targets or libraries that are dependencies. +# Returns: +# - A new target called `RTIConnextDDS::`, set to work properly with +# the desired ConnextDDS library, using the DEPENDENCIES as interface +# dependencies. +# If the target was created previusly or the library was not found, nothing +# will happen. +function(create_connext_imported_target) + set(options "") + set(single_value_args "TARGET" "VAR") + set(multi_value_args "DEPENDENCIES") + cmake_parse_arguments(_CONNEXT + "${options}" + "${single_value_args}" + "${multi_value_args}" + ${ARGN} + ) + + if(WIN32 + AND NOT BUILD_SHARED_LIBS + AND ${_CONNEXT_TARGET} STREQUAL "routing_service_c") + # ROUTING-276: Routing Service is not available as a static library + # for Windows + return() + endif() + + set(target_name RTIConnextDDS::${_CONNEXT_TARGET}) + if(TARGET ${target_name}) + return() # Nothing to be done + endif() + + if(NOT ${_CONNEXT_VAR}_FOUND) + return() # Nothing to be done + endif() + + set(imported_lib "${_CONNEXT_VAR}_LIBRARIES") + + # Get the library for the non multiconfiguration generators + if(CONNEXTDDS_IMPORTED_TARGETS_DEBUG) + set(imported_lib "${imported_lib}_DEBUG") + else() + set(imported_lib "${imported_lib}_RELEASE") + endif() + + if(BUILD_SHARED_LIBS) + set(link_mode "SHARED") + else() + set(link_mode "STATIC") + endif() + + list(GET ${imported_lib}_${link_mode} 0 + module_library + ) + + # Create the library + add_library(${target_name} UNKNOWN IMPORTED) + + + if(WIN32 AND BUILD_SHARED_LIBS) + set(location_property IMPORTED_IMPLIB) + else() + set(location_property IMPORTED_LOCATION) + endif() + + # Set properties for all the targets + set_target_properties(${target_name} + PROPERTIES + ${location_property} ${module_library} + IMPORTED_NO_SONAME TRUE + MAP_IMPORTED_CONFIG_MINSIZEREL Release + MAP_IMPORTED_CONFIG_RELWITHDEBINFO Release + ) + + # Add dependencies + if(_CONNEXT_DEPENDENCIES) + set_target_properties(${target_name} + PROPERTIES + INTERFACE_LINK_LIBRARIES + "${_CONNEXT_DEPENDENCIES}" + ) + endif() + + + # Set properties per configuration + foreach(build_mode "RELEASE" "DEBUG") + + list(GET ${_CONNEXT_VAR}_LIBRARIES_${build_mode}_${link_mode} 0 + imported_library + ) + + set_target_properties(${target_name} + PROPERTIES + ${location_property}_${build_mode} + "${imported_library}" + ) + endforeach() +endfunction() + + +##################################################################### +# Platform-specific Definitions # +##################################################################### + +set(connextdds_host_arch "java") + +if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") + # connextdds_host_arch is usually a prefix of the CONNEXTDDS_ARCH (e.g., + # "x64Linux" is a prefix of "x64Linux3gcc5.4.0"). However, in the case + # of Darwin, connextdds_host_arch is simply "darwin". + # To be able to match the CONNEXTDDS_ARCH in some parts of the script, + # we need to be able to consider connextdds_host_arch with both names + # "darwin" and the more natural "x64Darwin". Consequently, we assign a + # list of names to CONNEXT_HOST_ARCH in the case of darwin. + set(connextdds_host_arch ${connextdds_host_arch} "darwin" "x64Darwin") +elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86") + set(connextdds_host_arch ${connextdds_host_arch} "i86Win32") + elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "AMD64") + set(connextdds_host_arch ${connextdds_host_arch} "x64Win64") + else() + message(FATAL_ERROR + "${CMAKE_HOST_SYSTEM} is not supported as host architecture") + endif() +elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux") + if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64") + set(connextdds_host_arch ${connextdds_host_arch} "x64Linux") + elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i686") + set(connextdds_host_arch ${connextdds_host_arch} "i86Linux") + else() + message(FATAL_ERROR + "${CMAKE_HOST_SYSTEM} is not supported as host architecture") + endif() +else() + message(FATAL_ERROR + "${CMAKE_HOST_SYSTEM} is not supported as host architecture") +endif() + +if(CONNEXTDDS_ARCH MATCHES "Linux") + # Linux Platforms + set(CONNEXTDDS_EXTERNAL_LIBS -ldl -lm -lpthread -lrt) + set(CONNEXTDDS_COMPILE_DEFINITIONS RTI_UNIX RTI_LINUX) + + if(CONNEXTDDS_ARCH MATCHES "x64Linux") + set(CONNEXTDDS_COMPILE_DEFINITIONS + ${CONNEXTDDS_COMPILE_DEFINITIONS} + RTI_64BIT) + endif() +elseif(CONNEXTDDS_ARCH MATCHES "Win") + # Windows Platforms + set(CONNEXTDDS_EXTERNAL_LIBS ws2_32 netapi32 version) + + set(CONNEXTDDS_COMPILE_DEFINITIONS + WIN32_LEAN_AND_MEAN + WIN32 + _WINDOWS + RTI_WIN32 + _BIND_TO_CURRENT_MFC_VERSION=1 + _BIND_TO_CURRENT_CRT_VERSION=1 + _SCL_SECURE_NO_WARNINGS + _CRT_SECURE_NO_WARNING) + + # When building against ConnextDDS's shared libraries, users need to also + # add the CONNEXTDDS_DLL_EXPORT_MACRO to their definitions. + set(CONNEXTDDS_DLL_EXPORT_MACRO NDDS_DLL_VARIABLE) + +elseif(CONNEXTDDS_ARCH MATCHES "Darwin") + # Darwin Platforms + set(CONNEXTDDS_EXTERNAL_LIBS "") + + set(CONNEXTDDS_COMPILE_DEFINITIONS + RTI_UNIX + RTI_DARWIN + RTI_DARWIN10 + RTI_64BIT) +elseif(CONNEXTDDS_ARCH MATCHES "Android") + set(CONNEXTDDS_EXTERNAL_LIBS -llog -lc -lm) + set(CONNEXTDDS_COMPILE_DEFINITIONS RTI_UNIX LINUX RTI_ANDROID) +else() + message(FATAL_ERROR + "${CONNEXTDDS_ARCH} architecture is unsupported by this module") +endif() + + +##################################################################### +# Core Component Variables # +##################################################################### + +# This script verifies the version of each of the following fields in +# ${CONNEXTDDS_DIR}/rti_versions.xml, as they are the basic components of the +# RTI Connext DDS core libraries, which are always part of an installation. +list(APPEND rti_versions_field_names_host + "header_files" + "host_files" + "core_release_docs" + "core_api_docs" + "core_jars") + +list(APPEND rti_versions_field_names_target + "target_libraries") + +# Define CONNEXTDDS_INCLUDE_DIRS +find_path(CONNEXTDDS_INCLUDE_DIRS + NAMES + ndds_c.h + PATHS + "${CONNEXTDDS_DIR}/include/ndds") + +set(CONNEXTDDS_INCLUDE_DIRS + "${CONNEXTDDS_DIR}/include" + ${CONNEXTDDS_INCLUDE_DIRS} + "${CONNEXTDDS_DIR}/include/ndds/hpp") + +# Find all flavors of nddscore +get_all_library_variables("nddscore" "CONNEXTDDS_CORE") + +# Find all flavors of nddsc and nddscore +set(c_api_libs "nddsc" "nddscore") +get_all_library_variables("${c_api_libs}" "CONNEXTDDS_C_API") + +# Find all flavors of nddscpp and nddscore +set(cpp_api_libs "nddscpp" "nddsc" "nddscore") +get_all_library_variables("${cpp_api_libs}" "CONNEXTDDS_CPP_API") + +# Find all flavors of nddscpp2 and nddscore +set(cpp2_api_libs "nddscpp2" "nddsc" "nddscore") +get_all_library_variables("${cpp2_api_libs}" "CONNEXTDDS_CPP2_API") + +if(CONNEXTDDS_CORE_FOUND AND CONNEXTDDS_C_API_FOUND) + set(RTIConnextDDS_core_FOUND TRUE) +else() + set(RTIConnextDDS_core_FOUND FALSE) +endif() + +##################################################################### +# Distributed Logger Component Variables # +##################################################################### +if(distributed_logger IN_LIST RTIConnextDDS_FIND_COMPONENTS) + + # Find all flavors of rtidlc + set(distributed_logger_c_libs "rtidlc" "nddsc" "nddscore") + get_all_library_variables("${distributed_logger_c_libs}" + "DISTRIBUTED_LOGGER_C") + + # Find all flavors of rtidlcpp + set(distributed_logger_cpp_libs + "rtidlcpp" + "librtidlc" + "nddscpp" + "nddsc" + "nddscore") + get_all_library_variables("${distributed_logger_cpp_libs}" + "DISTRIBUTED_LOGGER_CPP") + + + if(DISTRIBUTED_LOGGER_C_FOUND AND DISTRIBUTED_LOGGER_CPP_FOUND) + set(RTIConnextDDS_distributed_logger_FOUND TRUE) + + if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND + CMAKE_COMPILER_VERSION VERSION_GREATER "4.6.0") + set(CONNEXTDDS_EXTERNAL_LIBS + -Wl,--no-as-needed ${CONNEXTDDS_EXTERNAL_LIBS}) + endif() + else() + set(RTIConnextDDS_distributed_logger_FOUND FALSE) + endif() +endif() + +##################################################################### +# METP Library Component Variables # +##################################################################### +if(metp IN_LIST RTIConnextDDS_FIND_COMPONENTS) + # Find all flavors of libnddsmetp + set(metp_libs + "nddsmetp" + "nddsc" + "nddscore") + get_all_library_variables("${metp_libs}" "METP") + + if(METP_FOUND) + set(RTIConnextDDS_metp_FOUND TRUE) + else() + set(RTIConnextDDS_metp_FOUND FALSE) + endif() +endif() + + +##################################################################### +# Routing Service Component Variables # +##################################################################### +if(routing_service IN_LIST RTIConnextDDS_FIND_COMPONENTS) + # Add fields associated with the routing_service component + list(APPEND rti_versions_field_names_host + "routing_service_host" + "routing_service") + if(RTIConnextDDS_FIND_VERSION VERSION_GREATER 5.3.0.8) + list(APPEND rti_versions_field_names_host + "routing_service_sdk_jars") + endif() + + list(APPEND rti_versions_field_names_target + "routing_service_sdk") + + # Find all flavors of librtirsinfrastructure + set(rtirsinfrastructure_libs + "rtirsinfrastructure" + "nddsc" + "nddscore") + get_all_library_variables( + "${rtirsinfrastructure_libs}" + "ROUTING_SERVICE_INFRASTRUCTURE") + + set(addon_dependencies) + if(RTIConnextDDS_metp_FOUND) + set(addon_dependencies "nddsmetp") + endif() + + if(RTIConnextDDS_distributed_logger_FOUND) + set(addon_dependencies "${addon_dependencies}" "rtidlc") + endif() + + # Find all flavors of librtiroutingservice + set(routing_service_libs + "rtiroutingservice" + "rtirsinfrastructure" + ${addon_dependencies} + "rtixml2" + "rticonnextmsgc" + "nddsc" + "nddscore") + get_all_library_variables("${routing_service_libs}" "ROUTING_SERVICE_API") + + if(WIN32 AND ROUTING_SERVICE_API_RELEASE_STATIC AND + ROUTING_SERVICE_API_DEBUG_STATIC) + # ROUTING-276: Routing Service is not available as a static library + # for Windows + set(ROUTING_SERVICE_API_FOUND TRUE) + endif() + + if(ROUTING_SERVICE_API_FOUND) + set(RTIConnextDDS_routing_service_FOUND TRUE) + else() + set(RTIConnextDDS_routing_service_FOUND FALSE) + endif() + +endif() + +##################################################################### +# Assign Transformation Component Variables # +##################################################################### +if(assign_transformation IN_LIST RTIConnextDDS_FIND_COMPONENTS) + # Find all flavors of librtirsassigntransf + set(assign_transformation_libs + "rtirsassigntransf" + "rtiroutingservice" + "nddsc" + "nddscore") + get_all_library_variables( + "${assign_transformation_libs}" + "ASSIGN_TRANSFORMATION") + + if(ASSIGN_TRANSFORMATION_FOUND) + set(RTIConnextDDS_assign_transformation_FOUND TRUE) + else() + set(RTIConnextDDS_assign_transformation_FOUND FALSE) + endif() +endif() + +##################################################################### +# Messaging Component Variables # +##################################################################### +if(messaging_api IN_LIST RTIConnextDDS_FIND_COMPONENTS) + list(APPEND rti_versions_field_names_host + "request_reply_host") + list(APPEND rti_versions_field_names_target + "request_reply") + + # Find all flavors of librticonnextmsgc + set(messaging_c_api_libs "rticonnextmsgc" "nddsc" "nddscore") + get_all_library_variables("${messaging_c_api_libs}" "MESSAGING_C_API") + + # Find all flavors of librticonnextmsgcpp + set(messaging_cpp_api_libs "rticonnextmsgcpp" "nddscpp" "nddsc" "nddscore") + get_all_library_variables("${messaging_cpp_api_libs}" "MESSAGING_CPP_API") + + # Find all flavors of librticonnextmsgcpp2 + set(messaging_cpp2_api_libs + "rticonnextmsgcpp2" + "nddscpp2" + "nddsc" + "nddscore") + get_all_library_variables("${messaging_cpp2_api_libs}" + "MESSAGING_CPP2_API") + + if(MESSAGING_C_API_FOUND AND MESSAGING_CPP_API_FOUND AND + MESSAGING_CPP2_API_FOUND) + set(RTIConnextDDS_messaging_api_FOUND TRUE) + else() + set(RTIConnextDDS_messaging_api_FOUND FALSE) + endif() +endif() + +##################################################################### +# Security Plugins Component Variables # +##################################################################### +if(security_plugins IN_LIST RTIConnextDDS_FIND_COMPONENTS) + list(APPEND rti_versions_field_names_host + "secure_base" + "secure_host") + + list(APPEND rti_versions_field_names_target + "secure_target_libraries") + + # Find all flavors of libnddssecurity + set(security_plugins_libs + "nddssecurity" + "nddsc" + "nddscore") + get_all_library_variables( + "${security_plugins_libs}" + "SECURITY_PLUGINS" + ) + + if(SECURITY_PLUGINS_FOUND) + if(CONNEXTDDS_OPENSSL_DIR) + find_package(OpenSSL + REQUIRED ${CONNEXTDDS_OPENSSL_VERSION} + PATHS + "${CONNEXTDDS_OPENSSL_DIR}") + elseif(CONNEXTDDS_OPENSSL_VERSION) + find_package(OpenSSL REQUIRED ${CONNEXTDDS_OPENSSL_VERSION}) + else() + find_package(OpenSSL REQUIRED) + endif() + + # Add OpenSSL include directories to the list of + # CONNEXTDDS_INCLUDE_DIRS + set(CONNEXTDDS_INCLUDE_DIRS + "${OPENSSL_INCLUDE_DIR}" + ${CONNEXTDDS_INCLUDE_DIRS}) + + # Add OpenSSL libraries to the list of CONNEXTDDS_EXTERNAL_LIBS + set(CONNEXTDDS_EXTERNAL_LIBS + ${OPENSSL_SSL_LIBRARY} + ${OPENSSL_CRYPTO_LIBRARY} + ${CONNEXTDDS_EXTERNAL_LIBS}) + + set(RTIConnextDDS_security_plugins_FOUND TRUE) + else() + set(RTIConnextDDS_security_plugins_FOUND FALSE) + endif() + +endif() + +##################################################################### +# Monitoring Liraries Component Variables # +##################################################################### +if(monitoring_libraries IN_LIST RTIConnextDDS_FIND_COMPONENTS) + # Find all flavors of librtimonitoring + get_all_library_variables("rtimonitoring" "MONITORING") + + if(MONITORING_FOUND) + if(CONNEXTDDS_ARCH MATCHES "Win") + set(CONNEXTDDS_EXTERNAL_LIBS psapi ${CONNEXTDDS_EXTERNAL_LIBS}) + endif() + set(RTIConnextDDS_monitoring_libraries_FOUND TRUE) + else() + set(RTIConnextDDS_monitoring_libraries_FOUND FALSE) + endif() +endif() + +##################################################################### +# TLS Static Component Variables # +##################################################################### +if(nddstls IN_LIST RTIConnextDDS_FIND_COMPONENTS) + # Find all flavors of libnddstls + set(nddstls_libs + "nddstls" + "nddsc" + "nddscore") + get_all_library_variables("${nddstls_libs}" "NDDSTLS") + + if(NDDSTLS_FOUND) + set(RTIConnextDDS_nddstls_FOUND TRUE) + else() + set(RTIConnextDDS_nddstls_FOUND FALSE) + endif() +endif() + +##################################################################### +# Transport TCP Library Component Variables # +##################################################################### +if(transport_tcp IN_LIST RTIConnextDDS_FIND_COMPONENTS) + # Find all flavors of libnddstransporttcp + set(transport_tcp_libs + "nddstransporttcp" + "nddsc" + "nddscore") + get_all_library_variables("${transport_tcp_libs}" "TRANSPORT_TCP") + + if(TRANSPORT_TCP_FOUND) + set(RTIConnextDDS_transport_tcp_FOUND TRUE) + else() + set(RTIConnextDDS_transport_tcp_FOUND FALSE) + endif() +endif() + +##################################################################### +# Transport TLS Library Component Variables # +##################################################################### +if(transport_tls IN_LIST RTIConnextDDS_FIND_COMPONENTS) + # Find all flavors of libnddstransporttls + set(transport_tls_libs + "nddstransporttls" + "nddsc" + "nddscore") + get_all_library_variables("${transport_tls_libs}" "TRANSPORT_TLS") + + if(TRANSPORT_TLS_FOUND) + set(RTIConnextDDS_transport_tls_FOUND TRUE) + else() + set(RTIConnextDDS_transport_tls_FOUND FALSE) + endif() +endif() + +##################################################################### +# Transport WAN Library Component Variables # +##################################################################### +if(transport_wan IN_LIST RTIConnextDDS_FIND_COMPONENTS) + # Find all flavors of libnddstransportwan + set(transport_wan_libs + "nddstransportwan" + "nddstransporttls" + "nddsc" + "nddscore") + get_all_library_variables("${transport_wan_libs}" "TRANSPORT_WAN") + + if(TRANSPORT_WAN_FOUND) + set(RTIConnextDDS_transport_wan_FOUND TRUE) + else() + set(RTIConnextDDS_transport_wan_FOUND FALSE) + endif() +endif() + +##################################################################### +# Recording Service API Component Variables # +##################################################################### +if(recording_service IN_LIST RTIConnextDDS_FIND_COMPONENTS) + # Find all flavors of librtirecordingservice + set(recording_service_libs + "rtirecordingservice" + "rtiroutingservice" + "rtirsinfrastructure" + "nddscpp2" + "rtidlc" + "nddsmetp" + "rticonnextmsgc" + "rtixml2" + "nddsc" + "nddscore") + get_all_library_variables( + "${recording_service_libs}" + "RECORDING_SERVICE_API") + + if(RECORDING_SERVICE_API_FOUND) + set(RTIConnextDDS_recording_service_FOUND TRUE) + else() + set(RTIConnextDDS_recording_service_FOUND FALSE) + endif() +endif() + +##################################################################### +# rtixml2 Library Component Variables # +##################################################################### +if(rtixml2 IN_LIST RTIConnextDDS_FIND_COMPONENTS) + if(WIN32) + message(FATAL_ERROR "rtixml2 component is not supported for Windows") + endif() + + # Find all flavors of librtixml2 + set(rtixml2_libs + "rtixml2" + "nddsc" + "nddscore") + get_all_library_variables("${rtixml2_libs}" "RTIXML2") + + if(RTIXML2_FOUND) + set(RTIConnextDDS_rtixml2_FOUND TRUE) + else() + set(RTIConnextDDS_rtixml2_FOUND FALSE) + endif() +endif() + +##################################################################### +# Low Bandwidth Pluggins Component Variables # +##################################################################### +if(low_bandwidth_plugins IN_LIST RTIConnextDDS_FIND_COMPONENTS) + # Find all flavors of libnddsdiscoverystatic + set(discovery_static_libs + "nddsdiscoverystatic" + "nddsc" + "nddscore") + get_all_library_variables( + "${discovery_static_libs}" + "LOW_BANDWIDTH_DISCOVERY_STATIC") + + # Find all flavors of librtilbedisc + set(rtilbedisc_libs + "rtilbedisc" + "nddsc" + "nddscore") + get_all_library_variables("${rtilbedisc_libs}" "LOW_BANDWIDTH_EDISC") + + # Find all flavors of librtilbpdisc + set(rtilbpdisc_libs + "rtilbpdisc" + "nddsc" + "nddscore") + get_all_library_variables("${rtilbpdisc_libs}" "LOW_BANDWIDTH_PDISC") + + # Find all flavors of librtilbrtps + set(rtilbrtps_libs + "rtilbrtps" + "nddsc" + "nddscore") + get_all_library_variables("${rtilbrtps_libs}" "LOW_BANDWIDTH_RTPS") + + # Find all flavors of librtilbsm + set(rtilbsm_libs + "rtilbsm" + "nddsc" + "nddscore") + get_all_library_variables("${rtilbsm_libs}" "LOW_BANDWIDTH_SM") + + # Find all flavors of librtilbst + set(rtilbst_libs + "rtilbst" + "nddsc" + "nddscore") + get_all_library_variables("${rtilbst_libs}" "LOW_BANDWIDTH_ST") + + if(LOW_BANDWIDTH_DISCOVERY_STATIC_FOUND AND LOW_BANDWIDTH_EDISC_FOUND AND + LOW_BANDWIDTH_PDISC_FOUND AND LOW_BANDWIDTH_RTPS_FOUND AND + LOW_BANDWIDTH_SM_FOUND AND LOW_BANDWIDTH_ST_FOUND) + set(RTIConnextDDS_low_bandwidth_plugins_FOUND TRUE) + else() + set(RTIConnextDDS_low_bandwidth_plugins_FOUND FALSE) + endif() +endif() + +##################################################################### +# rtizrtps Component Variables # +##################################################################### +if(rtizrtps IN_LIST RTIConnextDDS_FIND_COMPONENTS) + # Find all flavors of librtizrtps + set(rtizrtps_libs + "rtizrtps" + "nddsc" + "nddscore") + get_all_library_variables("${rtizrtps_libs}" "RTIZRTPS") + + if(RTIZRTPS_FOUND) + set(RTIConnextDDS_rtizrtps_FOUND TRUE) + else() + set(RTIConnextDDS_rtizrtps_FOUND FALSE) + endif() +endif() + +##################################################################### +# Version Variables # +##################################################################### + +# In the header files, there is a variable that contains the BUILD ID of the +# release. From the BUILD ID, we can get the version. +set(regex_for_build "NDDSCORE_BUILD_.*_RTI_REL") +file(STRINGS + "${CONNEXTDDS_DIR}/include/ndds/core_version/core_version_buildid.h" + build_id_line + REGEX ${regex_for_build} +) +string(REGEX MATCH + ${regex_for_build} + CONNEXTDDS_BUILD_ID + "${build_id_line}" +) +string(REGEX MATCH + "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" + RTICONNEXTDDS_VERSION + "${CONNEXTDDS_BUILD_ID}") + +if(CONNEXTDDS_ENABLE_VERSION_CHECK) + # Verify that all the components specified have the same version + file(READ "${CONNEXTDDS_DIR}/rti_versions.xml" xml_file) + # Verify host components + foreach(field IN LISTS rti_versions_field_names_host) + connextdds_check_component_field_version( + ${field} + ${xml_file} + connextdds_host_arch) + endforeach() + + # Verify target components + foreach(field IN LISTS rti_versions_field_names_target) + connextdds_check_component_field_version( + ${field} + ${xml_file} + CONNEXTDDS_ARCH) + endforeach() +endif() + +# Set CONNEXTDDS_DEFINITIONS for backward compatibility +foreach(definition ${CONNEXTDDS_COMPILE_DEFINITIONS}) + set(CONNEXTDDS_DEFINITIONS "${CONNEXTDDS_DEFINITIONS} -D${definition}") +endforeach() + +# If there were not errors checking the version, everything was fine +if(NOT rtiversion_error) + set(RTICONNEXTDDS_VERSION_OK TRUE) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(RTIConnextDDS + REQUIRED_VARS + CONNEXTDDS_DIR + RTICONNEXTDDS_VERSION + RTICONNEXTDDS_VERSION_OK + VERSION_VAR + RTICONNEXTDDS_VERSION + HANDLE_COMPONENTS) + + +##################################################################### +# Create the imported targets # +##################################################################### + +if(RTIConnextDDS_FOUND) + #################### Core and APIs imported targets ##################### + # Core + create_connext_imported_target( + TARGET "core" + VAR "CONNEXTDDS_CORE" + DEPENDENCIES + ${CONNEXTDDS_EXTERNAL_LIBS} + ) + + set(target_definitions ${CONNEXTDDS_COMPILE_DEFINITIONS}) + if(BUILD_SHARED_LIBS) + set(target_definitions + ${CONNEXTDDS_COMPILE_DEFINITIONS} + ${CONNEXTDDS_DLL_EXPORT_MACRO}) + endif() + + set_target_properties(RTIConnextDDS::core + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES + "${CONNEXTDDS_INCLUDE_DIRS}" + INTERFACE_LINK_DIRECTORIES + "${CONNEXTDDS_DIR}/lib/${CONNEXTDDS_ARCH}" + INTERFACE_COMPILE_DEFINITIONS + "${target_definitions}" + ) + + # C API + create_connext_imported_target( + TARGET "c_api" + VAR "CONNEXTDDS_C_API" + DEPENDENCIES + RTIConnextDDS::core + ) + + # CPP API + create_connext_imported_target( + TARGET "cpp_api" + VAR "CONNEXTDDS_CPP_API" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # Modern CPP API + create_connext_imported_target( + TARGET "cpp2_api" + VAR "CONNEXTDDS_CPP2_API" + DEPENDENCIES + RTIConnextDDS::cpp_api + ) + + # Metp + create_connext_imported_target( + TARGET "metp" + VAR "METP" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # Metp + create_connext_imported_target( + TARGET "rtixml2" + VAR "RTIXML2" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + + ###################### Distributed Logger targets ###################### + # Distributed Logger C API + create_connext_imported_target( + TARGET "distributed_logger_c" + VAR "DISTRIBUTED_LOGGER_C" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # Distributed Logger CPP API + create_connext_imported_target( + TARGET "distributed_logger_cpp" + VAR "DISTRIBUTED_LOGGER_CPP" + DEPENDENCIES + RTIConnextDDS::distributed_logger_c + ) + + + ############## Messaging (Request-Reply) imported targets ############### + # C Messaging API + create_connext_imported_target( + TARGET "messaging_c_api" + VAR "MESSAGING_C_API" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # CPP Messaging API + create_connext_imported_target( + TARGET "messaging_cpp_api" + VAR "MESSAGING_CPP_API" + DEPENDENCIES + RTIConnextDDS::cpp_api + ) + + # Modern CPP Messaging API + create_connext_imported_target( + TARGET "messaging_cpp_api" + VAR "MESSAGING_CPP2_API" + DEPENDENCIES + RTIConnextDDS::cpp2_api + ) + + + ################## Security plugins imported targets ################### + # Security plugins + set(dependencies RTIConnextDDS::c_api) + + # The OpenSSL imported targets are created by find_package(OpenSSL). + if(TARGET OpenSSL::SSL) + set(dependencies ${dependencies} OpenSSL::SSL) + endif() + + if(TARGET OpenSSL::Crypto) + set(dependencies ${dependencies} OpenSSL::Crypto) + endif() + + create_connext_imported_target( + TARGET "security_plugins" + VAR "SECURITY_PLUGINS" + DEPENDENCIES + ${dependencies} + ) + + + ################ Monitoring libraries imported targets ################## + create_connext_imported_target( + TARGET "monitoring" + VAR "MONITORING" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + + ###################### Transports imported targets ###################### + # TLS library + create_connext_imported_target( + TARGET "nddstls" + VAR "NDDSTLS" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # TCP + create_connext_imported_target( + TARGET "transport_tcp" + VAR "TRANSPORT_TCP" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # Transport TLS + create_connext_imported_target( + TARGET "transport_tls" + VAR "TRANSPORT_TLS" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # Transport WAN + create_connext_imported_target( + TARGET "transport_wan" + VAR "TRANSPORT_WAN" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + + ######################## Low bandwidth plugins ######################### + # Discovery Static + create_connext_imported_target( + TARGET "low_bandwidth_discovery_static" + VAR "LOW_BANDWIDTH_DISCOVERY_STATIC" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # EDISC + create_connext_imported_target( + TARGET "low_bandwidth_discovery_static" + VAR "LOW_BANDWIDTH_EDISC" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # PDISC + create_connext_imported_target( + TARGET "low_bandwidth_pdisc" + VAR "LOW_BANDWIDTH_PDISC" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # RTPS + create_connext_imported_target( + TARGET "low_bandwidth_rtps" + VAR "LOW_BANDWIDTH_RTPS" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # SM + create_connext_imported_target( + TARGET "low_bandwidth_sm" + VAR "LOW_BANDWIDTH_SM" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # ST + create_connext_imported_target( + TARGET "low_bandwidth_st" + VAR "LOW_BANDWIDTH_ST_LIBRARIES_RELEASE_STATIC" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # RTIRTPS + create_connext_imported_target( + TARGET "rtirtps" + VAR "RTIRTPS" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + + ####################### Services imported targets ####################### + # Infrastructure + create_connext_imported_target( + TARGET "routing_service_infrastructure" + VAR "ROUTING_SERVICE_INFRASTRUCTURE" + DEPENDENCIES + RTIConnextDDS::c_api + ) + + # Routing Service C API + set(dependencies RTIConnextDDS::c_api) + + if(TARGET RTIConnextDDS::distributed_logger_c) + set(dependencies + ${dependencies} + RTIConnextDDS::distributed_logger_c + ) + endif() + + if(TARGET RTIConnextDDS::metp) + set(dependencies + ${dependencies} + RTIConnextDDS::metp + ) + endif() + + if(TARGET RTIConnextDDS::messaging_c_api) + set(dependencies + ${dependencies} + RTIConnextDDS::messaging_c_api + ) + endif() + + if(TARGET RTIConnextDDS::rtixml2) + set(dependencies + ${dependencies} + RTIConnextDDS::rtixml2 + ) + endif() + + create_connext_imported_target( + TARGET "routing_service_c" + VAR "ROUTING_SERVICE_API_LIBRARIES" + DEPENDENCIES + ${dependencies} + ) + + # Routing Service Assign Transformation + create_connext_imported_target( + TARGET "assign_transformation" + VAR "ASSIGN_TRANSFORMATION" + DEPENDENCIES + RTIConnextDDS::routing_service_c + ) + + # Recording Service + create_connext_imported_target( + TARGET "recording_service" + VAR "RECORDING_SERVICE" + DEPENDENCIES + RTIConnextDDS::routing_service_c + RTIConnextDDS::routing_service_infrastructure + RTIConnextDDS::cpp2_api + ) + +endif() diff --git a/ChocolateFactory/ExampleCode/make/Makefile.common b/ChocolateFactory/ExampleCode/make/Makefile.common deleted file mode 100644 index 892d0670..00000000 --- a/ChocolateFactory/ExampleCode/make/Makefile.common +++ /dev/null @@ -1,194 +0,0 @@ -############################################################################### -## (c) Copyright, Real-Time Innovations, All rights reserved. ## -## ## -## Permission to modify and use for internal purposes granted. ## -## This software is provided "as is", without warranty, express or implied. ## -## ## -############################################################################### - -# This Makefile contains the common rules to build for all the architectures. -# It is included from the architecture-specific Makefile. -# This Makefile requires the following variables: -# - ARCH: Architecture to build (for example x64Linux3gcc5.4.0) -# -# Optional variables: -# - DEBUG: If set to '1', it turns on debugging information -# - SHAREDLIB: If set to '1', shared libraries will be used -# - CXX: compiler name. -# - CXXFLAGS: compiler flags: will be appended to $CXX command-line -# - CXXLD: linker name. -# - CXXLDFLAGS: linker flags: will be inserted at the beginning of CXXLD cmdline -# - SYSLIBS: additional system libraries to append to the CXXLD command-line - -############################################################################### -# Ensure this Makefile is invoked with the right variable set -############################################################################### -ifeq ($(ARCH), ) -all: - @echo "***************************************************************" - @echo "You cannot use this Makefile directly, instead use the" - @echo "architecture-specific Makefile. For example:" - @echo " gmake -f make/Makefile.x64Linux3gcc5.4.0" - @echo "***************************************************************" - @false -else -############################################################################### -# Ensure $NDDSHOME is defined -############################################################################### -ifeq ($(NDDSHOME), ) -all: - @echo "***************************************************************" - @echo "The environment variable 'NDDSHOME' is not set!" - @echo "To use this makefile you need to set NDDSHOME to the directory" - @echo "where you have RTI Connext installed." - @echo "***************************************************************" - @false -endif -endif - - -# Define the sources and NDDS search path -INCLUDES = -Isrc/CommonInfrastructure -Isrc/Generated -I$(NDDSHOME)/include \ - -I$(NDDSHOME)/include/ndds - -############################################################################### -# Modify build flags for debug/release -############################################################################### -ifeq ($(DEBUG),1) -CXXFLAGS += -g -O0 -ifeq ($(SHAREDLIB),1) -NDDSLIBS = -lnddscppd -lnddscd -lnddscored -else -NDDSLIBS = -lnddscppzd -lnddsczd -lnddscorezd -endif -else -CXXFLAGS += -O2 -ifeq ($(SHAREDLIB),1) -NDDSLIBS = -lnddscpp -lnddsc -lnddscore -else -NDDSLIBS = -lnddscppz -lnddscz -lnddscorez -endif -endif - -LIBS = -L$(NDDSHOME)/lib/$(ARCH) $(NDDSLIBS) $(SYSLIBS) -STATION_CONTROLLERLIBS = $(LIBS) - -COMMONSRC = src/CommonInfrastructure/DDSCommunicator.cxx \ - src/CommonInfrastructure/OSAPI.cxx \ - src/CommonInfrastructure/ChocolateLotStateEntities.cxx \ - src/CommonInfrastructure/EnumPrintHelpers.cxx \ - -COMMON_H = src/CommonInfrastructure/DDSCommunicator.h \ - src/CommonInfrastructure/OSAPI.h \ - src/CommonInfrastructure/DDSTypeWrapper.h \ - src/CommonInfrastructure/ChocolateLotStateEntities.h \ - src/CommonInfrastructure/EnumPrintHelpers.h \ - -SOURCES_IDL = src/Generated/ChocolateFactory.cxx \ - src/Generated/ChocolateFactoryPlugin.cxx \ - src/Generated/ChocolateFactorySupport.cxx - -MESSRC = src/ManufacturingExecutionSystem/MESInterface.cxx \ - src/ManufacturingExecutionSystem/ManufacturingExecutionSystem.cxx - -RECIPESRC = src/RecipeGenerator/RecipePublisherInterface.cxx \ - src/RecipeGenerator/RecipeGenerator.cxx - -STATION_CONTROLLERSRC = src/StationControllerInterface.cxx \ - src/StationController.cxx - -HEADERS_IDL = src/Generated/ChocolateFactory.h \ - src/Generated/ChocolateFactoryPlugin.h \ - src/Generated/ChocolateFactorySupport.h - -DIRECTORIES = objs.dir objs/$(ARCH).dir objs/$(ARCH)/ManufacturingExecutionSystem.dir \ - objs/$(ARCH)/RecipeGenerator.dir objs/$(ARCH)/StationController.dir \ - objs/$(ARCH)/Common.dir -SOURCES_NODIR = $(notdir $(COMMONSRC)) $(notdir $(SOURCES_IDL)) -COMMONOBJS = $(SOURCES_NODIR:%.cxx=objs/$(ARCH)/Common/%.o) -EXEC = ManufacturingExecutionSystem - -MESSRC_NODIR = $(notdir $(MESSRC)) -MESOBJS = $(MESSRC_NODIR:%.cxx=objs/$(ARCH)/ManufacturingExecutionSystem/%.o) $(COMMONOBJS) - -RECIPESRC_NODIR = $(notdir $(RECIPESRC)) -RECIPEOBJS = $(RECIPESRC_NODIR:%.cxx=objs/$(ARCH)/RecipeGenerator/%.o) $(COMMONOBJS) -RECIPEEXEC = RecipeGenerator - -STATION_CONTROLLERSRC_NODIR = $(notdir $(STATION_CONTROLLERSRC)) -STATION_CONTROLLEROBJS = $(STATION_CONTROLLERSRC_NODIR:%.cxx=objs/$(ARCH)/StationController/%.o) $(COMMONOBJS) -STATION_CONTROLLEREXEC = StationController - -############################################################################### -# Build Rules -############################################################################### -$(ARCH): ManufacturingExecutionSystem RecipeGenerator StationController - -ManufacturingExecutionSystem: $(DIRECTORIES) $(MESOBJS) $(EXEC:%=objs/$(ARCH)/ManufacturingExecutionSystem/%.o) \ - $(EXEC:%=objs/$(ARCH)/ManufacturingExecutionSystem/%.out) - -RecipeGenerator: $(RECIPEOBJS) $(@:%=objs/$(ARCH)/RecipeGenerator/%.o) \ - $(RECIPEEXEC:%=objs/$(ARCH)/RecipeGenerator/%.out) - -StationController: $(STATION_CONTROLLEROBJS) $(@:%=objs/$(ARCH)/StationController/%.o) \ - $(STATION_CONTROLLEREXEC:%=objs/$(ARCH)/StationController/%.out) - -# Building the manufacturing execution system application -objs/$(ARCH)/ManufacturingExecutionSystem/%.out: objs/$(ARCH)/ManufacturingExecutionSystem/%.o - $(CXXLD) $(CXXLDFLAGS) -o $(@:%.out=%) $(MESOBJS) $(LIBS) - -# Building the recipe generator application -objs/$(ARCH)/RecipeGenerator/%.out: objs/$(ARCH)/RecipeGenerator/%.o - $(CXXLD) $(CXXLDFLAGS) -o $(@:%.out=%) $(RECIPEOBJS) $(LIBS) - -# Building the station controller application -objs/$(ARCH)/StationController/%.out: objs/$(ARCH)/StationController/%.o - $(CXXLD) $(CXXLDFLAGS) -o $(@:%.out=%) $(STATION_CONTROLLEROBJS) $(STATION_CONTROLLERLIBS) - - -objs/$(ARCH)/Common/%.o: src/CommonInfrastructure/%.cxx $(COMMON_H) - $(CXX) $(CXXFLAGS) -o $@ $(DEFINES) $(INCLUDES) -c $< - -objs/$(ARCH)/Common/%.o: src/Generated/%.cxx $(COMMON_H) - $(CXX) $(CXXFLAGS) -o $@ $(DEFINES) $(INCLUDES) -c $< - -objs/$(ARCH)/ManufacturingExecutionSystem/%.o: src/ManufacturingExecutionSystem/%.cxx $(COMMON_H) $(HEADERS_IDL) - $(CXX) $(CXXFLAGS) -o $@ $(DEFINES) $(INCLUDES) -c $< - -objs/$(ARCH)/RecipeGenerator/%.o: src/RecipeGenerator/%.cxx $(COMMON_H) - $(CXX) $(CXXFLAGS) -o $@ $(DEFINES) $(INCLUDES) -c $< - -objs/$(ARCH)/StationController/%.o: src/StationController/%.cxx $(COMMON_H) - $(CXX) $(CXXFLAGS) -o $@ $(DEFINES) $(INCLUDES) -c $< - -# Rule to rebuild the generated files when the .idl file change -$(SOURCES_IDL) $(HEADERS_IDL): src/Idl/ChocolateFactory.idl - @mkdir -p src/Generated -ifeq ($(OS_ARCH), i86Win32) - call $(NDDSHOME)/bin/rtiddsgen.bat -d src/idl src/ChocolateFactory.idl -replace -language C++ -else - $(NDDSHOME)/bin/rtiddsgen -namespace -d src/Generated src/Idl/ChocolateFactory.idl -replace -language C++ -endif - -generate: $(SOURCES_IDL) $(HEADERS_IDL) - -# Here is how we create those subdirectories automatically. -%.dir : - @echo "Checking directory $*" - @if [ ! -d $* ]; then \ - echo "Making directory $*"; \ - mkdir -p $* ; \ - fi; - -############################################################################### -# Clean target: removes the objs dir -############################################################################### -clean: - @rm -Rf objs/$(ARCH) - @echo "Successfully deleted object and executable files for architecture $(ARCH)" - @echo "To delete ALL the architectures and any generated file use target 'veryclean'" - -veryclean: - @rm -Rf objs - @rm -Rf src/idl - @echo "Deleted all executables, objects and generated files" diff --git a/ChocolateFactory/ExampleCode/make/Makefile.x64Linux3gcc5.4.0 b/ChocolateFactory/ExampleCode/make/Makefile.x64Linux3gcc5.4.0 deleted file mode 100644 index 81924829..00000000 --- a/ChocolateFactory/ExampleCode/make/Makefile.x64Linux3gcc5.4.0 +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################### -## (c) Copyright, Real-Time Innovations, All rights reserved. ## -## ## -## Permission to modify and use for internal purposes granted. ## -## This software is provided "as is", without warranty, express or implied. ## -## ## -############################################################################### - -# Note: -# - To use this Makefile, you must have the 'NDDSHOME' environment variable -# set to the location of RTI Connext. -# -# - You need to invoke the make command from the root directory of this example. -# -# - To enable debugging information, set the Makefile variable 'DEBUG' to '1'. -# Example: -# make -f make/Makefile.x64Linux3gcc5.4.0 DEBUG=1 - - -# Defines required Make variables. They will be used in the Makefile.common -# to define the rules to define the build process for this application. -ARCH=x64Linux3gcc5.4.0 - -CXX = g++ -CXXFLAGS = -DRTI_UNIX -DRTI_LINUX -m64 -CXXLD = g++ -CXXLDFLAGS = -m64 -static-libgcc -SYSLIBS = -ldl -lnsl -lm -lpthread -lrt - -# The rest of the rules are in the 'Makefile.common' -include make/Makefile.common - diff --git a/ChocolateFactory/ExampleCode/make/Makefile.x64Linux4gcc7.3.0 b/ChocolateFactory/ExampleCode/make/Makefile.x64Linux4gcc7.3.0 deleted file mode 100644 index b026b13e..00000000 --- a/ChocolateFactory/ExampleCode/make/Makefile.x64Linux4gcc7.3.0 +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################### -## (c) Copyright, Real-Time Innovations, All rights reserved. ## -## ## -## Permission to modify and use for internal purposes granted. ## -## This software is provided "as is", without warranty, express or implied. ## -## ## -############################################################################### - -# Note: -# - To use this Makefile, you must have the 'NDDSHOME' environment variable -# set to the location of RTI Connext. -# -# - You need to invoke the make command from the root directory of this example. -# -# - To enable debugging information, set the Makefile variable 'DEBUG' to '1'. -# Example: -# make -f make/Makefile.x64Linux4gcc7.3.0 DEBUG=1 - - -# Defines required Make variables. They will be used in the Makefile.common -# to define the rules to define the build process for this application. -ARCH=x64Linux4gcc7.3.0 - -CXX = g++ -CXXFLAGS = -DRTI_UNIX -DRTI_LINUX -m64 -CXXLD = g++ -CXXLDFLAGS = -m64 -static-libgcc -SYSLIBS = -ldl -lnsl -lm -lpthread -lrt - -# The rest of the rules are in the 'Makefile.common' -include make/Makefile.common - diff --git a/ChocolateFactory/ExampleCode/scripts/AllStationControllers.sh b/ChocolateFactory/ExampleCode/scripts/AllStationControllers.sh index e19bd4de..d0680c99 100755 --- a/ChocolateFactory/ExampleCode/scripts/AllStationControllers.sh +++ b/ChocolateFactory/ExampleCode/scripts/AllStationControllers.sh @@ -1,27 +1,26 @@ #!/bin/sh filename=$0 -arch=$1 script_dir=`dirname $filename` executable_name="StationController" -bin_dir=${script_dir}/../objs/${arch}/StationController +bin_dir=${script_dir}/../build if [ -f $bin_dir/$executable_name ] then cd $bin_dir export LD_LIBRARY_PATH=$LD_LIBRARY_PATH - shift - gnome-terminal -x bash -c "./$executable_name --controller-type 1 $*" - gnome-terminal -x bash -c "./$executable_name --controller-type 2 $*" - gnome-terminal -x bash -c "./$executable_name --controller-type 3 $*" - gnome-terminal -x bash -c "./$executable_name --controller-type 4 $*" - gnome-terminal -x bash -c "./$executable_name --controller-type 5 $*" + gnome-terminal --tab -- bash -c "./$executable_name --controller-type 1 $*" + gnome-terminal --tab -- bash -c "./$executable_name --controller-type 2 $*" + gnome-terminal --tab -- bash -c "./$executable_name --controller-type 3 $*" + gnome-terminal --tab -- bash -c "./$executable_name --controller-type 4 $*" + gnome-terminal --tab -- bash -c "./$executable_name --controller-type 5 $*" else echo "***************************************************************" echo $executable_name executable does not exist in: echo $bin_dir echo "" echo Please, try to recompile the application using the command: - echo " $ make -f make/Makefile.${arch}" + echo " $ cmake --build ." + echo while in the build directory. echo "***************************************************************" fi diff --git a/ChocolateFactory/ExampleCode/scripts/MES.sh b/ChocolateFactory/ExampleCode/scripts/MES.sh index ec5fb94d..34ab032e 100755 --- a/ChocolateFactory/ExampleCode/scripts/MES.sh +++ b/ChocolateFactory/ExampleCode/scripts/MES.sh @@ -1,16 +1,14 @@ #!/bin/sh filename=$0 -arch=$1 script_dir=`dirname $filename` executable_name="ManufacturingExecutionSystem" -bin_dir=${script_dir}/../objs/${arch}/ManufacturingExecutionSystem +bin_dir=${script_dir}/../build if [ -f $bin_dir/$executable_name ] then cd $bin_dir export LD_LIBRARY_PATH=$LD_LIBRARY_PATH - shift ./$executable_name $* else echo "***************************************************************" @@ -18,6 +16,7 @@ else echo $bin_dir echo "" echo Please, try to recompile the application using the command: - echo " $ make -f make/Makefile.${arch}" + echo " $ cmake --build ." + echo while in the build directory. echo "***************************************************************" fi diff --git a/ChocolateFactory/ExampleCode/scripts/RecipeGenerator.sh b/ChocolateFactory/ExampleCode/scripts/RecipeGenerator.sh index 954cf6dc..9345d22a 100755 --- a/ChocolateFactory/ExampleCode/scripts/RecipeGenerator.sh +++ b/ChocolateFactory/ExampleCode/scripts/RecipeGenerator.sh @@ -1,16 +1,14 @@ #!/bin/sh filename=$0 -arch=$1 script_dir=`dirname $filename` executable_name="RecipeGenerator" -bin_dir=${script_dir}/../objs/${arch}/RecipeGenerator +bin_dir=${script_dir}/../build if [ -f $bin_dir/$executable_name ] then cd $bin_dir export LD_LIBRARY_PATH=$LD_LIBRARY_PATH - shift ./$executable_name $* else echo "***************************************************************" @@ -18,6 +16,7 @@ else echo $bin_dir echo "" echo Please, try to recompile the application using the command: - echo " $ make -f make/Makefile.${arch}" + echo " $ cmake --build ." + echo while in the build directory. echo "***************************************************************" fi diff --git a/ChocolateFactory/ExampleCode/scripts/StationController.sh b/ChocolateFactory/ExampleCode/scripts/StationController.sh index fdc6fac3..443439e1 100755 --- a/ChocolateFactory/ExampleCode/scripts/StationController.sh +++ b/ChocolateFactory/ExampleCode/scripts/StationController.sh @@ -1,17 +1,15 @@ #!/bin/sh filename=$0 -arch=$1 script_dir=`dirname $filename` executable_name="StationController" -bin_dir=${script_dir}/../objs/${arch}/StationController +bin_dir=${script_dir}/../build if [ -f $bin_dir/$executable_name ] then cd $bin_dir export LD_LIBRARY_PATH=$LD_LIBRARY_PATH echo $LD_LIBRARY_PATH - shift ./$executable_name $* else echo "***************************************************************" @@ -19,6 +17,7 @@ else echo $bin_dir echo "" echo Please, try to recompile the application using the command: - echo " $ make -f make/Makefile.${arch}" + echo " $ cmake --build ." + echo while in the build directory. echo "***************************************************************" fi diff --git a/ChocolateFactory/ExampleCode/src/CMakeLists.txt b/ChocolateFactory/ExampleCode/src/CMakeLists.txt new file mode 100644 index 00000000..1b626137 --- /dev/null +++ b/ChocolateFactory/ExampleCode/src/CMakeLists.txt @@ -0,0 +1,87 @@ +#Set the name and code for the project +project(ChocolateFactory CXX) + +#Set the minimum version of cmake required to build this project +cmake_minimum_required(VERSION 3.10) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") + +#Find the ConnextDDS libraries.This will look fo the core and API libraries +#only +find_package(RTIConnextDDS + "6.0.1" + REQUIRED + COMPONENTS core) + +set(IDL_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Idl/ChocolateFactory.idl) +set(CODEGEN_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Generated) +set(MES_PATH ${CMAKE_CURRENT_SOURCE_DIR}/ManufacturingExecutionSystem) +set(RECIPE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/RecipeGenerator) +set(STATION_PATH ${CMAKE_CURRENT_SOURCE_DIR}/StationController) + +#Run Codegen to generate the source code files for the types +include(ConnextDdsCodegen) +connextdds_rtiddsgen_run( + IDL_FILE ${IDL_PATH} + OUTPUT_DIRECTORY ${CODEGEN_PATH} + LANG C++11) + +set(TYPE_FILES + "${CODEGEN_PATH}/ChocolateFactory.cxx" + "${CODEGEN_PATH}/ChocolateFactoryPlugin.cxx") + +set(TYPE_HEADERS + "${CODEGEN_PATH}/ChocolateFactory.hpp" + "${CODEGEN_PATH}/ChocolateFactoryPlugin.hpp") + +add_custom_target(codegen_sources + DEPENDS ${TYPE_FILES}) + +#Create a library for the Common Infrastructure +set(LIB_COMMON_SRC + "${CMAKE_CURRENT_SOURCE_DIR}/CommonInfrastructure/DDSCommunicator.cxx" + "${CMAKE_CURRENT_SOURCE_DIR}/CommonInfrastructure/EnumPrintHelpers.cxx" + "${CMAKE_CURRENT_SOURCE_DIR}/CommonInfrastructure/InputParser.cxx") + +set(LIB_COMMON_H + "${CMAKE_CURRENT_SOURCE_DIR}/CommonInfrastructure/DDSCommunicator.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/CommonInfrastructure/EnumPrintHelpers.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/CommonInfrastructure/InputParser.hpp") + +add_library(common + OBJECT ${LIB_COMMON_SRC} ${LIB_COMMON_H} ${TYPE_FILES}) + +target_link_libraries(common + RTIConnextDDS::cpp2_api) + +#Create the target for the executable +add_executable(ManufacturingExecutionSystem + "${MES_PATH}/ManufacturingExecutionSystem.cxx" + "${MES_PATH}/MESInterface.cxx" + "${MES_PATH}/MESInterface.hpp" + $) + +add_executable(RecipeGenerator + "${RECIPE_PATH}/RecipeGenerator.cxx" + "${RECIPE_PATH}/RecipePublisherInterface.cxx" + "${RECIPE_PATH}/RecipePublisherInterface.hpp" + $) + +add_executable(StationController + "${STATION_PATH}/StationController.cxx" + "${STATION_PATH}/StationController.hpp" + "${STATION_PATH}/StationControllerInterface.cxx" + "${STATION_PATH}/StationControllerInterface.hpp" + $) + +target_link_libraries(StationController + RTIConnextDDS::cpp2_api) + +target_link_libraries(ManufacturingExecutionSystem + RTIConnextDDS::cpp2_api) + +target_link_libraries(RecipeGenerator + RTIConnextDDS::cpp2_api) + +add_dependencies(common + codegen_sources) diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.cxx b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.cxx index 2dcd51b4..af5902d8 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.cxx +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.cxx @@ -1,481 +1,186 @@ /********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. +(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. +RTI grants Licensee a license to use, modify, compile, and create derivative +works of the Software. Licensee has the right to distribute object form only +for use with RTI products. The Software is provided as is, with no warranty +of any type, including any warranty for fitness for any purpose. RTI is under no +obligation to maintain or support the Software. RTI shall not be liable for any +incidental or consequential damages arising out of the use or inability to use +the software. **********************************************************************************************/ -#include "ChocolateLotStateEntities.h" -#include "EnumPrintHelpers.h" +#include "ChocolateLotStateEntities.hpp" +#include "EnumPrintHelpers.hpp" -using namespace DDS; using namespace com::chocolatefactory::generated; +using namespace dds::topic; +using namespace dds::pub; +using namespace dds::sub; // ------------------------------------------------------------------------- // -// Create the ChocolateLotState DataWriter. This uses the -// DDSCommunicator's DomainParticipant object to create a -// DataWriter and Topic. -ChocolateLotStateWriter::ChocolateLotStateWriter( - DDSCommunicator *communicator, - Publisher *pub, - const std::string &qosLibrary, - const std::string &qosProfile) +// Constructors for the ChocolateLotStateCommon base class. The topic object is +// the description of the data that you will be sending. It associates a +// particular data type with a name that describes the meaning of the data. +// Along with the data types, and whether your application is reading or +// writing particular data, this is the data interface of your application. + +// This topic has the name CHOCOLATE_LOT_TOPIC - a constant string that is +// defined in the .idl file. (It is not required that you define your topic +// name in IDL, but it is a best practice for ensuring the data interface of +// an application is all defined in one place.) Generally you can register all +// topics and types up-front if necessary. + +// This can be done at any time before creating the DataWriters and +// DataReaders. In some systems, this is done in a separate initialization all +// at once - especially in applications that read and write the same topic. +ChocolateLotStateCommon::ChocolateLotStateCommon(DDSCommunicator& comm) : + _topic(dds::topic::Topic(comm.Participant(), CHOCOLATE_LOT_TOPIC)) +{} +ChocolateLotStateCommon::ChocolateLotStateCommon(DDSCommunicator& comm, + const std::string& profile) : + _topic(dds::topic::Topic(comm.Participant(), + CHOCOLATE_LOT_TOPIC, comm.Qos().topic_qos(profile))) +{} + +// Accessor for the private Topic data +const dds::topic::Topic& ChocolateLotStateCommon::Topic() { + return _topic; +} - if (communicator == NULL) - { - std::stringstream errss; - errss << "ChocolateLotStateWriter(): Bad parameter communicator"; - throw errss.str(); - } - - _chocolateLotStateWriter = NULL; - - _communicator = communicator; - DomainParticipant *participant = - _communicator->GetParticipant(); - - if (participant == NULL) - { - std::stringstream errss; - errss << "ChocolateLotStateWriter(): participant has not been created"; - throw errss.str(); - } - - // The topic object is the description of the data that you will be - // sending. It associates a particular data type with a name that - // describes the meaning of the data. Along with the data types, and - // whether your application is reading or writing particular data, this - // is the data interface of your application. - - // This topic has the name CHOCOLATE_LOT_TOPIC - a constant string that is - // defined in the .idl file. (It is not required that you define your - // topic name in IDL, but it is a best practice for ensuring the data - // interface of an application is all defined in one place.) - // Generally you can register all topics and types up-front if - // necessary. - - // This can be done at any time before creating the DataWriters and - // DataReaders. In some systems, this is done in a separate initialization - // all at once - especially in applications that read and write the same - // topic - Topic *topic = (DDS::Topic *) - _communicator-> - GetParticipant()->lookup_topicdescription(CHOCOLATE_LOT_TOPIC); - - if (topic == NULL) - { - - topic = _communicator->CreateTopic( - CHOCOLATE_LOT_TOPIC); - } - - - // Create a DataWriter - // The topic object is the description of the data that you will be - // sending. It associates a particular data type with a name that - // describes the meaning of the data. Along with the data types, and - // whether your application is reading or writing particular data, this - // is the data interface of your application. - - // This topic has the name CHOCOLATE_LOT_TOPIC - a constant string that was - // defined in the .idl file. (It is not required that you define your - // topic name in IDL, but it is a best practice for ensuring the data - // interface of an application is all defined in one place. - // Generally you can register all topics and types up-front if - // necessary. - - // Use QoS loaded from the XML file - - // Create the DDS DataWriter object that sends data over the network (or - // shared memory) - DataWriter *ddsWriter = - pub->create_datawriter_with_profile( - topic, - qosLibrary.c_str(), - qosProfile.c_str(), - NULL, - DDS_STATUS_MASK_NONE); - - - // You cannot use a generic DataWriter to write data, you must cast it to - // your type-specific DataWriter - in this case, a - // ChocolateLotStateDataWriter. - _chocolateLotStateWriter = ChocolateLotStateDataWriter::narrow(ddsWriter); - if (_chocolateLotStateWriter == NULL) - { - std::stringstream errss; - errss << "ChocolateLotStateWriter(): failure to create writer. " << - "Inconsistent Qos?"; - throw errss.str(); - } - +// ------------------------------------------------------------------------- // +// Create the ChocolateLotState DataWriter. This uses the +// DDSCommunicator's DomainParticipant object to create a +// DataWriter and Topic. +ChocolateLotStateWriter::ChocolateLotStateWriter(DDSCommunicator& comm, + const std::string& profile) : + ChocolateLotStateCommon(comm, profile), + _writer(CreateWriter(comm, profile)) +{ } // ------------------------------------------------------------------------- // -// Delete the ChocolateLotStateWriter, and the DDS entities using DDS -// mechanisms - use the factory that created the DataWriter to delete the -// DataWriter +// Destructor for the ChocolateLotStateWriter ChocolateLotStateWriter::~ChocolateLotStateWriter() { - Publisher *pub = _chocolateLotStateWriter->get_publisher(); - pub->delete_datawriter(_chocolateLotStateWriter); +} + +dds::pub::DataWriter& ChocolateLotStateWriter::CreateWriter( + DDSCommunicator& comm, const std::string& profile) +{ + // Create a DataWriter The topic object is the description of the data that + // you will be sending. It associates a particular data type with a name + // that describes the meaning of the data. Along with the data types, and + // whether your application is reading or writing particular data, this is + // the data interface of your application. + + // This topic has the name CHOCOLATE_LOT_TOPIC - a constant string that was + // defined in the .idl file. (It is not required that you define your topic + // name in IDL, but it is a best practice for ensuring the data interface of + // an application is all defined in one place. Generally you can register + // all topics and types up-front if necessary. + + // Use QoS loaded from the XML file + + // Create the DDS DataWriter object that sends data over the network (or + // shared memory) + + auto writer = rti::pub::find_datawriter_by_topic_name + >(comm.Publisher(), CHOCOLATE_LOT_TOPIC); + + if (writer == dds::core::null) + return DataWriter( + comm.Publisher(), Topic(), comm.Qos().datawriter_qos(profile)); + else + return writer; } // ------------------------------------------------------------------------- // // Write the data into the DDS "cloud" - in other words, write the data, -// within the numbered domain that the DomainParticipant was created with, +// within the numbered domain that the DomainParticipant was created with, // to whichever DataReaders of the same topic were discovered over the // available transports. -void ChocolateLotStateWriter::PublishChocolateLotState( - DdsAutoType &lotState) +void ChocolateLotStateWriter::PublishChocolateLotState(const ChocolateLotState& lotState) { - - InstanceHandle_t handle = DDS_HANDLE_NIL; - bool handleSet = false; - - // You can register the instance handle to get better - // throughput - however, this mostly makes sense if you are keeping - // an object in your application where you can attach the instance - // handle, or if you key fields are complex (more than 16 bytes long) - -/* handle = _chocolateLotStateWriter->register_instance(lotState); -*/ - - // Write the chocolate lot data onto the network (or over shared memory) - DDS_ReturnCode_t retcode = _chocolateLotStateWriter->write(lotState, handle); - - if (retcode != RETCODE_OK) - { - std::stringstream errss; - errss << "Write failure - resource limits hit?"; - throw errss.str(); - } - - + _writer.write(lotState); } - // ------------------------------------------------------------------------- // // Unregisters the lot state published by this station controller. This says // that this station controller no longer wants to provide an update to the -// state of a particular lot. -// (The application calls this when a lot has completed all stages of -// processing so there is no need for a station controller to continue to +// state of a particular lot. +// (The application calls this when a lot has completed all stages of +// processing so there is no need for a station controller to continue to // provide its processing state for that lot). -void ChocolateLotStateWriter::UnregisterChocolateLotState( - DdsAutoType &lotState) +void ChocolateLotStateWriter::UnregisterChocolateLotState(const ChocolateLotState& lotState) { - InstanceHandle_t handle = DDS_HANDLE_NIL; - - // Retrieve the handle of the instance we were disposing - handle = _chocolateLotStateWriter->lookup_instance(lotState); - - // Note that DDS has two ways to indicate that an instance has gone away - // it can unregister the instance or dispose it. Also, by default when - // the DataWriter unregisters an instance, it also disposes it. If you - // dispose and instance, the memory for the instance is not cleaned up, - // with the expectation that it will be reused. - // In this case, the next station controller in the factory will start - // writing the lot state for this lot instance. We don't want to dispose - // that lot, but only unregister it. - DDS_ReturnCode_t retcode = - _chocolateLotStateWriter->unregister_instance(lotState, handle); - - if (retcode != RETCODE_OK) - { - std::stringstream errss; - errss << "Write failure - resource limits hit?"; - throw errss.str(); - } - + auto handle = dds::core::InstanceHandle::nil(); + + // Retrieve the handle of the instance we were disposing + handle = _writer.lookup_instance(lotState); + + // Note that DDS has two ways to indicate that an instance has gone away + // it can unregister the instance or dispose it. Also, by default when + // the DataWriter unregisters an instance, it also disposes it. If you + // dispose and instance, the memory for the instance is not cleaned up, + // with the expectation that it will be reused. + // In this case, the next station controller in the factory will start + // writing the lot state for this lot instance. We don't want to dispose + // that lot, but only unregister it. + _writer.unregister_instance(handle); } - // ------------------------------------------------------------------------- // // This creates the DDS DataReader that receives updates about chocolate lots. -ChocolateLotStateReader::ChocolateLotStateReader( - DDSCommunicator *comm, - Subscriber *sub, - const std::string &qosLibrary, - const std::string &qosProfile, - StationControllerKind stationControllerKind) -{ - - if (comm == NULL) - { - std::stringstream errss; - errss << "ChocolateLotStateReader(): bad parameter \"comm\""; - throw errss.str(); - } - - _communicator = comm; - - // Creating a Topic - // The topic object is the description of the data that you will be - // sending. It associates a particular data type with a name that - // describes the meaning of the data. Along with the data types, and - // whether your application is reading or writing particular data, this - // is the data interface of your application. - - // This topic has the name CHOCOLATE_LOT_TOPIC - a constant string - // that is defined in the .idl file. (It is not required that you define - // your topic name in IDL, but it is a best practice for ensuring the data - // interface of an application is all defined in one place. - // Generally you can register all topics and types up-front if - // necessary. - Topic *topic = (DDS::Topic *) - _communicator-> - GetParticipant()->lookup_topicdescription(CHOCOLATE_LOT_TOPIC); - - if (topic == NULL) - { - - topic = _communicator-> - CreateTopic(CHOCOLATE_LOT_TOPIC); - } - - // If this ChocolateLotStateReader is receiving data for a real station - // controller, it filters data so it receives data only for that controller - // If it is being used by another object such as the MES, it does not - // filter, so all ChocolateLotState updates are received by the DataReader. - TopicDescription *topicDescription = NULL; - - if (stationControllerKind != INVALID_CONTROLLER) - { - _parameters.ensure_length(1,1); - - // Static helper method that converts an enumeration into the string - // that represents that enumeration - std::string enumName; - StationControllerType::GetControllerEnumName( - stationControllerKind, - enumName); - - // Filter to receive updates if: 1) This is assigned to me or 2) this - // lot is in state LOT_COMPLETED (at which point I unregister the - // instance) Note: The _parameters StringSeq will delete this - // char * when the ChocolateLotStateReader class is deleted, so must - // duplicate the string using DDS::String_dup. - _parameters[0] = - DDS::String_dup(const_cast(enumName.c_str())); - ContentFilteredTopic *cft = - _communicator-> - GetParticipant()->create_contentfilteredtopic( - "ContentFilter", - topic, - "lotStatus = 'LOT_COMPLETED' OR nextController = %0", - _parameters); - if (cft == NULL) - { - std::stringstream errss; - errss << "ChocolateLotStateReader(): failure to create " << - "Content-Filtered Topic."; - throw errss.str(); - } - - topicDescription = cft; - } - else - { - topicDescription = topic; - } - - // Creating a DataReader - // This DataReader will receive the chocolate lot, and will store that - // data in the middleware's queue to be queried by the application - // Note that if this DataReader belongs to a particular StationController - // type, it will filter to only receive updates for that station controller. - // If it belongs to a non-station controller it does not filter. - DataReader *reader = sub->create_datareader_with_profile( - topicDescription, - qosLibrary.c_str(), - qosProfile.c_str(), - NULL, - DDS_STATUS_MASK_NONE); - if (reader == NULL) - { - std::stringstream errss; - errss << "ChocolateLotStateReader(): failure to create DataReader."; - throw errss.str(); - } - - // Down casting to the type-specific reader - _reader = ChocolateLotStateDataReader::narrow(reader); - - // This WaitSet object will be used to block a thread until one or more - // conditions become true. In this case, there is a single condition that - // will wake up the WaitSet when the reader receives data - _waitSet = new WaitSet(); - if (_waitSet == NULL) - { - std::stringstream errss; - errss << "ChocolateLotStateReader(): failure to create WaitSet."; - throw errss.str(); - } - - // Creating the infrastructure that allows an application thread to block - // until some condition becomes true, such as data availability. - _condition = _reader->get_statuscondition(); - - // Wake up the thread when data is available - _condition->set_enabled_statuses(DDS_DATA_AVAILABLE_STATUS); - if (_condition == NULL) - { - std::stringstream errss; - errss << "ChocolateLotStateReader(): failure to initialize condition."; - throw errss.str(); - } - - // Attaching the condition to the WaitSet - _waitSet->attach_condition(_condition); - -} +ChocolateLotStateReader::ChocolateLotStateReader(DDSCommunicator& comm, + const std::string& profile, const StationControllerKind kind) : + ChocolateLotStateCommon(comm, profile), + _reader(CreateReader(comm, profile, kind)) +{ } // ------------------------------------------------------------------------- // -// Destory the chocolate lot DataReader and WaitSet. Note that this uses -// the DDS factories that created various objects to later delete them. +// Destory the chocolate lot DataReader and WaitSet. ChocolateLotStateReader::~ChocolateLotStateReader() -{ - _waitSet->detach_condition(_condition); - delete _waitSet; - - _reader->delete_contained_entities(); - Subscriber *sub = _reader->get_subscriber(); - sub->delete_datareader(_reader); - -} - -// This example is using an application thread to be notified when chocolate -// lot state updates arrive. -// -// There are three options for getting data from RTI Connext DDS: -// 1. Being notified in the application's thread of data arriving (as here). -// This mechanism has slightly higher latency than option #2, but low -// latency is not important for this use case. In addition, this is safer -// than using option #2, because you do not have to worry about the effect -// on the middleware's thread. -// This uses WaitSet objects to be notified of data arriving. -// A simple of example of this can be found at: -// http://community.rti.com/examples/waitset-status-condition -// 2. Being notified in a listener callback of data arriving. -// This has lower latency than using a WaitSet, but is more dangerous -// because you have to worry about not blocking the middleware's thread. -// 3. Polling for data. -// You can call read() or take() at any time to view or remove the data that -// is currently in the queue. -// A simple example of this can be found at: -// http://community.rti.com/examples/polling-read - -void ChocolateLotStateReader::WaitForChocolateLotUpdates( -std::vector< DdsAutoType > *lots) -{ - - ConditionSeq activeConditions; - // How long to block for data at a time - DDS_Duration_t timeout = {10,0}; +{ } - // Process chocolate lot updates if they exist, and do not wait for another - // notification of new data - if (true == ProcessChocolateLot(lots)) - { - return; - } - - // Block thread for chocolate lot state updates to arrive - DDS_ReturnCode_t retcode = _waitSet->wait(activeConditions, timeout); - - // Normal to time out - if (retcode == DDS_RETCODE_TIMEOUT) - { - return; - } - if (retcode != DDS_RETCODE_OK) - { - std::stringstream errss; - errss << "WaitForChocolateLotUpdates(): error " << retcode << - " when receiving updates to chocolate lots."; - throw errss.str(); - } - - // If we have been woken up and notified that there was an event, we can - // try to process chocolate lot state updates. Errors in processing - // chocolate lot state updates will throw an exception - ProcessChocolateLot(lots); - - -} - -// This method is taking data from the middleware's queue. +// Create the DataReader // -// In this example, we remove the data from the middleware's queue by calling -// take(). We do this because we do not need to retrieve the same update to -// the chocolate lot state more than once. This means there is no need for -// the chocolate lot state to be stored in the middleware's queue. - -bool ChocolateLotStateReader::ProcessChocolateLot( -std::vector< DdsAutoType > *lots) +// If this ChocolateLotStateReader is receiving data for a real station +// controller, it filters data so it receives data only for that controller If +// it is being used by another object such as the MES, it does not filter, so +// all ChocolateLotState updates are received by the DataReader. This DataReader +// will receive the chocolate lot, and will store that data in the middleware's +// queue to be queried by the application Note that if this DataReader belongs +// to a particular StationController type, it will filter to only receive +// updates for that station controller. If it belongs to a non-station +// controller it does not filter. +dds::sub::DataReader& ChocolateLotStateReader::CreateReader( + DDSCommunicator& comm, const std::string& profile, const StationControllerKind kind) { - // Note: These two sequences are being created with a length = 0. - // this means that the middleware is loaning memory to them, which - // the application must return to the middleware. This avoids - // having two separate copies of the data. - ChocolateLotStateSeq lotStateUpdates; - SampleInfoSeq sampleInfos; - - bool haveLotUpdates = false; - - DDS_ReturnCode_t retcode = DDS_RETCODE_OK; - - while (retcode != DDS_RETCODE_NO_DATA) - { - // This call removes the data from the middleware's queue - retcode = _reader->take(lotStateUpdates, sampleInfos); - - // If an error has occurred, throw an exception. No data being - // available is not an error condition - if ((retcode != DDS_RETCODE_OK) && - (retcode != DDS_RETCODE_NO_DATA)) - { - std::stringstream errss; - errss << "ProcessChocolateLot(): error " << retcode << - " when retrieving chocolate lot status updates."; - throw errss.str(); - } - - // Note, based on the QoS profile (history = keep last, depth = 1) and - // the fact that we modeled chocolate lots so that an instance - // corresponds to the combination of a lot and a station controller - // means that we will get at most a single update per pair of - // . - for (int i = 0; i < lotStateUpdates.length(); i++) - { - // Data may not be valid if this is a notification that an instance - // has changed state. In other words, this could be a notification - // that a writer called "dispose" to notify the other applications - // that the lot has moved to a disposed state. - if (sampleInfos[i].valid_data) - { - // Return a value of true that lot updates have been received - haveLotUpdates = true; - - // Making copies of this type for clean API because we do not need - // lowest latency for lot updates - DdsAutoType lot = lotStateUpdates[i]; - lots->push_back(lot); - } - - } - - // This returns the loaned memory to the middleware. - _reader->return_loan(lotStateUpdates, sampleInfos); - - } - - return haveLotUpdates; + // Get the QoS profile from the QoS Provider + auto qos = comm.Qos().datareader_qos(profile); + + if (kind != StationControllerKind::INVALID_CONTROLLER) { + // Static helper method that converts an enumeration into the string + // that represents that enumeration + std::vector parameters = { StationControllerType::ControllerEnumName(kind) }; + + // Filter to receive updates if: 1) This is assigned to me or 2) this + // lot is in state LOT_COMPLETED (at which point I unregister the + // instance) Note: The _parameters StringSeq will delete this + // char * when the ChocolateLotStateReader class is deleted, so must + // duplicate the string using DDS::String_dup. + auto cft = ContentFilteredTopic + (Topic(), "ContentFilter", + Filter("lotStatus = 'LOT_COMPLETED' OR nextController = %0", parameters)); + + return DataReader(comm.Subscriber(), cft, qos); + } + else { + return DataReader(comm.Subscriber(), Topic(), qos); + } } - - +const dds::sub::DataReader& ChocolateLotStateReader::Reader() +{ + return _reader; +} \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.h b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.h deleted file mode 100644 index b86b9ac4..00000000 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.h +++ /dev/null @@ -1,143 +0,0 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ - -#ifndef CHOCOLATE_LOT_STATE_ENTITIES_H -#define CHOCOLATE_LOT_STATE_ENTITIES_H - -#include "ndds/ndds_cpp.h" -#include "ndds/ndds_namespace_cpp.h" -#include "DDSCommunicator.h" -#include "DDSTypeWrapper.h" -#include "../Generated/ChocolateFactory.h" -#include "../Generated/ChocolateFactorySupport.h" - -// ------------------------------------------------------------------------- // -// -// ChocolateLotStateReader: -// Used for receiving the chocolate lot state. This encapsulates the concepts -// of a DDS type-specific DataReader (for type ChocolateLotState), along with -// the mechanisms for accessing data - in this case, this allows the -// application to block one of its threads to wait for data from the -// ChocolateLotStateReader. -// -// ------------------------------------------------------------------------- // -class ChocolateLotStateReader -{ - -public: - - // --- Constructor --- - // This creates a DDS DataReader that subscribes to chocolate lot information. - // This uses the app object to access the DomainParticipant, and it uses - // the QoS profiles specified when creating the DataReader. The XML QoS - // files were previously configured when the StationControllerInterface's - // DDSCommunicator was created. - ChocolateLotStateReader( - DDSCommunicator *comm, - DDS::Subscriber *sub, - const std::string &qosLibrary, - const std::string &qosProfile, - com::chocolatefactory::generated::StationControllerKind - stationControllerKind); - - - // --- Destructor --- - ~ChocolateLotStateReader(); - - // --- Receive chocolate lot updates --- - // This example receives updates about chocolate lots that are destined for - // it, including: lot updates that suggest this should process them, or lot - // updates saying that the lot is entirely done (so this can remove the - // state) - void WaitForChocolateLotUpdates( - std::vector< - DdsAutoType > - *lotState); - - -private: - // --- Private methods --- - - // --- Process chocolate lot state updates in queue --- - bool ProcessChocolateLot( - std::vector< - DdsAutoType > - *lotState); - - // --- Private members --- - - // Contains all the components needed to create the DataReader - DDSCommunicator *_communicator; - - // Application-specific DDS DataReader for receiving chocolate lot state data - com::chocolatefactory::generated::ChocolateLotStateDataReader *_reader; - - // Objects to block a thread until chocolate lot state update arrives - DDS::WaitSet *_waitSet; - DDS::StatusCondition *_condition; - - // Parameters for the content-filtered topic. These can theoretically change, - // but in this case we are always filtering for data for ourself. - DDS_StringSeq _parameters; - -}; - -// ------------------------------------------------------------------------- // -// -// ChocolateLotStateWriter: -// This class is used to create a write chocolate lot data over the network. -// -class ChocolateLotStateWriter -{ - -public: - - // --- Constructor --- - // This creates a DDS DataWriter that publishes the chocolate lot state - ChocolateLotStateWriter(DDSCommunicator *comm, - DDS::Publisher *pub, - const std::string &qosLibrary, - const std::string &qosProfile); - - // --- Destructor --- - ~ChocolateLotStateWriter(); - - // --- Sends the Chocolate Lot State --- - // Uses DDS interface to send a chocolate lot state update over the network - // or shared memory to interested applications subscribing to chocolate - // lot state information. - void PublishChocolateLotState( - DdsAutoType - &lotState); - - // --- Unregisters the lot state --- - // When this application sees that the chocolate lot is finished, it - // unregisters the lot state - void UnregisterChocolateLotState( - DdsAutoType - &lotState); - -private: - // --- Private members --- - - // Contains all the components needed to create the DataWriter - DDSCommunicator *_communicator; - - // The application-specific DDS DataWriter that sends chocolate lot state - // updates over the network or shared memory - com::chocolatefactory::generated::ChocolateLotStateDataWriter - *_chocolateLotStateWriter; - - -}; - - - -#endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.hpp b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.hpp new file mode 100644 index 00000000..ef19e6a9 --- /dev/null +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.hpp @@ -0,0 +1,121 @@ +/********************************************************************************************* +(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. +RTI grants Licensee a license to use, modify, compile, and create derivative +works of the Software. Licensee has the right to distribute object form only +for use with RTI products. The Software is provided as is, with no warranty +of any type, including any warranty for fitness for any purpose. RTI is under no +obligation to maintain or support the Software. RTI shall not be liable for any +incidental or consequential damages arising out of the use or inability to use +the software. +**********************************************************************************************/ + +#ifndef CHOCOLATE_LOT_STATE_ENTITIES_H +#define CHOCOLATE_LOT_STATE_ENTITIES_H + +#include +#include "DDSCommunicator.hpp" +#include "../Generated/ChocolateFactory.hpp" + +using namespace com::chocolatefactory::generated; + +// ------------------------------------------------------------------------- // +// +// ChocolateLotStateCommon: +// Used for dealing with the chocolate lot state. This encapsulates the topic +// used for DataReaders and DataWriters of the state data. +// +// ------------------------------------------------------------------------- // +class ChocolateLotStateCommon { +protected: + // --- Constructors --- + // Default constructor that creates the topic from the default profile + // provided by the DDSCommunicator object + ChocolateLotStateCommon(DDSCommunicator& comm); + // Constructor that creates the topic from the specified profile + ChocolateLotStateCommon(DDSCommunicator& comm, const std::string& profile); + + // --- Accessors --- + // Accessor for the topic data created in initialization + const dds::topic::Topic& Topic(); + +private: + dds::topic::Topic& _topic; +}; + +// ------------------------------------------------------------------------- // +// +// ChocolateLotStateReader: +// Used for receiving the chocolate lot state. This encapsulates the concepts +// of a DDS type-specific DataReader (for type ChocolateLotState), along with +// the mechanisms for accessing data - in this case, this allows the +// application to block one of its threads to wait for data from the +// ChocolateLotStateReader. +// +// ------------------------------------------------------------------------- // +class ChocolateLotStateReader : ChocolateLotStateCommon { +public: + // --- Constructor --- + // This creates a DDS DataReader that subscribes to chocolate lot + // information. This uses the app object to access the DomainParticipant, + // and it uses the QoS profiles specified when creating the DataReader. The + // XML QoS files were previously configured when the + // StationControllerInterface's DDSCommunicator was created. + ChocolateLotStateReader(DDSCommunicator& comm, const std::string& profile, + const StationControllerKind kind); + + // --- Destructor --- + ~ChocolateLotStateReader(); + + const dds::sub::DataReader& Reader(); + +private: + // --- Private methods --- + + // Create reader + dds::sub::DataReader& CreateReader(DDSCommunicator& comm, + const std::string& profile, const StationControllerKind kind); + + // --- Private members --- + + // Application-specific DDS DataReader for receiving chocolate lot state + // data + dds::sub::DataReader& _reader; +}; + +// ------------------------------------------------------------------------- // +// +// ChocolateLotStateWriter: +// This class is used to create a write chocolate lot data over the network. +// +class ChocolateLotStateWriter : ChocolateLotStateCommon { +public: + // --- Constructor --- + // This creates a DDS DataWriter that publishes the chocolate lot state + ChocolateLotStateWriter(DDSCommunicator& comm, const std::string& profile); + + // --- Destructor --- + ~ChocolateLotStateWriter(); + + // --- Sends the Chocolate Lot State --- + // Uses DDS interface to send a chocolate lot state update over the network + // or shared memory to interested applications subscribing to chocolate + // lot state information. + void PublishChocolateLotState(const ChocolateLotState& lotState); + + // --- Unregisters the lot state --- + // When this application sees that the chocolate lot is finished, it + // unregisters the lot state + void UnregisterChocolateLotState(const ChocolateLotState& lotState); + +private: + dds::pub::DataWriter& CreateWriter( + DDSCommunicator& comm, const std::string& profile); + + // --- Private members --- + + // The application-specific DDS DataWriter that sends chocolate lot state + // updates over the network or shared memory + dds::pub::DataWriter& _writer; +}; + +#endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx index 607f9e7d..400edab1 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx @@ -1,65 +1,45 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ -#include "DDSCommunicator.h" +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ -using namespace DDS; +/* DDSCommunicator.cxx -// ------------------------------------------------------------------------- // -// Destruction of a DDS communication interface. This first deletes all the -// entities created by the DomainParticipant object. Then, it cleans up the -// types that have been registered with the DomainParticipant. (This is not -// strictly necessary, but will cause a very small memory leak at shutdown if -// all types are not unregistered. Thirdly, this deletes the -// DomainParticipant. Lastly, this finalizes the DomainParticipantFactory. -DDSCommunicator::~DDSCommunicator() -{ - if (_participant != NULL) - { + Defines common DDS communication elements that are to be inherited by other + classes in the creation of DDS applications. - // Delete DataWriters, DataReaders, Topics, Subscribers, and Publishers - // created by this DomainParticipant. - _participant->delete_contained_entities(); +*/ - // Unregister all the data types registered with this DomainParticipant - for (std::map::iterator it = - _typeCleanupFunctions.begin(); - it != _typeCleanupFunctions.end(); it++) - { - (*it).second.unregisterFunction(_participant, ( - *it).first.c_str()); - } - - // Delete the DomainParticipant - TheParticipantFactory->delete_participant(_participant); - - // You finalize the participant factory here, but this - // will not work if you have multiple communicators - for example - // in different DDS domains. In that case, you must be more careful - // to only finalize the participant factory after all - // DomainParticipants have been deleted. - TheParticipantFactory->finalize_instance(); - } -} +#include "DDSCommunicator.hpp" +using namespace std; +// ------------------------------------------------------------------------- // +// Default constructor. Creates a QoS Provider, Participant, Publisher, and +// Subscriber based on the default profile in the default QoS file. +// ------------------------------------------------------------------------- // +// Creating a QosProvider +// +// A QoS provider allows access to qos profiles and the ability to choose and +// modify them. // ------------------------------------------------------------------------- // -// Creating a DomainParticipant +// Creating a DomainParticipant // // A DomainParticipant starts the DDS discovery process. It creates -// several threads, sends and receives discovery information over one or -// more transports, and maintains an in-memory discovery database of +// several threads, sends and receives discovery information over one or +// more transports, and maintains an in-memory discovery database of // remote DomainParticipants, remote DataWriters, and remote DataReaders // -// Quality of Service can be applied on the level of the DomainParticipant. -// This QoS controls the characteristics of: -// 1. Transport properties such as which type of network (UDPv4, UDPv6, +// Quality of Service can be applied on the level of the DomainParticipant. +// This QoS controls the characteristics of: +// 1. Transport properties such as which type of network (UDPv4, UDPv6, // shared memory) or which network interfaces it is allowed to use // 2. Which applications this discovers. By default, apps will discover // other DDS applications over multicast, loopback, and shared memory. @@ -67,263 +47,94 @@ DDSCommunicator::~DDSCommunicator() // // For more information on participant QoS, see the USER_QOS_PROFILES.xml // file - // ------------------------------------------------------------------------- // -// Creating a DomainParticipant with a specified domain ID -DomainParticipant* DDSCommunicator::CreateParticipant(long domain) -{ - _participant = - TheParticipantFactory->create_participant(domain, - PARTICIPANT_QOS_DEFAULT, NULL, STATUS_MASK_NONE); - - if (_participant == NULL) - { - std::stringstream errss; - errss << "Failed to create DomainParticipant object"; - throw errss.str(); - } - - return _participant; -} - -// ------------------------------------------------------------------------- // -// Creating a DomainParticipant with a domain ID of zero -DomainParticipant* DDSCommunicator::CreateParticipant() -{ - _participant = - TheParticipantFactory->create_participant( - 0, - PARTICIPANT_QOS_DEFAULT, - NULL, STATUS_MASK_NONE); - - if (_participant == NULL) - { - std::stringstream errss; - errss << "Failed to create DomainParticipant object"; - throw errss.str(); - } - - return _participant; +DDSCommunicator::DDSCommunicator() : + _qos(dds::core::QosProvider::Default()), + _participant(dds::domain::DomainParticipant(0)), + _pub(dds::pub::Publisher(_participant)), + _sub(dds::sub::Subscriber(_participant)) +{ } +DDSCommunicator::DDSCommunicator(std::string& qosFile) : + _qos(dds::core::QosProvider(qosFile)), + _participant(dds::domain::DomainParticipant(0, _qos.participant_qos())), + _pub(dds::pub::Publisher(_participant, _qos.publisher_qos())), + _sub(dds::sub::Subscriber(_participant, _qos.subscriber_qos())) +{ } +DDSCommunicator::DDSCommunicator(std::string& qosFile, std::string& profile) : + _qos(dds::core::QosProvider(qosFile, profile)), + _participant(dds::domain::DomainParticipant(0, _qos.participant_qos(profile))), + _pub(dds::pub::Publisher(_participant, _qos.publisher_qos(profile))), + _sub(dds::sub::Subscriber(_participant, _qos.subscriber_qos(profile))) +{ } +DDSCommunicator::DDSCommunicator(dds::core::StringSeq& qosFiles) : + _qos(dds::core::QosProvider(dds::core::null)), + _participant(dds::domain::DomainParticipant(dds::core::null)), + _pub(dds::pub::Publisher(dds::core::null)), + _sub(dds::sub::Subscriber(dds::core::null)) +{ + ostringstream fileString; + if (!qosFiles.empty()) { + copy(qosFiles.begin(), qosFiles.end() - 1, ostream_iterator(fileString, "; ")); + fileString << qosFiles.back(); + } + + _qos = dds::core::QosProvider(fileString.str()); + _participant = dds::domain::DomainParticipant(0, _qos.participant_qos()); + _pub = dds::pub::Publisher(_participant, _qos.publisher_qos()); + _sub = dds::sub::Subscriber(_participant, _qos.subscriber_qos()); } - - -// ------------------------------------------------------------------------- // -// Creating a DomainParticipant with a specified domain ID and specified QoS -DomainParticipant* DDSCommunicator::CreateParticipant( - long domain, - const std::string &participantQosLibrary, - const std::string &participantQosProfile) +DDSCommunicator::DDSCommunicator(std::vector& qosFiles, std::string& profile) : + _qos(dds::core::QosProvider(dds::core::null)), + _participant(dds::domain::DomainParticipant(dds::core::null)), + _pub(dds::pub::Publisher(dds::core::null)), + _sub(dds::sub::Subscriber(dds::core::null)) { - _participant = - TheParticipantFactory->create_participant_with_profile( - domain, - participantQosLibrary.c_str(), - participantQosProfile.c_str(), - NULL, - STATUS_MASK_NONE); - - if (_participant == NULL) - { - std::stringstream errss; - errss << "Failed to create DomainParticipant object"; - throw errss.str(); - } - - return _participant; - + ostringstream fileString; + if (!qosFiles.empty()) { + copy(qosFiles.begin(), qosFiles.end() - 1, ostream_iterator(fileString, "; ")); + fileString << qosFiles.back(); + } + + _qos = dds::core::QosProvider(fileString.str()); + _participant = dds::domain::DomainParticipant(0, _qos.participant_qos(profile)); + _pub = dds::pub::Publisher(_participant, _qos.publisher_qos(profile)); + _sub = dds::sub::Subscriber(_participant, _qos.subscriber_qos(profile)); } // ------------------------------------------------------------------------- // -// Creating a DomainParticipant with a specified domain ID, specified QoS file -// names, and specified QoS -DomainParticipant* DDSCommunicator::CreateParticipant(long domain, - std::vectorfileNames, - const std::string &participantQosLibrary, - const std::string &participantQosProfile) +// Destruction of a DDS communication interface. This first deletes all the +// entities created by the DomainParticipant object. Then, it cleans up the +// types that have been registered with the DomainParticipant. (This is not +// strictly necessary, but will cause a very small memory leak at shutdown if +// all types are not unregistered. Thirdly, this deletes the +// DomainParticipant. Lastly, this finalizes the DomainParticipantFactory. +DDSCommunicator::~DDSCommunicator() { - - // Adding a list of explicit file names to the DomainParticipantFactory - // This gives the middleware a set of places to search for the files - DomainParticipantFactoryQos factoryQos; - TheParticipantFactory->get_qos(factoryQos); - factoryQos.profile.url_profile.ensure_length(fileNames.size(), - fileNames.size()); - - for (unsigned int i = 0; i < fileNames.size(); i++) - { - // Note that we copy the file names here, so they cannot go out of - // scope - factoryQos.profile.url_profile[i] = DDS_String_dup( - fileNames[i].c_str()); - } - - ReturnCode_t retcode = TheParticipantFactory->set_qos(factoryQos); - - if (retcode != RETCODE_OK) - { - std::stringstream errss; - errss << "Failed to create DomainParticipant object"; - throw errss.str(); - } - - // Actually creating the DomainParticipant - _participant = - TheParticipantFactory->create_participant_with_profile( - domain, - participantQosLibrary.c_str(), - participantQosProfile.c_str(), - NULL, - STATUS_MASK_NONE); - - if (_participant == NULL) - { - std::stringstream errss; - errss << "Failed to create DomainParticipant object"; - throw errss.str(); - } - - return _participant; - + if (_participant != dds::core::null) { + // RTI Connext provides a finalize_participant_factory() method if you + // want to release memory used by the participant factory singleton. + _participant->finalize_participant_factory(); + } } - // ------------------------------------------------------------------------- // -// Creating a Publisher object. This is used to create type-specific -// DataWriter objects in the application -Publisher* DDSCommunicator::CreatePublisher() +// Getters for QoS, Publisher, and Subscriber. +dds::core::QosProvider& DDSCommunicator::Qos() { - if (GetParticipant() == NULL) - { - std::stringstream errss; - errss << - "DomainParticipant NULL - communicator not properly " << - "initialized"; - throw errss.str(); - } - - // Creating a Publisher. - // This object is used to create type-specific DataWriter objects that - // can actually send data. - // - _pub = GetParticipant()->create_publisher( - PUBLISHER_QOS_DEFAULT, - NULL, STATUS_MASK_NONE); - - if (_pub == NULL) - { - std::stringstream errss; - errss << "Failed to create Publisher"; - throw errss.str(); - } - - return _pub; + return _qos; } -// ------------------------------------------------------------------------- // -// Creating a Publisher object with specified QoS. This is used to create -// type-specific DataWriter objects in the application -Publisher* DDSCommunicator::CreatePublisher( - const std::string &qosLibrary, - const std::string &qosProfile) +dds::domain::DomainParticipant& DDSCommunicator::Participant() { - if (GetParticipant() == NULL) - { - std::stringstream errss; - errss << - "DomainParticipant NULL - communicator not properly " << - "initialized"; - throw errss.str(); - } - - // Creating a Publisher. - // This object is used to create type-specific DataWriter objects that - // can actually send data. - // - _pub = GetParticipant()->create_publisher_with_profile( - qosLibrary.c_str(), - qosProfile.c_str(), - NULL, STATUS_MASK_NONE); - - if (_pub == NULL) - { - std::stringstream errss; - errss << "Failed to create Publisher"; - throw errss.str(); - } - - return _pub; + return _participant; } - -// ------------------------------------------------------------------------- // -// Creating a Subscriber object. This is used to create type-specific -// DataReader objects in the application -Subscriber* DDSCommunicator::CreateSubscriber() +dds::pub::Publisher& DDSCommunicator::Publisher() { - if (GetParticipant() == NULL) - { - std::stringstream errss; - errss << - "DomainParticipant NULL - communicator not properly " << - "initialized"; - throw errss.str(); - } - - // Creating a Subscriber. - // This object is used to create type-specific DataReader objects that - // can actually receive data. The Subscriber object is being created - // in the DDSCommunicator class because one Subscriber can be used to - // create multiple DDS DataReaders. - // - _sub = GetParticipant()->create_subscriber( - SUBSCRIBER_QOS_DEFAULT, - NULL, STATUS_MASK_NONE); - - if (_sub == NULL) - { - std::stringstream errss; - errss << "Failed to create Subscriber"; - throw errss.str(); - } - - return _sub; + return _pub; } - -// ------------------------------------------------------------------------- // -// Creating a Subscriber object with specified QoS. This is used to create -// type-specific DataReader objects in the application -Subscriber* DDSCommunicator::CreateSubscriber( - const std::string &qosLibrary, - const std::string &qosProfile) +dds::sub::Subscriber& DDSCommunicator::Subscriber() { - if (GetParticipant() == NULL) - { - std::stringstream errss; - errss << - "DomainParticipant NULL - communicator not properly " << - "initialized"; - throw errss.str(); - } - - // Creating a Subscriber. - // This object is used to create type-specific DataReader objects that - // can actually receive data. The Subscriber object is being created - // in the DDSCommunicator class because one Subscriber can be used to - // create multiple DDS DataReaders. - // - _sub = GetParticipant()->create_subscriber_with_profile( - qosLibrary.c_str(), - qosProfile.c_str(), - NULL, STATUS_MASK_NONE); - if (_sub == NULL) - { - std::stringstream errss; - errss << "Failed to create Subscriber"; - throw errss.str(); - } - - return _sub; - + return _sub; } - diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.h b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.h deleted file mode 100644 index 8cc791f4..00000000 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.h +++ /dev/null @@ -1,216 +0,0 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ -#ifndef DDS_COMMUNICATOR_H -#define DDS_COMMUNICATOR_H - -#include -#include -#include -#include "ndds/ndds_cpp.h" -#include "ndds/ndds_namespace_cpp.h" - - -// ------------------------------------------------------------------------- // -// Function that is used to unregister types from the DomainParticipant. -// types are automatically registered when you create the topic, and -// unregistered at shutdown. - -typedef DDS_ReturnCode_t (*unregister_fn)(DDSDomainParticipant *, const char *); - -// ------------------------------------------------------------------------- // -// -// UnregisterInfo: -// This structure maintains a mapping between a data type and its unregister -// function, which can be used at shutdown when cleaning up the the -// DomainParticipant and all of its registered data types. -// -// ------------------------------------------------------------------------- // -struct UnregisterInfo -{ - std::string typeName; - unregister_fn unregisterFunction; -}; - -// ------------------------------------------------------------------------- // -// -// DDSCommunicator: -// This class is used by all RTI Connext DDS interfaces to create the core -// communication objects, such as a DomainParticipant, Publisher and/or -// Subscriber. -// -// ------------------------------------------------------------------------- // -class DDSCommunicator -{ - -public: - // --- Constructor and Destructor --- - DDSCommunicator() : _participant(NULL), _pub(NULL), _sub(NULL) - {} - - ~DDSCommunicator(); - - // --- Creating a DomainParticipant --- - - // A DomainParticipant starts the DDS discovery process. It creates - // several threads, sends and receives discovery information over one or - // more transports, and maintains an in-memory discovery database of - // remote DomainParticipants, remote DataWriters, and remote DataReaders - - // Quality of Service can be applied on the level of the DomainParticipant. - // This QoS controls the characteristics of: - // 1. Transport properties such as which type of network (UDPv4, UDPv6, - // shared memory) or which network interfaces it is allowed to use - // 2. Which applications this discovers. By default, apps will discover - // other DDS applications over multicast, loopback, and shared memory. - // 3. Resource limits for the DomainParticipant - // - // For more information on participant QoS, see the .xml files in the - // Config directory - - // Creates a DomainParticipant with default QoS in domain 0 - DDS::DomainParticipant* CreateParticipant(); - - // Creates a DomainParticipant with default QoS in the specified domain - DDS::DomainParticipant* CreateParticipant(long domain); - - // Creates a DomainParticipant with specified QoS in the specified domain - DDS::DomainParticipant* CreateParticipant(long domain, - const std::string &participantQosLibrary, - const std::string &participantQosProfile); - - // Loads a set of XML files to load QoS profile information - // Creates a DomainParticipant with specified QoS in the specified domain - DDS::DomainParticipant* CreateParticipant(long domain, - std::vectorfileNames, - const std::string &participantQosLibrary, - const std::string &participantQosProfile) ; - - // --- Getting the DomainParticipant --- - - // Returns the DomainParticipant created by the Communicator. - DDS::DomainParticipant* GetParticipant() - { - return _participant; - } - - // --- Creating a Publisher --- - - // The Publisher object is a factory for creating type-specific DataWriters - // Note that the same publisher can be used for multiple DataWriters - - // typically you will create zero or one Publisher per application. - - // Create a Publisher with default QoS - DDS::Publisher* CreatePublisher(); - - // Create a Publisher with specified QoS - DDS::Publisher* CreatePublisher(const std::string &qosLibrary, - const std::string &qosProfile); - - // --- Getting the Publisher --- - - // Returns the Publisher created by the Communicator. - DDS::Publisher* GetPublisher() - { - return _pub; - } - - // --- Creating a Subscriber --- - - // The Subscriber object is a factory for creating type-specific - // DataReaders. - // Note that the same subscriber can be used for multiple DataReaders - - // typically you will create zero or one Subscriber per application. - - // Create a Subscriber with default QoS - DDS::Subscriber* CreateSubscriber(); - - // Create a Subscriber with specified QoS - DDS::Subscriber* CreateSubscriber(const std::string &qosLibrary, - const std::string &qosProfile); - - // --- Getting the Subscriber --- - - // Returns the Publisher created by the Communicator. - DDS::Subscriber* GetSubscriber() - { - return _sub; - } - - // --- Create a Topic --- - - // Creates a Topic. Templatized with the type name to - // allow storage and deletion of the data type at - // shutdown. - template - DDS::Topic *CreateTopic(std::string topicName) - { - // Register the data type with the DomainParticipant - this - // tells the DomainParticipant how to create/destroy/ - // serialize/deserialize this data type. - const char *typeName = T::TypeSupport::get_type_name(); - - DDS_ReturnCode_t retcode = T::TypeSupport::register_type( - GetParticipant(), typeName); - if (retcode != DDS_RETCODE_OK) - { - std::stringstream errss; - errss << "Failure to register type. Regisetered twice?"; - throw errss.str(); - } - - // Create the Topic object, using the associated data type that - // was registered above. - DDS::Topic *topic = GetParticipant()->create_topic( - topicName.c_str(), - typeName, DDS_TOPIC_QOS_DEFAULT, NULL /* listener */, - DDS_STATUS_MASK_NONE); - if (topic == NULL) - { - std::stringstream errss; - errss << "CreateTopic(): failure to create Topic. Created twice?"; - throw errss.str(); - } - - // Save the type unregister information for a clean shutdown. This is - // not strictly necessary, but prevents what looks like a memory leak - // at shutdown. - UnregisterInfo unregisterInfo; - unregisterInfo.typeName = typeName; - unregisterInfo.unregisterFunction = - T::TypeSupport::unregister_type; - _typeCleanupFunctions[typeName] = unregisterInfo; - - return topic; - } - -private: - - // --- Private members --- - - // Used to create other DDS entities - DDS::DomainParticipant* _participant; - - // Used to create DataWriters - DDS::Publisher* _pub; - - // Used to create DataReaders - DDS::Subscriber* _sub; - - // Map between type names and unregistration functions. Functions are - // added to this in CreateTopic(), after each data type is registered - // with the DomainParticipant. This cleans up a small amount of memory - // that would otherwise appear as a memory leak at shutdown. - std::map _typeCleanupFunctions; - - -}; - - -#endif diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp new file mode 100644 index 00000000..e496333c --- /dev/null +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp @@ -0,0 +1,77 @@ +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ + +/* DDSCommunicator.h + + Defines common DDS communication elements that are to be inherited by other + classes in the creation of DDS applications. + +*/ + +#ifndef DDS_COMMUNICATOR_H +#define DDS_COMMUNICATOR_H + +#include +#include +#include + +#include + +// ------------------------------------------------------------------------- // +// +// DDSCommunicator: +// This class is used by all RTI Connext DDS interfaces to create the core +// communication objects, such as a DomainParticipant, Publisher and/or +// Subscriber. +// +// ------------------------------------------------------------------------- // +class DDSCommunicator { +public: + // --- Constructor and Destructor --- + DDSCommunicator(); + DDSCommunicator(std::string& qosFile); + DDSCommunicator(std::string& qosFiles, std::string& profile); + DDSCommunicator(dds::core::StringSeq& qosFiles); + DDSCommunicator(std::vector& qosFiles, std::string& profile); + + ~DDSCommunicator(); + + // --- Data element Getters --- + + // These getter functions allow classes that use the DDS Communicator class + // to pull the QoS, Publisher, and Subscriber to create DataReaders and + // DataWriters + + dds::core::QosProvider& Qos(); + dds::domain::DomainParticipant& Participant(); + dds::pub::Publisher& Publisher(); + dds::sub::Subscriber& Subscriber(); + +private: + // --- Protected members --- + + // Used to create a QOS Provider to be used by other elements + dds::core::QosProvider& _qos; + + // Used to create other DDS entities + dds::domain::DomainParticipant& _participant; + + // Used to create DataWriters + dds::pub::Publisher& _pub; + + // Used to create DataReaders + dds::sub::Subscriber& _sub; +}; + + +#endif diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSTypeWrapper.h b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSTypeWrapper.h deleted file mode 100644 index a74c1933..00000000 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSTypeWrapper.h +++ /dev/null @@ -1,95 +0,0 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ - -#ifndef DDS_TYPE_WRAPPER_H -#define DDS_TYPE_WRAPPER_H - -// ------------------------------------------------------------------------- // -// -// DdsAutoType -// This is a wrapper to RTI Connext DDS types, which includes a default -// constructor, a copy constructor, the = operator, and a destructor. This -// allows us to use RTI Connext DDS types in common C++ patterns, and ensures -// and ensures that you do a deep copy of the contents of the data types. -// -// ------------------------------------------------------------------------- // - -template -class DdsAutoType : public T -{ -public: - - // --- Constructor type for your generated data type --- - DdsAutoType() - { - if (T::TypeSupport::initialize_data(this) != DDS_RETCODE_OK) - { - throw std::bad_alloc(); - } - } - - // --- Copy constructor --- - - // This copy constructor calls the TypeSupport::initialize_data for your - // generated data type (generated from IDL) - DdsAutoType(const DdsAutoType &rhs) - { - if (T::TypeSupport::initialize_data(this) != DDS_RETCODE_OK) - { - throw std::bad_alloc(); - } - if (T::TypeSupport::copy_data(this, &rhs) != DDS_RETCODE_OK) - { - throw std::bad_alloc(); - } - } - - // --- Constructor to initialize from base type - - // This constructor takes in a structure of the base type, and does a deep - // copy of the data into the DdsAutoType - DdsAutoType(const T &rhs) { - - if (T::TypeSupport::initialize_data(this) != DDS_RETCODE_OK) - { - throw std::bad_alloc(); - } - if (T::TypeSupport::copy_data(this, &rhs) != DDS_RETCODE_OK) - { - throw std::bad_alloc(); - } - } - - // --- Assignment operator --- - - // = operator that allows assignment between two generated types. - // This calls FooTypeSupport::copy_data to do a deep copy of the - // data type, including pointers. - DdsAutoType operator=(const DdsAutoType &rhs) - { - if (T::TypeSupport::copy_data(this, &rhs) != DDS_RETCODE_OK) - { - throw std::bad_alloc(); - } - - return *this; - } - - // --- Destructor --- - - // Destroy the data type, including any allocated pointers, etc. - ~DdsAutoType() - { - // in the RTI current implementation the finalize call never fails - T::TypeSupport::finalize_data(this); - } -}; - -#endif diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/EnumPrintHelpers.cxx b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/EnumPrintHelpers.cxx index 8210f433..50aa1650 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/EnumPrintHelpers.cxx +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/EnumPrintHelpers.cxx @@ -1,14 +1,23 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ -#include "EnumPrintHelpers.h" +/* EnumPrintHelpers.cxx + + A set of functions that assist in the conversion of Enumerated values defined + in the IDL from integer enums to strings. + +*/ +#include "EnumPrintHelpers.hpp" using namespace com::chocolatefactory::generated; @@ -16,115 +25,67 @@ using namespace com::chocolatefactory::generated; // ------------------------------------------------------------------------- // // Converts from a StationControllerKind to a string representation of what // the Station Controller does -void StationControllerType::GetControllerPrettyName( - StationControllerKind kind, - std::string &kindOut) +std::string StationControllerType::ControllerPrettyName(StationControllerKind kind) { - if (kind == SUGAR_CONTROLLER) - { - kindOut = "Sugar Controller"; - } - else if (kind == COCOA_BUTTER_CONTROLLER) - { - kindOut = "Cocoa Butter Controller"; - } - else if (kind == COCOA_LIQUOR_CONTROLLER) - { - kindOut = "Cocoa Liquor Controller"; - } - else if (kind == VANILLA_CONTROLLER) - { - kindOut = "Vanilla Controller"; - } - else if (kind == MILK_CONTROLLER) - { - kindOut = "Milk Controller"; - } - + if (kind == StationControllerKind::SUGAR_CONTROLLER) { + return std::string("Sugar Controller"); + } else if (kind == StationControllerKind::COCOA_BUTTER_CONTROLLER) { + return std::string("Cocoa Butter Controller"); + } else if (kind == StationControllerKind::COCOA_LIQUOR_CONTROLLER) { + return std::string("Cocoa Liquor Controller"); + } else if (kind == StationControllerKind::VANILLA_CONTROLLER) { + return std::string("Vanilla Controller"); + } else if (kind == StationControllerKind::MILK_CONTROLLER) { + return std::string("Milk Controller"); + } } // ------------------------------------------------------------------------- // // Converts from a StationControllerKind to a string representation of the // enumeration kind -void StationControllerType::GetControllerEnumName( - StationControllerKind kind, - std::string &kindOut) +std::string StationControllerType::ControllerEnumName(StationControllerKind kind) { - if (kind == SUGAR_CONTROLLER) - { - kindOut = "'SUGAR_CONTROLLER'"; - } - else if (kind == COCOA_BUTTER_CONTROLLER) - { - kindOut = "'COCOA_BUTTER_CONTROLLER'"; - } - else if (kind == COCOA_LIQUOR_CONTROLLER) - { - kindOut = "'COCOA_LIQUOR_CONTROLLER'"; - } - else if (kind == VANILLA_CONTROLLER) - { - kindOut = "'VANILLA_CONTROLLER'"; - } - else if (kind == MILK_CONTROLLER) - { - kindOut = "'MILK_CONTROLLER'"; - } - + if (kind == StationControllerKind::SUGAR_CONTROLLER) { + return std::string("'SUGAR_CONTROLLER'"); + } else if (kind == StationControllerKind::COCOA_BUTTER_CONTROLLER) { + return std::string("'COCOA_BUTTER_CONTROLLER'"); + } else if (kind == StationControllerKind::COCOA_LIQUOR_CONTROLLER) { + return std::string("'COCOA_LIQUOR_CONTROLLER'"); + } else if (kind == StationControllerKind::VANILLA_CONTROLLER) { + return std::string("'VANILLA_CONTROLLER'"); + } else if (kind == StationControllerKind::MILK_CONTROLLER) { + return std::string("'MILK_CONTROLLER'"); + } } // ------------------------------------------------------------------------- // // Converts from a StationControllerKind to a string representation of the // ingredient that the Station Controller adds to the recipe -void StationControllerType::GetControllerIngredientName( - StationControllerKind kind, - std::string &ingredientOut) +std::string StationControllerType::ControllerIngredientName(StationControllerKind kind) { - if (kind == SUGAR_CONTROLLER) - { - ingredientOut = "sugar"; - } - else if (kind == COCOA_BUTTER_CONTROLLER) - { - ingredientOut = "cocoa butter"; - } - else if (kind == COCOA_LIQUOR_CONTROLLER) - { - ingredientOut = "cocoa liquor"; - } - else if (kind == VANILLA_CONTROLLER) - { - ingredientOut = "vanilla"; - } - else if (kind == MILK_CONTROLLER) - { - ingredientOut = "milk"; - } - - + if (kind == StationControllerKind::SUGAR_CONTROLLER) { + return std::string("sugar"); + } else if (kind == StationControllerKind::COCOA_BUTTER_CONTROLLER) { + return std::string("cocoa butter"); + } else if (kind == StationControllerKind::COCOA_LIQUOR_CONTROLLER) { + return std::string("cocoa liquor"); + } else if (kind == StationControllerKind::VANILLA_CONTROLLER) { + return std::string("vanilla"); + } else if (kind == StationControllerKind::MILK_CONTROLLER) { + return std::string("milk"); + } } -void LotStatusType:: GetLotStatusPrettyName( - LotStatusKind kind, - std::string &kindOut) +std::string LotStatusType::LotStatusPrettyName(LotStatusKind kind) { - if (kind == ASSIGNED_TO_SC) - { - kindOut = "Assigned to Station Controller"; - } - else if (kind == WAITING_AT_SC) - { - kindOut = "Waiting at Station Controller"; - } - else if (kind == PROCESSING_AT_SC) - { - kindOut = "Processing at Station Controller"; - } - else if (kind == LOT_COMPLETED) - { - kindOut = "Lot Completed"; - } + if (kind == LotStatusKind::ASSIGNED_TO_SC) { + return std::string("Assigned to Station Controller"); + } else if (kind == LotStatusKind::WAITING_AT_SC) { + return std::string("Waiting at Station Controller"); + } else if (kind == LotStatusKind::PROCESSING_AT_SC) { + return std::string("Processing at Station Controller"); + } else if (kind == LotStatusKind::LOT_COMPLETED) { + return std::string("Lot Completed"); + } } - - diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/EnumPrintHelpers.h b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/EnumPrintHelpers.h deleted file mode 100644 index 436e741e..00000000 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/EnumPrintHelpers.h +++ /dev/null @@ -1,64 +0,0 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ -#ifndef ENUM_PRINT_HELPERS_H -#define ENUM_PRINT_HELPERS_H - -#include -#include "../Generated/ChocolateFactory.h" - -// ------------------------------------------------------------------------- // -// -// StationControllerType: -// A small helper class that converts between the enumeration type and a -// pretty name for printing or a string that represents the enumeration for -// content-filtering purposes. -// -class StationControllerType -{ -public: - - // --- Static methods --- - - // Converts from a StationControllerKind to a nice readable name for - // printing messages - static void GetControllerPrettyName( - com::chocolatefactory::generated::StationControllerKind kind, - std::string &kindOut); - - // Converts from a StationControllerKind to a string that represents - // the enumeration - static void GetControllerEnumName( - com::chocolatefactory::generated::StationControllerKind kind, - std::string &kindOut); - - // Takes a StationControllerKind and fills in a string that represents - // the type of ingredient that controller adds - static void GetControllerIngredientName( - com::chocolatefactory::generated::StationControllerKind kind, - std::string &ingredientOut); - - -}; - -class LotStatusType -{ -public: - - // --- Static methods --- - - // Converts from a LotStatusKind to a nice readable name for - // printing messages - static void GetLotStatusPrettyName( - com::chocolatefactory::generated::LotStatusKind kind, - std::string &kindOut); - -}; - -#endif diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/EnumPrintHelpers.hpp b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/EnumPrintHelpers.hpp new file mode 100644 index 00000000..d21e54ae --- /dev/null +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/EnumPrintHelpers.hpp @@ -0,0 +1,63 @@ +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ + +/* EnumPrintHelpers.h + +A set of functions that assist in the conversion of Enumerated values defined +in the IDL from integer enums to strings. + +*/ +#ifndef ENUM_PRINT_HELPERS_H +#define ENUM_PRINT_HELPERS_H + +#include +#include "../Generated/ChocolateFactory.hpp" + +using namespace com::chocolatefactory::generated; + +// ------------------------------------------------------------------------- // +// +// StationControllerType: +// A small helper class that converts between the enumeration type and a +// pretty name for printing or a string that represents the enumeration for +// content-filtering purposes. +// +class StationControllerType { +public: + // --- Static methods --- + + // Converts from a StationControllerKind to a nice readable name for + // printing messages + static std::string ControllerPrettyName(StationControllerKind kind); + + // Converts from a StationControllerKind to a string that represents + // the enumeration + static std::string ControllerEnumName(StationControllerKind kind); + + // Takes a StationControllerKind and fills in a string that represents + // the type of ingredient that controller adds + static std::string ControllerIngredientName( + com::chocolatefactory::generated::StationControllerKind kind); +}; + +class LotStatusType { +public: + // --- Static methods --- + + // Converts from a LotStatusKind to a nice readable name for + // printing messages + static std::string LotStatusPrettyName( + com::chocolatefactory::generated::LotStatusKind kind); +}; + +#endif diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/InputParser.cxx b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/InputParser.cxx new file mode 100644 index 00000000..ce89bcd6 --- /dev/null +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/InputParser.cxx @@ -0,0 +1,35 @@ +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ + +#include "InputParser.hpp" + +InputParser::InputParser(int& argc, char* argv[]) { + for (int i = 1; i < argc; ++i) + tokens.push_back(std::string(argv[i])); +} + +const std::string& InputParser::getCmdOption(const std::string& option) const { + std::vector::const_iterator itr; + itr = std::find(tokens.begin(), tokens.end(), option); + if (itr != tokens.end() && ++itr != tokens.end()) { + return *itr; + } + else { + static const std::string empty_string(""); + return empty_string; + } +} + +bool InputParser::cmdOptionExists(const std::string& option) const { + return std::find(tokens.begin(), tokens.end(), option) != tokens.end(); +} \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/InputParser.hpp b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/InputParser.hpp new file mode 100644 index 00000000..eea8acd6 --- /dev/null +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/InputParser.hpp @@ -0,0 +1,29 @@ +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ + +#pragma once + +#include +#include + +class InputParser +{ +public: + InputParser(int& argc, char* argv[]); + const std::string& getCmdOption(const std::string& option) const; + bool cmdOptionExists(const std::string& option) const; + +private: + std::vector tokens; +}; + diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/OSAPI.cxx b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/OSAPI.cxx deleted file mode 100644 index 977c5d7b..00000000 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/OSAPI.cxx +++ /dev/null @@ -1,77 +0,0 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ -#include "../CommonInfrastructure/OSAPI.h" - -OSThread::OSThread( - ThreadFunction function, - void *functionParam) -{ - _function = function; - _functionParam = functionParam; -} - -void OSThread::Run() -{ - -#ifdef RTI_WIN32 - _thread = (HANDLE) _beginthread( - (void(__cdecl*)(void*))_function, - 0, (void*)_functionParam); -#else - pthread_attr_t threadAttr; - pthread_attr_init(&threadAttr); - pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_JOINABLE); - int error = pthread_create( - &_thread, - &threadAttr, - _function, - (void *)_functionParam); - pthread_attr_destroy(&threadAttr); - #endif -} - -OSMutex::OSMutex() -{ -#ifdef RTI_WIN32 - InitializeCriticalSection(&_handleCriticalSection); -#else - pthread_mutex_init(&_mutex, NULL); -#endif -} - -OSMutex::~OSMutex() -{ -#ifdef RTI_WIN32 - DeleteCriticalSection(&_handleCriticalSection); -#else - pthread_mutex_destroy(&_mutex); -#endif -} - -void OSMutex::Lock() -{ -#ifdef RTI_WIN32 - EnterCriticalSection(&_handleCriticalSection); -#else - pthread_mutex_lock(&_mutex); -#endif - - -} - -void OSMutex::Unlock() -{ -#ifdef RTI_WIN32 - LeaveCriticalSection(&_handleCriticalSection); -#else - pthread_mutex_unlock(&_mutex); -#endif -} - diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/OSAPI.h b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/OSAPI.h deleted file mode 100644 index 893117dd..00000000 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/OSAPI.h +++ /dev/null @@ -1,111 +0,0 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ - -#ifndef OSAPI_H -#define OSAPI_H - -// ------------------------------------------------------------------------- // -// -// OS APIs for Windows and Linux -// This file includes the APIs to create threads and mutexes in Linux and -// Windows. -// ------------------------------------------------------------------------- // - - -#ifdef RTI_WIN32 - /* strtok, fopen warnings */ - #pragma warning( disable : 4996 ) -#endif - -#ifdef RTI_WIN32 - #define DllExport __declspec( dllexport ) - #include - #include -#else - #define DllExport - #include - #include - #include -#endif - -#include - -// ------------------------------------------------------------------------- // -// -// OS APIs: -// These APIs wrap common OS functionality of creating a thread and mutex. -// These only support Windows and Linux, and are provided as-is. -// -// ------------------------------------------------------------------------- // - -// A function that takes a void pointer, and is passed to the thread creation -// function. -typedef void* (*ThreadFunction)(void *); - -// ------------------------------------------------------------------------- // -// Wrap threads -// -// Right now this only supports threads on Linux and Windows. -// ------------------------------------------------------------------------- // -class OSThread -{ - -public: - // --- Constructor --- - OSThread(ThreadFunction function, - void *functionParam); - - // Run the thread - void Run(); - -private: - // --- Private members --- - - // OS-specific thread definition -#ifdef RTI_WIN32 - HANDLE _thread; -#else - pthread_t _thread; -#endif - // Function called by OS-specific thread - ThreadFunction _function; - - // Parameter to the function - void *_functionParam; -}; - -// ------------------------------------------------------------------------- // -// Wrap mutexes -// -// Right now, this only supports mutexes on Linux and Windows -// ------------------------------------------------------------------------- // -class OSMutex -{ -public: - // --- Constructor and destructor --- - OSMutex(); - ~OSMutex(); - - // --- Lock and unlock mutext --- - void Lock(); - void Unlock(); -private: - // --- Private members --- - - // OS-specific mutex constructs -#ifdef RTI_WIN32 - CRITICAL_SECTION _handleCriticalSection; -#else - pthread_mutex_t _mutex; -#endif -}; - - -#endif diff --git a/ChocolateFactory/ExampleCode/src/Config/base_profile_multicast.xml b/ChocolateFactory/ExampleCode/src/Config/base_profile_multicast.xml index 038e3a07..a87b7755 100644 --- a/ChocolateFactory/ExampleCode/src/Config/base_profile_multicast.xml +++ b/ChocolateFactory/ExampleCode/src/Config/base_profile_multicast.xml @@ -1,25 +1,27 @@ - + xsi:noNamespaceSchemaLocation="http://community.rti.com/schema/6.1.0/rti_dds_qos_profiles.xsd"> @@ -29,72 +31,15 @@ RTI Connext user manual. size allowed for UDP. This is required to get the maximum possible throughput. --> - - - 65507 - - - - - - - dds.transport.UDPv4.builtin.parent.message_size_max - 65507 - - - - - dds.transport.UDPv4.builtin.send_socket_buffer_size - 2097152 - - - dds.transport.UDPv4.builtin.recv_socket_buffer_size - 2097152 - - - - - dds.transport.shmem.builtin.parent.message_size_max - 65507 - - - - - dds.transport.shmem.builtin.receive_buffer_size - 2097152 - - - - - dds.transport.shmem.builtin.received_message_count_max - 2048 - - - - - - - + + BuiltinQosSnippetLib::Optimization.Transport.LargeBuffers + - - + - - - - - diff --git a/ChocolateFactory/ExampleCode/src/Config/base_profile_no_multicast.xml b/ChocolateFactory/ExampleCode/src/Config/base_profile_no_multicast.xml index 1b58223e..433b21bc 100644 --- a/ChocolateFactory/ExampleCode/src/Config/base_profile_no_multicast.xml +++ b/ChocolateFactory/ExampleCode/src/Config/base_profile_no_multicast.xml @@ -1,24 +1,27 @@ - + + xsi:noNamespaceSchemaLocation="http://community.rti.com/schema/6.1.0/rti_dds_qos_profiles.xsd"> @@ -28,79 +31,13 @@ RTI Connext user manual. size allowed for UDP. This is required to get the maximum possible throughput. --> - - - - 65507 - - - - - - - - dds.transport.UDPv4.builtin.parent.message_size_max - 65507 - - - - - dds.transport.UDPv4.builtin.send_socket_buffer_size - 2097152 - - - dds.transport.UDPv4.builtin.recv_socket_buffer_size - 2097152 - - - - - dds.transport.shmem.builtin.parent.message_size_max - 65507 - - - - - dds.transport.shmem.builtin.receive_buffer_size - 2097152 - - - - - dds.transport.shmem.builtin.received_message_count_max - 2048 - - - - - - - + + BuiltinQosSnippetLib::Optimization.Transport.LargeBuffers + - - - - @@ -111,10 +48,7 @@ RTI Connext user manual. - - - diff --git a/ChocolateFactory/ExampleCode/src/Config/recipe_profiles_multicast.xml b/ChocolateFactory/ExampleCode/src/Config/recipe_profiles_multicast.xml index c157ee5a..582d5027 100644 --- a/ChocolateFactory/ExampleCode/src/Config/recipe_profiles_multicast.xml +++ b/ChocolateFactory/ExampleCode/src/Config/recipe_profiles_multicast.xml @@ -1,61 +1,45 @@ - + + xsi:noNamespaceSchemaLocation="http://community.rti.com/schema/6.1.0/rti_dds_qos_profiles.xsd"> - - - - + + + RTIExampleQosLibrary::OneToManyMulticast + + + + Chocolate Factory Application + + - - - - RELIABLE_RELIABILITY_QOS - - - - - TRANSIENT_LOCAL_DURABILITY_QOS - - - - - - KEEP_LAST_HISTORY_QOS - 1 - - - - - - + 0 50000000 @@ -89,88 +71,26 @@ RTI Connext user manual. 0 50000000 - - - - 0 - 0 - - - true - - - - - - RELIABLE_RELIABILITY_QOS - - - - - TRANSIENT_LOCAL_DURABILITY_QOS - - - - - - KEEP_LAST_HISTORY_QOS - 1 - - - - - - - - 0 - 0 - - - 0 - 0 - - - - - - - - Chocolate Factory Application - - - - - diff --git a/ChocolateFactory/ExampleCode/src/Config/recipe_profiles_no_multicast.xml b/ChocolateFactory/ExampleCode/src/Config/recipe_profiles_no_multicast.xml index 72f19e46..5baf9ff1 100644 --- a/ChocolateFactory/ExampleCode/src/Config/recipe_profiles_no_multicast.xml +++ b/ChocolateFactory/ExampleCode/src/Config/recipe_profiles_no_multicast.xml @@ -1,61 +1,45 @@ - + + xsi:noNamespaceSchemaLocation="http://community.rti.com/schema/6.1.0/rti_dds_qos_profiles.xsd"> - - - - + + + RTIExampleQosLibrary::MulticastNotAvailable + + + + Chocolate Factory Application + + - - - - RELIABLE_RELIABILITY_QOS - - - - - TRANSIENT_LOCAL_DURABILITY_QOS - - - - - - KEEP_LAST_HISTORY_QOS - 1 - - - - - - + 0 50000000 @@ -89,88 +71,26 @@ RTI Connext user manual. 0 50000000 - - - - 0 - 0 - - - true - - - - - - RELIABLE_RELIABILITY_QOS - - - - - TRANSIENT_LOCAL_DURABILITY_QOS - - - - - - KEEP_LAST_HISTORY_QOS - 1 - - - - - - - - 0 - 0 - - - 0 - 0 - - - - - - - - Chocolate Factory Application - - - - - diff --git a/ChocolateFactory/ExampleCode/src/Idl/ChocolateFactory.idl b/ChocolateFactory/ExampleCode/src/Idl/ChocolateFactory.idl index 3861145c..c770883a 100644 --- a/ChocolateFactory/ExampleCode/src/Idl/ChocolateFactory.idl +++ b/ChocolateFactory/ExampleCode/src/Idl/ChocolateFactory.idl @@ -17,7 +17,7 @@ const string RECIPE_TOPIC = "ChocolateRecipes"; const string CHOCOLATE_LOT_TOPIC = "ChocolateLotState"; const string QOS_LIBRARY = "RTIExampleQosLibrary"; -const string QOS_PROFILE_STATE_DATA = "FactoryStateData"; +const string QOS_PROFILE_STATE_DATA = "RTIExampleQosLibrary::FactoryStateData"; const long MAX_INGREDIENT_LIST = 9; const long MAX_RECIPE_STEPS = 9; diff --git a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx index 1862eac0..0a2fb611 100644 --- a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx @@ -1,38 +1,39 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ + +#include "MESInterface.hpp" -#include "MESInterface.h" - -using namespace DDS; using namespace com::chocolatefactory::generated; - // ------------------------------------------------------------------------- // // The MESInterface is the network interface to the whole Manufacturing // Execution System application. This creates DataReaders and DataWriters -// in order to receive and send data. +// in order to receive and send data. // // This interface is built from: // 1. Network data types and topic names defined in the IDL file -// 2. XML configuration files that describe the QoS profiles that should be -// used by individual DataWriters and DataReaders. These describe the +// 2. XML configuration files that describe the QoS profiles that should be +// used by individual DataWriters and DataReaders. These describe the // movement and persistence characteristics of the data (how reliable should // this be?), as well as other QoS such as resource limits. -// 3. The code itself creates DataReaders and DataWriters, and selects which +// 3. The code itself creates DataReaders and DataWriters, and selects which // profile to use when creating the DataReaders and DataWriters. // // Reading ChocolateLotState data: // ------------------------------ -// The Manufacturing Execution System listens to chocolate lot state data that +// The Manufacturing Execution System listens to chocolate lot state data that // indicates the current location of the chocolate lot state according to each -// Station Controller. +// Station Controller. // // !!! // NOTE: This may receive updates about a chocolate lot state out of order, @@ -40,18 +41,18 @@ using namespace com::chocolatefactory::generated; // that could reside on multiple machines. Getting in-order data from multiple // sources can be difficult, and may require finely-synchronized clocks on each // machine. -// +// // Writing ChocolateLotState data: // ---------------------------- -// This application sends chocolate lot state data, using the announcement to -// assign the chocolate lot to a particular controller. This sets the +// This application sends chocolate lot state data, using the announcement to +// assign the chocolate lot to a particular controller. This sets the // chocolate lot state to: // - Assigned to the next station controller. -// -// For information on the ChocolateRecipe or ChocolateLotState types, please see the -// ChocolateFactory.idl file. // -// For information on the quality of service for state data, please see the +// For information on the ChocolateRecipe or ChocolateLotState types, please see +// the ChocolateFactory.idl file. +// +// For information on the quality of service for state data, please see the // recipe_profiles_multicast.xml file. // // @@ -61,108 +62,35 @@ using namespace com::chocolatefactory::generated; // 1. It is sent reliably (RELIABLE_RELIABILITY_QOS) // 2. It is made available to late-joining applications as soon as they start // (TRANSIENT_LOCAL_DURABILITY_QOS) -// 3. A predetermined amount of state is sent to any late-joiners. In this +// 3. A predetermined amount of state is sent to any late-joiners. In this // case, applications are only interested in the current state of each // chocolate lot (or the current chocolate recipe), which translates to a // history with depth = 1, kind = KEEP_LAST_HISTORY_QOS // // ------------------------------------------------------------------------- // -MESInterface::MESInterface( - std::vectorqosFileNames) -{ - - // Creating the communicator object - _communicator = new DDSCommunicator(); - - // Calling the DDSCommunicator class's CreateParticipant method. - // This creates the DomainParticpant, the first step in creating a DDS - // application. This starts the discovery process. For more information - // on what the DomainParticipant is responsible for, and how to configure - // it, see DDSCommunicator class - - // Note: all data in this example is "state data." The string constants with the - // QoS library name and the QoS profile name are configured as constants in - // the .idl file. The profiles themselves are configured in the .xml file. - // Look in the XML for more details on the definition of state data. - if (NULL == GetCommunicator()->CreateParticipant( - 0, - qosFileNames, - QOS_LIBRARY, - QOS_PROFILE_STATE_DATA)) - { - std::stringstream errss; - errss << "Failed to create DomainParticipant object"; - throw errss.str(); - } - - - // Calling the DDSCommunicator class's CreatePublisher method. - // You do _not_ need to create one publisher per DataWriter. - Publisher *publisher = GetCommunicator()->CreatePublisher(); - - if (publisher == NULL) - { - std::stringstream errss; - errss << "Failed to create Publisher object"; - throw errss.str(); - } - - // Creating the application's ChocolateLotStateWriter object. - // This could use the RTI Connext DDS writer directly as a way to write. - // This DataWriter is configured with QoS for state data. - _chocolateLotStateWriter = new ChocolateLotStateWriter( - GetCommunicator(), - publisher, - QOS_LIBRARY, - QOS_PROFILE_STATE_DATA); - if (_chocolateLotStateWriter == NULL) - { - std::stringstream errss; - errss << "Failed to create ChocolateLotState DataWriter object"; - throw errss.str(); - } - - - // Creating a DDS subscriber. - // You do _not_ need to create one subscriber per DataReader. - Subscriber *subscriber = GetCommunicator()->CreateSubscriber(); - if (subscriber == NULL) - { - std::stringstream errss; - errss << "Failed to create Subscriber object"; - throw errss.str(); - } - - // Creating the application's ChocolateLotStateReader object. - // We could give the application access to the DataReader directly, but - // this simplifies the application's access - this creates the objects that - // allow the application to block a thread until a ChocolateLotState update - // is received that notifies this MES that a chocolate lot state has been - // updated. - // This DataReader is configured with QoS for state data. - _chocolateLotStateReader = new ChocolateLotStateReader( - GetCommunicator(), - subscriber, - QOS_LIBRARY, - QOS_PROFILE_STATE_DATA, - INVALID_CONTROLLER); - - if (_chocolateLotStateReader == NULL) - { - std::stringstream errss; - errss << "Failed to create ChocolateLotState DataReader object"; - throw errss.str(); - } - +MESInterface::MESInterface(std::vector& qosFileNames) : + _profile(QOS_PROFILE_STATE_DATA), + _communicator(DDSCommunicator(qosFileNames, _profile)), + _topicChocolateLotState(dds::topic::Topic( + _communicator.Participant(), CHOCOLATE_LOT_TOPIC, + _communicator.Qos().topic_qos(_profile))), + _writerChocolateLotState(dds::pub::DataWriter( + _communicator.Publisher(), _topicChocolateLotState, + _communicator.Qos().datawriter_qos(_profile))), + _readerChocolateLotState(dds::sub::DataReader( + _communicator.Subscriber(), _topicChocolateLotState, + _communicator.Qos().datareader_qos(_profile))) +{ + // Note: all data in this example is "state data." The string constants + // with the QoS library name and the QoS profile name are configured as + // constants in the .idl file. The profiles themselves are configured in + // the .xml file. Look in the XML for more details on the definition of + // state data. } // ------------------------------------------------------------------------- // -// Deleting the ChocolateLotState DataWriter, and the ChocolateLotState -// DataReader and the communicator infrastructure. See the -// individual destructors to see how these are deleted. +// Destruction of objects within this class are handled in the destruction of +// the DDSCommunicator class MESInterface::~MESInterface() -{ - delete _chocolateLotStateWriter; - delete _chocolateLotStateReader; -} +{ } \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.h b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.h deleted file mode 100644 index 96e48bda..00000000 --- a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.h +++ /dev/null @@ -1,110 +0,0 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ - -#ifndef MES_INTERFACE_H -#define MES_INTERFACE_H - -#include -#include "../Generated/ChocolateFactory.h" -#include "../CommonInfrastructure/DDSCommunicator.h" -#include "../CommonInfrastructure/DDSTypeWrapper.h" -#include "../CommonInfrastructure/ChocolateLotStateEntities.h" - -using namespace com::chocolatefactory::generated; - -// ---------------------------------------------------------------------------- -// -// The manufacturing execution system interface provides lot plans -// over the network (or shared memory) to other applications that are interested -// in monitoring the state of chocolate lots. -// -// Writing chocolate lot state data: -// --------------------------------- -// This application sends chocolate lot state data, configured to behave as -// state data (or last-value cache). This will reliably deliver each chocolate -// lot state update to both existing and late-joining applications that subscribe -// to chocolate lot state data. -// -// This application is responsible for sending the initial chocolate lot state -// update to announce that there is a new lot that needs to be processed by all -// of the controllers. -// -// For information on the chocolate lot state data type, please see the -// ChocolateFactory.idl file. -// -// For information on the quality of service for chocolate lot state data, -// please see the recipe_profiles_multicast.xml or -// recipe_profiles_no_multicast.xml file. -// -// ---------------------------------------------------------------------------- -class MESInterface -{ - -public: - - // --- Constructor --- - // Initializes the manufacturing executive interface, including creating a - // DomainParticipant, creating all publishers and subscribers, topics - // writers and readers. Takes as input a vector of xml QoS files that - // should be loaded to find QoS profiles and libraries. - MESInterface(std::vector xmlFiles); - - // --- Destructor --- - ~MESInterface(); - - // --- Getter for the ChocolateLotStateWriter --- - // This returns a ChocolateLotStateWriter object, which is the part of the - // network interface that sends the chocolate lot's current state data over - // the network. Look at the ChocolateLotStateWriter class to see how to write - // data in RTI Connext DDS. - ChocolateLotStateWriter *GetChocolateLotStateWriter() - { - return _chocolateLotStateWriter; - } - - // --- Getter for the ChocolateLotStateReader --- - // This returns the ChocolateLotState reader - a small wrapper around the - // ChocolateLotStateDataReader that initializes the reader, the - // topic, and uses the DDS "WaitSet" object to wait for the chocolate lot - // state updates - ChocolateLotStateReader *GetChocolateLotStateReader() - { - return _chocolateLotStateReader; - } - - // --- Getter for Communicator --- - // Accessor for the communicator (the class that sets up the basic - // DDS infrastructure like the DomainParticipant). - // This allows access to the DDS DomainParticipant/Publisher/Subscriber - // classes - DDSCommunicator *GetCommunicator() - { - return _communicator; - } - -private: - // --- Private members --- - - // This contains the calls that allow the interface to create a - // "DomainParticipant", the first object that must be created to - // communicate over a DDS middleware. - DDSCommunicator *_communicator; - - - // Wrapper class around RTI Connext DDS for writing chocolate lot state - ChocolateLotStateWriter *_chocolateLotStateWriter; - - // Used for receiving chocolate lot state data, and being notified about - // the arrival of chocolate lot updates - ChocolateLotStateReader *_chocolateLotStateReader; - -}; - -#endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp new file mode 100644 index 00000000..45af29b9 --- /dev/null +++ b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp @@ -0,0 +1,99 @@ +/********************************************************************************************* +(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. +RTI grants Licensee a license to use, modify, compile, and create derivative +works of the Software. Licensee has the right to distribute object form only +for use with RTI products. The Software is provided as is, with no warranty +of any type, including any warranty for fitness for any purpose. RTI is under no +obligation to maintain or support the Software. RTI shall not be liable for any +incidental or consequential damages arising out of the use or inability to use +the software. +**********************************************************************************************/ + +#ifndef MES_INTERFACE_H +#define MES_INTERFACE_H + +#include +#include "../Generated/ChocolateFactory.hpp" +#include "../CommonInfrastructure/DDSCommunicator.hpp" + +using namespace com::chocolatefactory::generated; + +// ---------------------------------------------------------------------------- +// +// The manufacturing execution system interface provides lot plans +// over the network (or shared memory) to other applications that are interested +// in monitoring the state of chocolate lots. +// +// Writing chocolate lot state data: +// --------------------------------- +// This application sends chocolate lot state data, configured to behave as +// state data (or last-value cache). This will reliably deliver each chocolate +// lot state update to both existing and late-joining applications that +// subscribe to chocolate lot state data. +// +// This application is responsible for sending the initial chocolate lot state +// update to announce that there is a new lot that needs to be processed by all +// of the controllers. +// +// For information on the chocolate lot state data type, please see the +// ChocolateFactory.idl file. +// +// For information on the quality of service for chocolate lot state data, +// please see the recipe_profiles_multicast.xml or +// recipe_profiles_no_multicast.xml file. +// +// ---------------------------------------------------------------------------- +class MESInterface { +public: + // --- Constructor --- + // Initializes the manufacturing executive interface, including creating a + // DomainParticipant, creating all publishers and subscribers, topics + // writers and readers. Takes as input a vector of xml QoS files that + // should be loaded to find QoS profiles and libraries. + MESInterface(std::vector& xmlFiles); + + // --- Destructor --- + ~MESInterface(); + + // --- Getter for the ChocolateLotStateWriter --- + // This returns a ChocolateLotStateWriter object, which is the part of the + // network interface that sends the chocolate lot's current state data over + // the network. + dds::pub::DataWriter& WriterChocolateLotState() + { + return _writerChocolateLotState; + } + + // --- Getter for the ChocolateLotStateReader --- + // This returns the ChocolateLotState reader - a small wrapper around the + // ChocolateLotStateDataReader that initializes the reader, the + // topic, and uses the DDS "WaitSet" object to wait for the chocolate lot + // state updates + dds::sub::DataReader& ReaderChocolateLotState() + { + return _readerChocolateLotState; + } + +private: + // --- Private members --- + + // Stores profile based on elements from IDL file + std::string _profile; + + // This contains the calls that allow the interface to create a + // "DomainParticipant", the first object that must be created to + // communicate over a DDS middleware. + DDSCommunicator& _communicator; + + // Topic object used to define the datatype use by the ChocolateLotState + // DataReader and DataWriter + dds::topic::Topic& _topicChocolateLotState; + + // DataWriter object for ChocolateLotState + dds::pub::DataWriter& _writerChocolateLotState; + + // DataReader used for receiving chocolate lot state data + dds::sub::DataReader& _readerChocolateLotState; +}; + +#endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/ManufacturingExecutionSystem.cxx b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/ManufacturingExecutionSystem.cxx index f654b41f..87837b53 100644 --- a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/ManufacturingExecutionSystem.cxx +++ b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/ManufacturingExecutionSystem.cxx @@ -1,39 +1,41 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ #include #include #include -#include "../Generated/ChocolateFactory.h" -#include "../CommonInfrastructure/DDSTypeWrapper.h" -#include "../CommonInfrastructure/EnumPrintHelpers.h" -#include "../CommonInfrastructure/OSAPI.h" -#include "MESInterface.h" +#include +#include "../CommonInfrastructure/EnumPrintHelpers.hpp" +#include "MESInterface.hpp" +#include "../CommonInfrastructure/InputParser.hpp" using namespace std; void PrintHelp(); -void *PrintLotUpdates(void *param); +void PrintLotUpdates(rti::sub::LoanedSamples); // ------------------------------------------------------------------------- // // // // This application writes updates announcing that a chocolate lot is ready to // be processed. It fills in the details of the recipe name and the first -// station controller to process the lot, and announces over the network that +// station controller to process the lot, and announces over the network that // the lot should be processed. // -// This also listens for chocolate lot state data so it can print information +// This also listens for chocolate lot state data so it can print information // displaying the chocolate lot state data as the state is updated. // -// The chocolate lot state data is modeled as RTI Connext DDS "state data," +// The chocolate lot state data is modeled as RTI Connext DDS "state data," // meaning: // 1) the data is modeled to have a key field which differentiates individual // updates of each lot from each station controller. This key fields are @@ -44,243 +46,198 @@ void *PrintLotUpdates(void *param); // even if the subscribing applications do not exist, yet, they will be // notified of all lot updates as soon as they create the corresponding // DataReader. -// 3) With a history set to: kind = keep last, depth = 1. This means that -// just the most recent update to each chocolate lot sate will be sent to -// DataReaders at startup. -// Note: THIS HISTORY SETTING IS NOT APPROPRIATE FOR STRICT RELIABLITY. -// If you were to rapidly update the same lot state many times, it is -// possible that some updates would be overwritten. This guarantees +// 3) With a history set to: kind = keep last, depth = 1. This means that +// just the most recent update to each chocolate lot sate will be sent to +// DataReaders at startup. +// Note: THIS HISTORY SETTING IS NOT APPROPRIATE FOR STRICT RELIABILITY. +// If you were to rapidly update the same lot state many times, it is +// possible that some updates would be overwritten. This guarantees // delivery of the _most recent_ update to the lot state. // -// Note: it is possible to get chocolate lot state updates "out of order," +// Note: it is possible to get chocolate lot state updates "out of order," // meaning that you may see an update saying that a particular controller is -// processing the lot and THEN get an update saying it was assigned to that +// processing the lot and THEN get an update saying it was assigned to that // controller. This is inherent in the fact that you are getting updates from // multiple sources that could be sending updates from multiple machines. // ------------------------------------------------------------------------- // -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - - int numLotsToProcess = 5; - int timeBetweenLotCommands = 20; // 20 Seconds - bool multicastAvailable = true; - for (int i = 0; i < argc; i++) - { - if (0 == strcmp(argv[i], "--num-lots")) - { - ++i; - if (i == argc) - { - cout << "Bad parameter: Did not pass number of lots" << endl; - return -1; - } - numLotsToProcess = atoi(argv[i]); - } else if (0 == strcmp(argv[i], "--time-between")) - { - ++i; - if (i == argc) - { - cout << "Bad parameter: Did not pass number of seconds between lot commands" - << endl; - return -1; - } - timeBetweenLotCommands = atoi(argv[i]); - } else if (0 == strcmp(argv[i], "--no-multicast")) - { - multicastAvailable = false; - } else if (0 == strcmp(argv[i], "--help")) - { - PrintHelp(); - return 0; - } else if (i > 0) - { - // If we have a parameter that is not the first one, and is not - // recognized, return an error. - cout << "Bad parameter: " << argv[i] << endl; - PrintHelp(); - return -1; - } - - } - - // Set up paths for XML files. The profiles are for applications that - // have no multicast available at all, or that have multicast available - // on the network. - vector xmlFiles; - - if (multicastAvailable) - { - // Adding the XML files that contain profiles used by this application - xmlFiles.push_back( - "file://../../../src/Config/base_profile_multicast.xml"); - xmlFiles.push_back( - "file://../../../src/Config/recipe_profiles_multicast.xml"); - } - else - { - // Adding the XML files that contain profiles used by this application - xmlFiles.push_back( - "file://../../../src/Config/base_profile_no_multicast.xml"); - xmlFiles.push_back( - "file://../../../src/Config/recipe_profiles_no_multicast.xml"); - } - - try - { - - // This is the network interface for this application - this is what - // actually sends the lot state information over the transport - // (shared memory or over the network). Look into this class to see - // what you need to do to implement an RTI Connext DDS application that - // reads and writes data. - MESInterface mesInterface(xmlFiles); - - // Start a thread that will listen for updates about lots as they pass - // through the different station controllers - OSThread *thread = new OSThread( - (ThreadFunction)PrintLotUpdates, &mesInterface); - thread->Run(); - - DDS_Duration_t send_period = {timeBetweenLotCommands,0}; - - cout << "Sending chocolate lot commands over RTI Connext DDS\n" - << endl; - vector recipeNames; - recipeNames.push_back("Dark"); - recipeNames.push_back("Milk"); - recipeNames.push_back("White"); - - - // Write all chocolate lots up to the number specified - for (int i = 0; i < numLotsToProcess; i++) - { - - // Allocate a chocolate lot state - DdsAutoType lotState; - - // Give it an ID number - lotState.lotID = i; - - // Currently this lot is not at a controller - lotState.controller = INVALID_CONTROLLER; - - // Give it a recipe type: plain dark chocolate, milk chocolate, or - // white chocolate - sprintf(lotState.recipeName, "%s", - recipeNames[i % 3].c_str()); - - // All lots must to go the sugar controller first - lotState.nextController = SUGAR_CONTROLLER; - - // The current lot status is that it is assigned to a station - // controller. - lotState.lotStatus = ASSIGNED_TO_SC; - - cout << "Sending command to start lot with recipe " << - lotState.recipeName << endl; - - // Write the data to the network. This is a thin wrapper - // around the RTI Connext DDS DataWriter that writes data to - // the network. - mesInterface.GetChocolateLotStateWriter()-> - PublishChocolateLotState(lotState); - - NDDSUtility::sleep(send_period); - } - - // Wait for updates about chocolate lots and print out their status - while (1) - { - NDDSUtility::sleep(send_period); - } - } - catch (string message) - { - cout << "Application exception" << message << endl; - } - - return 0; + int numLotsToProcess = 5; + int timeBetweenLotCommands = 20; // 20 Seconds + bool multicastAvailable = true; + InputParser input(argc, argv); + + if (input.cmdOptionExists("--help")) { + PrintHelp(); + return 0; + } + + if (input.cmdOptionExists("--num-lots")) { + const std::string& numLots = input.getCmdOption("--num-lots"); + if (numLots.empty()) { + std::cout << "Bad parameter: Did not pass number of lots" << endl; + return -1; + } + numLotsToProcess = atoi(numLots.c_str()); + } + + if (input.cmdOptionExists("--time-between")) { + const std::string& timeBetween = input.getCmdOption("--time-between"); + if (timeBetween.empty()) { + std::cout << "Bad parameter: Did not pass number of seconds between lot commands" + << endl; + return -1; + } + timeBetweenLotCommands = atoi(timeBetween.c_str()); + } + + if (input.cmdOptionExists("--no-multicast")) + multicastAvailable = false; + + // Set up paths for XML files. The profiles are for applications that have + // no multicast available at all, or that have multicast available on the + // network. + vector xmlFiles; + + if (multicastAvailable) { + // Adding the XML files that contain profiles used by this application + xmlFiles.push_back("file://../src/Config/base_profile_multicast.xml"); + xmlFiles.push_back( + "file://../src/Config/recipe_profiles_multicast.xml"); + } + else { + // Adding the XML files that contain profiles used by this application + xmlFiles.push_back( + "file://../src/Config/base_profile_no_multicast.xml"); + xmlFiles.push_back( + "file://../src/Config/recipe_profiles_no_multicast.xml"); + } + + try { + // This is the network interface for this application - this is what + // actually sends the lot state information over the transport + // (shared memory or over the network). Look into this class to see + // what you need to do to implement an RTI Connext DDS application that + // reads and writes data. + MESInterface mesInterface(xmlFiles); + + // Get the reader, create a read condition and attach PrintLotUpdates + // Every time new data is available, the read condition will trigger + // and call the PrintLotUpdates function with the available samples. + dds::sub::DataReader reader = + mesInterface.ReaderChocolateLotState(); + dds::sub::cond::ReadCondition readCondition( + reader, dds::sub::status::DataState::new_data(), [&reader]() { + PrintLotUpdates(reader.take()); + }); + + // Create a Waitset for processing of read condition(s) + dds::core::cond::WaitSet waitSet; + + // Add the read condition to the WaitSet + waitSet += readCondition; + + dds::core::Duration send_period(timeBetweenLotCommands, 0); + + cout << "Sending chocolate lot commands over RTI Connext DDS\n" << endl; + vector recipeNames; + recipeNames.push_back("Dark"); + recipeNames.push_back("Milk"); + recipeNames.push_back("White"); + + // Write all chocolate lots up to the number specified + for (int i = 0; i < numLotsToProcess; i++) { + // Allocate a chocolate lot state + ChocolateLotState lotState; + + // Give it an ID number + lotState.lotID() = i; + + // Currently this lot is not at a controller + lotState.controller() = StationControllerKind::INVALID_CONTROLLER; + + // Give it a recipe type: plain dark chocolate, milk chocolate, or + // white chocolate + cout << lotState.recipeName() << recipeNames[i % 3] << endl; + + // All lots must to go the sugar controller first + lotState.nextController() = StationControllerKind::SUGAR_CONTROLLER; + + // The current lot status is that it is assigned to a station + // controller. + lotState.lotStatus() = LotStatusKind::ASSIGNED_TO_SC; + + cout << "Sending command to start lot with recipe " + << lotState.recipeName() << endl; + + // Write the data to the network. + mesInterface.WriterChocolateLotState().write(lotState); + + rti::util::sleep(send_period); + } + + // Wait for updates about chocolate lots and print out their status + while (1) { + waitSet.dispatch(send_period); + } + } + catch (string message) { + cout << "Application exception" << message << endl; + } + + return 0; } // ------------------------------------------------------------------------- // // This function waits for updates to lot states as they arrive over DDS (over // the network or shared memory). When it receives updates to lot states, it // prints the current state of the lot to the screen. -// -// Note: it is possible to get these updates "out of order," meaning that you +// +// Note: it is possible to get these updates "out of order," meaning that you // may see an update saying that a particular controller is processing the lot -// and THEN get an update saying it was assigned to that controller. This is +// and THEN get an update saying it was assigned to that controller. This is // inherent in the fact that you are getting updates from multiple sources that // could be on multiple machines. -void *PrintLotUpdates(void *param) +void PrintLotUpdates(rti::sub::LoanedSamples samples) { - MESInterface *mesInterface = (MESInterface *)param; - - while (1) - { - vector< DdsAutoType > lotStates; - - // This blocks a thread until chocolate lot state updates become - // available over DDS. It fills in the vector with chocolate lot state - // updates. - mesInterface->GetChocolateLotStateReader()-> - WaitForChocolateLotUpdates(&lotStates); - - // Iterate over the chocolate lot state updates that have arrived - for (int i = 0; i < lotStates.size(); i++) - { - string lotStatus, controllerName; - - // Get the name of the lot status to help with printing - LotStatusType::GetLotStatusPrettyName(lotStates[i].lotStatus, - lotStatus); - - // If the lot is not "assigned to station controller" print the - // current station controller - if (lotStates[i].lotStatus != ASSIGNED_TO_SC) - { - // Get the name of the current station controller that is - // updating the state of the chocolatel ot. - StationControllerType::GetControllerPrettyName( - lotStates[i].controller, - controllerName); - } else - { - // If the lot is "assigned to station controller," print the - // name of the next station controller that it is assigned to - StationControllerType::GetControllerPrettyName( - lotStates[i].nextController, - controllerName); - } - - cout << "Lot #" << lotStates[i].lotID - << " is in state: " - << lotStatus.c_str() - << " at controller: " - << controllerName.c_str() << endl; - + // Iterate over the chocolate lot state updates that have arrived + for (auto sample : samples) { + string controllerName; + + // If the lot is not "assigned to station controller" print the + // current station controller + if (sample.data().lotStatus() != LotStatusKind::ASSIGNED_TO_SC) { + // Get the name of the current station controller that is + // updating the state of the chocolate ot. + controllerName = StationControllerType::ControllerPrettyName( + sample.data().controller()); } - } + else { + // If the lot is "assigned to station controller," print the + // name of the next station controller that it is assigned to + controllerName = StationControllerType::ControllerPrettyName( + sample.data().nextController()); + } + + cout << "Lot #" << sample.data().lotID() + << " is in state: " + << LotStatusType::LotStatusPrettyName(sample.data().lotStatus()) + << " at controller: " << controllerName << endl; + } + } void PrintHelp() { - cout << "Valid options are: " << endl; - cout << - " --num-lots [num]" << - " Number of lots to start before shutting down" - << endl; - cout << - " --time-between [time in ms]" << - " Time between starting lot batches" - << endl; - cout << - " --no-multicast" << - " Do not use multicast " << - "(note you must edit XML" << endl << - " " << - "config to include IP addresses)" - << endl; - -} + cout << "Valid options are: " << endl; + cout << " --num-lots [num]" + << " Number of lots to start before shutting down" << endl; + cout << " --time-between [time in ms]" + << " Time between starting lot batches" << endl; + cout << " --no-multicast" + << " Do not use multicast " + << "(note you must edit XML" << endl + << " " + << "config to include IP addresses)" << endl; +} \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipeGenerator.cxx b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipeGenerator.cxx index 2ea9b638..3f71d4ca 100644 --- a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipeGenerator.cxx +++ b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipeGenerator.cxx @@ -1,20 +1,22 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ #include #include #include -#include "../Generated/ChocolateFactory.h" -#include "../Generated/ChocolateFactorySupport.h" -#include "../CommonInfrastructure/DDSTypeWrapper.h" -#include "RecipePublisherInterface.h" +#include "../Generated/ChocolateFactory.hpp" +#include "RecipePublisherInterface.hpp" +#include "../CommonInfrastructure/InputParser.hpp" using namespace std; using namespace com::chocolatefactory::generated; @@ -23,15 +25,15 @@ void PrintHelp(); // ------------------------------------------------------------------------- // // -// +// // This application creates a number of recipes that are available for, this // factory, and sends them over the network. It sends all of these recipes // immediately using a design for state data. This means that the recipes -// are available to any interested application as soon as that appliation +// are available to any interested application as soon as that application // starts up. // // The recipe data is modeled as RTI Connext DDS "state data," meaning: -// 1) the recipe is modeled to have a key field which differentiates +// 1) the recipe is modeled to have a key field which differentiates // individual recipes. This key field is the recipe name. // // and that it is sent: @@ -40,11 +42,11 @@ void PrintHelp(); // even if the subscribing applications do not exist, yet, they will be // notified of all recipes as soon as they create the corresponding // DataReader. -// 3) With a history set to: kind = keep last, depth = 1. This means that -// just the most recent update to each recipe will be sent to -// DataReaders at startup. This means that it a recipe is updated, +// 3) With a history set to: kind = keep last, depth = 1. This means that +// just the most recent update to each recipe will be sent to +// DataReaders at startup. This means that it a recipe is updated, // other applications will see only the updated recipe. -// Note: THIS HISTORY SETTING IS NOT APPROPRIATE FOR STRICT RELIABLITY. +// Note: THIS HISTORY SETTING IS NOT APPROPRIATE FOR STRICT RELIABILITY. // If you want to see all the updates to a particular recipe that have // ever been made, this setting should be changed to history= keep all. // The current setting guarantees delivery of the _most recent_ update @@ -52,162 +54,126 @@ void PrintHelp(); // // ------------------------------------------------------------------------- // -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - - bool multicastAvailable = true; - for (int i = 0; i < argc; i++) - { - - if (0 == strcmp(argv[i], "--no-multicast")) - { - multicastAvailable = false; - } else if (0 == strcmp(argv[i], "--help")) - { - PrintHelp(); - return 0; - } else if (i > 0) - { - // If we have a parameter that is not the first one, and is not - // recognized, return an error. - cout << "Bad parameter: " << argv[i] << endl; - PrintHelp(); - return -1; - } - - } - int recipeNum = 3; - const std::string recipes[] = { - "Dark","Milk","White"}; - - - // Set up paths for XML files. The profiles are for applications that - // have no multicast available at all, or that have multicast available - // on the network. - vector xmlFiles; - - if (multicastAvailable) - { - // Adding the XML files that contain profiles used by this application - xmlFiles.push_back( - "file://../../../src/Config/base_profile_multicast.xml"); - xmlFiles.push_back( - "file://../../../src/Config/recipe_profiles_multicast.xml"); - } - else - { - // Adding the XML files that contain profiles used by this application - xmlFiles.push_back( - "file://../../../src/Config/base_profile_no_multicast.xml"); - xmlFiles.push_back( - "file://../../../src/Config/recipe_profiles_no_multicast.xml"); - } - try - { - - // This is the network interface for this application - this is what - // actually sends the recipe information over the transport - // (shared memory or over the network). Look into this class to see - // what you need to do to implement an RTI Connext DDS application that - // writes data. - RecipePublisherInterface recipeInterface(xmlFiles); - - - DDS_Duration_t send_period = {0,100000000}; - - cout << "Sending recipes over RTI Connext DDS" << endl; - - - // Write all recipes up to the number specified - for (int i = 0; i < recipeNum; i++) - { - - // Allocate a recipe structure - DdsAutoType recipe; - - // Print each of the three recipes - sprintf(recipe.recipeName, "%s", - recipes[i].c_str()); - - // This sets up the recipes that can be used to create dark - // chocolate, milk chocolate, or white chocolate. In place of real - // recipe steps, it includes the timing that each step in the - // recipe should require. - if (0 == strcmp(recipe.recipeName, "Dark")) - { - recipe.steps.ensure_length(4,4); - recipe.steps[0].stationController = SUGAR_CONTROLLER; - recipe.steps[0].seconds = 1; - recipe.steps[1].stationController = COCOA_BUTTER_CONTROLLER; - recipe.steps[1].seconds = 2; - recipe.steps[2].stationController = COCOA_LIQUOR_CONTROLLER; - recipe.steps[2].seconds = 3; - recipe.steps[3].stationController = VANILLA_CONTROLLER; - recipe.steps[3].seconds = 4; - } - if (0 == strcmp(recipe.recipeName, "Milk")) - { - recipe.steps.ensure_length(5,5); - recipe.steps[0].stationController = SUGAR_CONTROLLER; - recipe.steps[0].seconds = 1; - recipe.steps[1].stationController = COCOA_BUTTER_CONTROLLER; - recipe.steps[1].seconds = 2; - recipe.steps[2].stationController = COCOA_LIQUOR_CONTROLLER; - recipe.steps[2].seconds = 3; - recipe.steps[3].stationController = MILK_CONTROLLER; - recipe.steps[3].seconds = 4; - recipe.steps[4].stationController = VANILLA_CONTROLLER; - recipe.steps[4].seconds = 5; - } - if (0 == strcmp(recipe.recipeName, "White")) - { - recipe.steps.ensure_length(4,4); - recipe.steps[0].stationController = SUGAR_CONTROLLER; - recipe.steps[0].seconds = 1; - recipe.steps[1].stationController = COCOA_BUTTER_CONTROLLER; - recipe.steps[1].seconds = 2; - recipe.steps[2].stationController = MILK_CONTROLLER; - recipe.steps[2].seconds = 3; - recipe.steps[3].stationController = VANILLA_CONTROLLER; - recipe.steps[3].seconds = 4; - - } - - - // Write the data to the network. This is a thin wrapper - // around the RTI Connext DDS DataWriter that writes data to - // the network. - recipeInterface.Write(recipe); - - // Sleep before sending the next recipe. There is no real - // requirement to sleep between sends, except that it stresses - // the network less - NDDSUtility::sleep(send_period); - } - - while (1) - { - NDDSUtility::sleep(send_period); - } - } - catch (string message) - { - cout << "Application exception" << message << endl; - } - - - return 0; + const vector recipes = { "Dark", "Milk", "White" }; + bool multicastAvailable = true; + InputParser input(argc, argv); + + if (input.cmdOptionExists("--help")) { + PrintHelp(); + return 0; + } + + if (input.cmdOptionExists("--no-multicast")) + multicastAvailable = false; + + // Set up paths for XML files. The profiles are for applications that + // have no multicast available at all, or that have multicast available + // on the network. + vector xmlFiles; + + if (multicastAvailable) { + // Adding the XML files that contain profiles used by this application + xmlFiles.push_back("file://../src/Config/base_profile_multicast.xml"); + xmlFiles.push_back( + "file://../src/Config/recipe_profiles_multicast.xml"); + } else { + // Adding the XML files that contain profiles used by this application + xmlFiles.push_back( + "file://../src/Config/base_profile_no_multicast.xml"); + xmlFiles.push_back( + "file://../src/Config/recipe_profiles_no_multicast.xml"); + } + try { + // This is the network interface for this application - this is what + // actually sends the recipe information over the transport + // (shared memory or over the network). Look into this class to see + // what you need to do to implement an RTI Connext DDS application that + // writes data. + RecipePublisherInterface recipeInterface(xmlFiles); + + dds::core::Duration send_period(0, 100000000); + + cout << "Sending recipes over RTI Connext DDS" << endl; + + // Write all recipes up to the number specified + for (auto r : recipes) { + // Allocate a recipe structure + ChocolateRecipe recipe; + + recipe.recipeName(r); + // Print each of the three recipes + cout << r << endl; + + // This sets up the recipes that can be used to create dark + // chocolate, milk chocolate, or white chocolate. In place of real + // recipe steps, it includes the timing that each step in the + // recipe should require. + if ("Dark" == r) { + recipe.steps().reserve(4); + recipe.steps()[0].stationController(StationControllerKind::SUGAR_CONTROLLER); + recipe.steps()[0].seconds(1); + recipe.steps()[1].stationController(StationControllerKind::COCOA_BUTTER_CONTROLLER); + recipe.steps()[1].seconds(2); + recipe.steps()[2].stationController(StationControllerKind::COCOA_LIQUOR_CONTROLLER); + recipe.steps()[2].seconds(3); + recipe.steps()[3].stationController(StationControllerKind::VANILLA_CONTROLLER); + recipe.steps()[3].seconds(4); + } + else if ("Milk" == r) { + recipe.steps().reserve(5); + recipe.steps()[0].stationController(StationControllerKind::SUGAR_CONTROLLER); + recipe.steps()[0].seconds(1); + recipe.steps()[1].stationController(StationControllerKind::COCOA_BUTTER_CONTROLLER); + recipe.steps()[1].seconds(2); + recipe.steps()[2].stationController(StationControllerKind::COCOA_LIQUOR_CONTROLLER); + recipe.steps()[2].seconds(3); + recipe.steps()[3].stationController(StationControllerKind::MILK_CONTROLLER); + recipe.steps()[3].seconds(4); + recipe.steps()[4].stationController(StationControllerKind::VANILLA_CONTROLLER); + recipe.steps()[4].seconds(5); + } + else if ("White" == r) { + recipe.steps().reserve(4); + recipe.steps()[0].stationController(StationControllerKind::SUGAR_CONTROLLER); + recipe.steps()[0].seconds(1); + recipe.steps()[1].stationController(StationControllerKind::COCOA_BUTTER_CONTROLLER); + recipe.steps()[1].seconds(2); + recipe.steps()[2].stationController(StationControllerKind::MILK_CONTROLLER); + recipe.steps()[2].seconds(3); + recipe.steps()[3].stationController(StationControllerKind::VANILLA_CONTROLLER); + recipe.steps()[3].seconds(4); + } + + // Write the data to the network. This is a thin wrapper + // around the RTI Connext DDS DataWriter that writes data to + // the network. + recipeInterface.Write(recipe); + + // Sleep before sending the next recipe. There is no real + // requirement to sleep between sends, except that it stresses + // the network less + rti::util::sleep(send_period); + } + + while (1) { + rti::util::sleep(send_period); + } + } catch (string message) { + cout << "Application exception" << message << endl; + } + + + return 0; } void PrintHelp() { - cout << "Valid options are: " << endl; - cout << - " --no-multicast" << - " Do not use multicast " << - "(note you must edit XML" << endl << - " " << - "config to include IP addresses)" - << endl; - + cout << "Valid options are: " << endl; + cout << " --no-multicast" + << " Do not use multicast " + << "(note you must edit XML" << endl + << " " + << "config to include IP addresses)" << endl; } diff --git a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx index 2739b9c3..7ab376d8 100644 --- a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx @@ -1,165 +1,87 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ -#include "RecipePublisherInterface.h" - +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ + +#include "RecipePublisherInterface.hpp" using namespace com::chocolatefactory::generated; // ---------------------------------------------------------------------------- -// The RecipePublisherInterface is the network interface to the whole +// The RecipePublisherInterface is the network interface to the whole // application. This creates a DataWriter in order to send recipe data -// over the network (or shared memory) to other applications that are +// over the network (or shared memory) to other applications that are // interested in recipes. // // This interface is built from: // 1. Network data types and topic names defined in the IDL file -// 2. XML configuration files that describe the QoS profiles that should be -// used by individual DataWriters and DataReaders. These describe the +// 2. XML configuration files that describe the QoS profiles that should be +// used by individual DataWriters and DataReaders. These describe the // movement and persistence characteristics of the data (how reliable should // this be?), as well as other QoS such as resource limits. // 3. The code itself creates DataWriters, and selects which QoS profile to use // when creating the DataWriters. -// +// // Writing recipe data: // -------------------- // This application sends recipes, configured to act as state data // (or last-value cache). This will reliably deliver the recipes to both // existing and late-joining applications that subscribe to recipes. // -// For information on the recipe data type, please see the -// ChocolateFactory.idl file. +// For information on the recipe data type, please see the +// ChocolateFactory.idl file. // // For information on the quality of service for recipe state data, please -// see the recipe_profiles_multicast.xml or recipe_profiles_no_multicast.xml +// see the recipe_profiles_multicast.xml or recipe_profiles_no_multicast.xml // file. // ------------------------------------------------------------------------- // -RecipePublisherInterface::RecipePublisherInterface(std::vector xmlFiles) +RecipePublisherInterface::RecipePublisherInterface( + std::vector& xmlFiles) : + _communicator(DDSCommunicator(xmlFiles)), + _topic(dds::topic::Topic(_communicator.Participant(), + RECIPE_TOPIC, _communicator.Qos().topic_qos())), + _writer(dds::pub::DataWriter(_communicator.Publisher(), + _topic, _communicator.Qos().datawriter_qos())) { - - // Creating the communicator object - _communicator = new DDSCommunicator(); - - // Create a DomainParticipant - // Start by creating a DomainParticipant. Generally you will have only - // one DomainParticipant per application. A DomainParticipant is - // responsible for starting the discovery process, allocating resources, - // and being the factory class used to create Publishers, Subscribers, - // Topics, etc. - - // Note: all data in this example is "state data." The string constants with the - // QoS library name and the QoS profile name are configured as constants in - // the .idl file. The profiles themselves are configured in the .xml file. - // Look in the XML for more details on the definition of state data. - if (NULL == _communicator->CreateParticipant(0, xmlFiles, - QOS_LIBRARY, - QOS_PROFILE_STATE_DATA)) - { - std::stringstream errss; - errss << "Failed to create DomainParticipant object"; - throw errss.str(); - } - - // Create a Publisher - // This application only writes data, so we only need to create a - // publisher. The StationController application has a more complex pattern - // so we explicitly separate the writing interface from the overall - // network interface - meaning that the publisher is created in the - // network interface, and the DataWriter is created in a separate class - // Note that one Publisher can be used to create multiple DataWriters - DDS::Publisher *pub = _communicator->CreatePublisher(); - - if (pub == NULL) - { - std::stringstream errss; - errss << "Failed to create Publisher object"; - throw errss.str(); - } - - - // Creating a Topic - // The Topic object is the description of the data that you will be - // sending. It associates a particular data type with a name that - // describes the meaning of the data. Along with the data types, and - // whether your application is reading or writing particular data, this - // is the data interface of your application. - - // This topic has the name RECIPE_TOPIC - a constant - // string that is defined in the .idl file. (It is not required that - // you define your topic name in IDL, but it is a best practice for - // ensuring the data interface of an application is all defined in one - // place. You can register all topics and types up-front, if you nee - DDS::Topic *topic = _communicator->CreateTopic( - RECIPE_TOPIC); - - - // Create a DataWriter. - // This creates a single DataWriter that writes recipe data, with QoS - // that is used for State Data. - DDS::DataWriter *writer = pub->create_datawriter_with_profile(topic, - QOS_LIBRARY, QOS_PROFILE_STATE_DATA, - NULL, DDS_STATUS_MASK_NONE); - - // Downcast the generic datawriter to a recipe DataWriter - _writer = ChocolateRecipeDataWriter::narrow(writer); - - if (_writer == NULL) - { - std::stringstream errss; - errss << - "RecipeWriter(): failure to create writer. Inconsistent Qos?"; - throw errss.str(); - } - + // Note: all data in this example is "state data." The string constants + // with the QoS library name and the QoS profile name are configured as + // constants in the .idl file. The profiles themselves are configured in + // the .xml file. Look in the XML for more details on the definition of + // state data. } // ---------------------------------------------------------------------------- // Destructor. // Deletes the DataWriter, and the Communicator object RecipePublisherInterface::~RecipePublisherInterface() -{ - DDS::Publisher *pub = _writer->get_publisher(); - pub->delete_datawriter(_writer); - _writer = NULL; - - delete _communicator; -} +{ } // ---------------------------------------------------------------------------- // Sends the recipe over a transport (such as shared memory or UDPv4) // This writes the Recipe data using RTI Connext DDS to any DataReader // that shares the same Topic -bool RecipePublisherInterface::Write(DdsAutoType data) +void RecipePublisherInterface::Write(ChocolateRecipe data) { - DDS_ReturnCode_t retcode = DDS_RETCODE_OK; - DDS_InstanceHandle_t handle = DDS_HANDLE_NIL; - - // This actually sends the recipe data over the network. - - // The handle that the write() call takes is a handle to the individual - // recipe instance - a unique recipe described by a - // unique recipe name + // This actually sends the recipe data over the network. - // The recipe data has a very simple ID, and does not need high- - // throughput, so we are not bothering to pre-register the instance - // handle. If we did pre-register the instance handle, this could - // potentially speed up the writing. - retcode = _writer->write(data, handle); + // The handle that the write() call takes is a handle to the individual + // recipe instance - a unique recipe described by a + // unique recipe name - if (retcode != DDS_RETCODE_OK) - { - return false; - } - - return true; + // The recipe data has a very simple ID, and does not need high- + // throughput, so we are not bothering to pre-register the instance + // handle. If we did pre-register the instance handle, this could + // potentially speed up the writing. + _writer.write(data); } - diff --git a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.h b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.h deleted file mode 100644 index 2d880385..00000000 --- a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.h +++ /dev/null @@ -1,82 +0,0 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ - -#ifndef RECIPE_PUBLISHER_INTERFACE_H -#define RECIPE_PUBLISHER_INTERFACE_H - -#include -#include "../CommonInfrastructure/DDSCommunicator.h" -#include "../CommonInfrastructure/DDSTypeWrapper.h" -#include "../Generated/ChocolateFactory.h" -#include "../Generated/ChocolateFactorySupport.h" - - -// ---------------------------------------------------------------------------- -// -// The recipe publisher interface provides recipe data over the network -// (or shared memory) to other applications that are interested in recipes. -// -// Writing recipe data: -// -------------------- -// This application sends recipe data, configured to behave as state data -// (or last-value cache). This will reliably deliver each recipe to both -// existing and late-joining applications that subscribe to recipes. -// -// For information on the recipe data type, please see the -// ChocolateFactory.idl file. -// -// For information on the quality of service for recipe state data, please -// see the recipe_profiles_multicast.xml or recipe_profiles_no_multicast.xml -// file. -// -// ---------------------------------------------------------------------------- -class RecipePublisherInterface -{ - -public: - - // --- Constructor --- - // Initializes the recipe publisher interface, including creating a - // DomainParticipant, creating all publishers and subscribers, topics - // writers and readers. Takes as input a vector of xml QoS files that - // should be loaded to find QoS profiles and libraries. - RecipePublisherInterface(std::vector xmlFiles); - - // --- Destructor --- - ~RecipePublisherInterface(); - - // --- Getter for Communicator --- - // Accessor for the communicator (the class that sets up the basic - // DDS infrastructure like the DomainParticipant). - // This allows access to the DDS DomainParticipant/Publisher/Subscriber - // classes - DDSCommunicator *GetCommunicator() - { - return _communicator; - } - - // --- Sends the recipe --- - // Uses DDS interface to send a recipe efficiently over the network - // or shared memory to interested applications subscribing to recipe - // information. - bool Write(DdsAutoType data); - - -private: - // --- Private members --- - - // Used to create basic DDS entities that all applications need - DDSCommunicator *_communicator; - - // Recipe publisher specific to this application - com::chocolatefactory::generated::ChocolateRecipeDataWriter *_writer; -}; - -#endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp new file mode 100644 index 00000000..d4ce8f7d --- /dev/null +++ b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp @@ -0,0 +1,74 @@ +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ + +#ifndef RECIPE_PUBLISHER_INTERFACE_H +#define RECIPE_PUBLISHER_INTERFACE_H + +#include +#include "../CommonInfrastructure/DDSCommunicator.hpp" +#include "../Generated/ChocolateFactory.hpp" + +using namespace com::chocolatefactory::generated; + +// ---------------------------------------------------------------------------- +// +// The recipe publisher interface provides recipe data over the network +// (or shared memory) to other applications that are interested in recipes. +// +// Writing recipe data: +// -------------------- +// This application sends recipe data, configured to behave as state data +// (or last-value cache). This will reliably deliver each recipe to both +// existing and late-joining applications that subscribe to recipes. +// +// For information on the recipe data type, please see the +// ChocolateFactory.idl file. +// +// For information on the quality of service for recipe state data, please +// see the recipe_profiles_multicast.xml or recipe_profiles_no_multicast.xml +// file. +// +// ---------------------------------------------------------------------------- +class RecipePublisherInterface { +public: + // --- Constructor --- + // Initializes the recipe publisher interface, including creating a + // DomainParticipant, creating all publishers and subscribers, topics + // writers and readers. Takes as input a vector of xml QoS files that + // should be loaded to find QoS profiles and libraries. + RecipePublisherInterface(std::vector& xmlFiles); + + // --- Destructor --- + ~RecipePublisherInterface(); + + // --- Sends the recipe --- + // Uses DDS interface to send a recipe efficiently over the network + // or shared memory to interested applications subscribing to recipe + // information. + void Write(ChocolateRecipe data); + + +private: + // --- Private members --- + + // Used to create basic DDS entities that all applications need + DDSCommunicator& _communicator; + + // Topic object used by writer + dds::topic::Topic& _topic; + + // Recipe publisher specific to this application + dds::pub::DataWriter& _writer; +}; + +#endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationController.cxx b/ChocolateFactory/ExampleCode/src/StationController/StationController.cxx index 9e89714f..a77f8681 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationController.cxx +++ b/ChocolateFactory/ExampleCode/src/StationController/StationController.cxx @@ -1,21 +1,22 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ #include #include #include -#include "StationController.h" -#include "../CommonInfrastructure/EnumPrintHelpers.h" +#include "StationController.hpp" +#include "../CommonInfrastructure/EnumPrintHelpers.hpp" - -using namespace DDS; using namespace std; using namespace com::chocolatefactory::generated; @@ -27,20 +28,20 @@ void PrintHelp(); // This application acts as a "station controller" in a chocolate factory. Its // purpose is to process a chocolate lot according to a recipe for the chocolate // either dark chocolate, milk chocolate, or white chocolate. -// +// // To "process" a lot, this application retrieves the recipe that this lot is // using, and based on how much time the step should take, it sleeps. // // This application receives: // 1. Recipe data: it receives recipes so it can get information on how to -// process a particular lot. (Note that this exmaple replaces real +// process a particular lot. (Note that this exmaple replaces real // recipe information with how long to sleep) -// 2. Filtered chocolate lot state updates: this application creates a +// 2. Filtered chocolate lot state updates: this application creates a // content-filtered topic, so it receives only updates about chocolate -// lots that: +// lots that: // a. Are assigned to it, or // b. Are completed (so it can unregister that lot) -// +// // This application sends: // 1. Updates to a chocolate state saying either: // a. It is waiting at this station controller @@ -50,128 +51,107 @@ void PrintHelp(); // // ------------------------------------------------------------------------- // -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - int sec = 0; - - int controllerType = 1; - string setting; - bool multicastAvailable = true; - - for (int i = 0; i < argc; i++) - { - // There are five types of valid controller described in the IDL type - // StationControllerKind: Sugar controller, cocoa butter controller - // cocoa liquor controller, vanilla controller, and milk controller - if (0 == strcmp(argv[i], "--controller-type")) - { - ++i; - if (i == argc) - { - cout << "Bad parameter: Did not pass a station controller type" - << endl; - return -1; - } - controllerType = atoi(argv[i]); - - // Only curently have 5 types of controller - if (controllerType < 1 || controllerType > 5) - { - cout << "Bad parameter: controller types are between 1 and 5" - << endl; - return -1; - } - } else if (0 == strcmp(argv[i], "--no-multicast")) - { - multicastAvailable = false; - } else if (0 == strcmp(argv[i], "--help")) - { - PrintHelp(); - return 0; - } else if (i > 0) - { - // If we have a parameter that is not the first one, and is not - // recognized, return an error. - cout << "Bad parameter: " << argv[i] << endl; - PrintHelp(); - return -1; - } - - } - - // Set up paths for XML files. The profiles are for applications that - // have no multicast available at all, or that have multicast available - // on the network. - vector xmlFiles; - - if (multicastAvailable) - { - // Adding the XML files that contain profiles used by this application - xmlFiles.push_back( - "file://../../../src/Config/base_profile_multicast.xml"); - xmlFiles.push_back( - "file://../../../src/Config/recipe_profiles_multicast.xml"); - } - else - { - // Adding the XML files that contain profiles used by this application - xmlFiles.push_back( - "file://../../../src/Config/base_profile_no_multicast.xml"); - xmlFiles.push_back( - "file://../../../src/Config/recipe_profiles_no_multicast.xml"); - } - - try - { - - // This sets up the data interface for the station controller - what - // data it sends and receives over the network, along with the quality - // of service. From the standpoint of RTI Connext, this is where - // the most interesting code is that sets up all of the objects that - // allow the application to communicate over shared memory or over - // the network - StationControllerInterface *stationControllerInterface - = new StationControllerInterface( - (StationControllerKind)controllerType, - xmlFiles); - - // Create a new Station Controller object. - StationController *controller = new StationController( - (StationControllerKind)controllerType, - stationControllerInterface); - - // Process incoming lots, including sending lot updates over - // RTI Connext - controller->ProcessLots(); - - delete controller; - delete stationControllerInterface; - } - catch (string message) - { - cout << "Application exception " << message << endl; - } - - - return 0; + int sec = 0; + + int controllerType = 1; + string setting; + bool multicastAvailable = true; + + for (int i = 0; i < argc; i++) { + // There are five types of valid controller described in the IDL type + // StationControllerKind: Sugar controller, cocoa butter controller + // cocoa liquor controller, vanilla controller, and milk controller + if (0 == strcmp(argv[i], "--controller-type")) { + ++i; + if (i == argc) { + cout << "Bad parameter: Did not pass a station controller type" + << endl; + return -1; + } + controllerType = atoi(argv[i]); + + // Only curently have 5 types of controller + if (controllerType < 1 || controllerType > 5) { + cout << "Bad parameter: controller types are between 1 and 5" + << endl; + return -1; + } + } else if (0 == strcmp(argv[i], "--no-multicast")) { + multicastAvailable = false; + } else if (0 == strcmp(argv[i], "--help")) { + PrintHelp(); + return 0; + } else if (i > 0) { + // If we have a parameter that is not the first one, and is not + // recognized, return an error. + cout << "Bad parameter: " << argv[i] << endl; + PrintHelp(); + return -1; + } + } + + // Set up paths for XML files. The profiles are for applications that + // have no multicast available at all, or that have multicast available + // on the network. + vector xmlFiles; + + if (multicastAvailable) { + // Adding the XML files that contain profiles used by this application + xmlFiles.push_back("file://../src/Config/base_profile_multicast.xml"); + xmlFiles.push_back( + "file://../src/Config/recipe_profiles_multicast.xml"); + } else { + // Adding the XML files that contain profiles used by this application + xmlFiles.push_back( + "file://../src/Config/base_profile_no_multicast.xml"); + xmlFiles.push_back( + "file://../src/Config/recipe_profiles_no_multicast.xml"); + } + + try { + // This sets up the data interface for the station controller - what + // data it sends and receives over the network, along with the quality + // of service. From the standpoint of RTI Connext, this is where + // the most interesting code is that sets up all of the objects that + // allow the application to communicate over shared memory or over + // the network + StationControllerInterface stationControllerInterface( + (StationControllerKind) controllerType, + xmlFiles, QOS_PROFILE_STATE_DATA, QOS_PROFILE_STATE_DATA); + + // Create a new Station Controller object. + StationController controller((StationControllerKind) controllerType, + stationControllerInterface); + + // Process incoming lots, including sending lot updates over + // RTI Connext + controller.ProcessLots(); + + } catch (string message) { + cout << "Application exception " << message << endl; + } + + + return 0; } // ---------------------------------------------------------------------------- -// Station controller constructor. +// Station controller constructor. StationController::StationController( - StationControllerKind kind, - StationControllerInterface *scInterface) + StationControllerKind kind, + StationControllerInterface& scInterface) : + _networkInterface(scInterface) { - _stationControllerKind = kind; - _networkInterface = scInterface; - _shuttingDown = false; + _stationControllerKind = kind; } // ---------------------------------------------------------------------------- // ProcessLots: // This method executes the main logic for the StationController: -// 1. Wait for lot status (filtered so it will only receive lots that are +// 1. Wait for lot status (filtered so it will only receive lots that are // assigned to this station controller, or that have been completed) // 2. Update lots to say they are being processed // 2. Process lots @@ -179,254 +159,199 @@ StationController::StationController( // void StationController::ProcessLots() { - while (!_shuttingDown) - { - - // --- Wait for lots to process --- - - string controllerKindString; - StationControllerType::GetControllerPrettyName( - _stationControllerKind, controllerKindString); - cout << "Station controller " - << controllerKindString.c_str() - << " waiting for data" << endl; - - vector< DdsAutoType > lotsToProcess; - - // This network interface receives lot state updates that are filtered - // for just this station controller. This method will block this - // thread until there are lots that should be processed (or a timeout - // occurs). - _networkInterface-> - GetChocolateLotStateReader()->WaitForChocolateLotUpdates( - &lotsToProcess); - - // --- Update lots to WAITING, or unregister completed lots --- - - // Announce that all lots I have received requests for are waiting at - // this StationController to be processed. - for (int i = 0; i < lotsToProcess.size(); i++) - { - UpdateState(&lotsToProcess[i]); - } - - // --- Process lots --- - // Process the lots that we know about. "Processing" a lot involves - // just sleeping in place of real functionality - for (int i = 0; i < lotsToProcess.size(); i++) - { - ProcessLot(&lotsToProcess[i]); - } - - } + dds::sub::DataReader reader = + _networkInterface.ReaderChocolateLotState(); + dds::sub::cond::ReadCondition readCondition(reader, + dds::sub::status::DataState::new_data(), [&reader, this]() { + auto samples = reader.take(); + vector lotStates; + // Copy the data so that it can be freely modified + for (auto sample : samples) { + lotStates.push_back(sample.data()); + } + // --- Update lots to WAITING, or unregister completed lots --- + + // Announce that all lots I have received requests for are waiting at + // this StationController to be processed. + for (auto& state : lotStates) { + UpdateState(state); + } + // --- Process lots --- + // Process the lots that we know about. "Processing" a lot involves + // just sleeping in place of real functionality + for (auto& state : lotStates) { + ProcessLot(state); + } + }); + + // Create a Waitset for processing of read condition(s) + dds::core::cond::WaitSet waitSet; + auto wait_period = dds::core::Duration::from_millisecs(100); + + // Add the read condition to the WaitSet + waitSet += readCondition; + + while (true) { + // --- Wait for lots to process --- + + cout << "Station controller " + << StationControllerType::ControllerPrettyName(_stationControllerKind) + << " waiting for data" << endl; + + waitSet.dispatch(wait_period); + } } // ---------------------------------------------------------------------------- // UpdateState: -void StationController::UpdateState(DdsAutoType *lotState) +void StationController::UpdateState(ChocolateLotState& lotState) { - - // Copy the lot state that was received into a new object we can modify - DdsAutoType updatedState = *lotState; - - // Controller updating/unregistering this lot is me - updatedState.controller = _stationControllerKind; - - // --- Unregister completed lots --- - // If this lot is entirely completed being created, I can - // unregister it - removing any information that I was storing - // about its state. This means that late-joining applications will - // not receive updates about this lot from me. If we fail to - // unregister, the state of this lot will be available until this - // application shuts down. - if (updatedState.lotStatus == LOT_COMPLETED) - { - // Call to unregister lot - _networkInterface->GetChocolateLotStateWriter()-> - UnregisterChocolateLotState(updatedState); - return; - } - - // --- Update lots assigned to me to waiting state --- - // If this lot is being assigned to me, update its status to say - // it is waiting at my station - - // Next station is invalid until I am complete - updatedState.nextController = INVALID_CONTROLLER; - - // State is waiting at the controller - updatedState.lotStatus = WAITING_AT_SC; - - // Write this update to the network - _networkInterface->GetChocolateLotStateWriter()-> - PublishChocolateLotState(updatedState); + // Controller updating/unregistering this lot is me + lotState.controller(_stationControllerKind); + + // --- Unregister completed lots --- + // If this lot is entirely completed being created, I can + // unregister it - removing any information that I was storing + // about its state. This means that late-joining applications will + // not receive updates about this lot from me. If we fail to + // unregister, the state of this lot will be available until this + // application shuts down. + if (lotState.lotStatus() == LotStatusKind::LOT_COMPLETED) { + // Call to unregister lot + _networkInterface.WriterChocolateLotState().unregister_instance( + _networkInterface.WriterChocolateLotState().lookup_instance(lotState) + ); + return; + } + + // --- Update lots assigned to me to waiting state --- + // If this lot is being assigned to me, update its status to say + // it is waiting at my station + + // Next station is invalid until I am complete + lotState.nextController(StationControllerKind::INVALID_CONTROLLER); + + // State is waiting at the controller + lotState.lotStatus(LotStatusKind::WAITING_AT_SC); + + // Write this update to the network + _networkInterface.WriterChocolateLotState().write(lotState); } // ---------------------------------------------------------------------------- // ProcessLot: -void StationController::ProcessLot(DdsAutoType *lotState) +void StationController::ProcessLot(ChocolateLotState& lotState) { - // If this lot is completed, don't process it. - if (lotState->lotStatus == LOT_COMPLETED) - { - return; - } - - // Copy the lot state that was received into a new object we can modify - DdsAutoType updatedState = *lotState; - - // I am the current controller, and the current state is I am processing it - updatedState.controller = _stationControllerKind; - updatedState.lotStatus = PROCESSING_AT_SC; - - // No next controller assigned until I am done - updatedState.nextController = INVALID_CONTROLLER; - - // Write the chocolate lot state over the network - _networkInterface->GetChocolateLotStateWriter()-> - PublishChocolateLotState(updatedState); - - // --- Query recipe for this lot --- - - // The GetRecipe() call queries recipes that are stored in the - // middleware's queue. - DdsAutoType recipe; - bool haveRecipe = false; - while (!haveRecipe) - { - haveRecipe = - _networkInterface->GetRecipeReader()->GetRecipe( - lotState->recipeName, &recipe); - if (!haveRecipe) - { - DDS_Duration_t recipeWait; - // 10 ms - recipeWait.sec = 10; - recipeWait.nanosec = 0; - - cout << "Have not received the required recipe. Waiting for " << - recipeWait.sec << " seconds for recipe." << - endl; - NDDSUtility::sleep(recipeWait); - } - } - - // Get the current recipe step information to know how to - // process the lot - RecipeStep currentStep; - - // Start to fill in the next state of the chocolate lot based - // on the next recipe step. - DdsAutoType nextState - = *lotState; - - // Iterate over the recipe steps - for (int j = 0; j < recipe.steps.length(); j++) - { - // Iterate over the recipe until reaching the current step - // in the process. - if (recipe.steps[j].stationController == _stationControllerKind) - { - // Set currentStep to the current recipe step - currentStep = recipe.steps[j]; - - // If this is the last step in the recipe, we can mark - // this lot as completed. - if (j == recipe.steps.length() - 1) - { - nextState.nextController = INVALID_CONTROLLER; - nextState.lotStatus = LOT_COMPLETED; - } else - { - nextState.nextController = - recipe.steps[j + 1].stationController; - nextState.lotStatus = ASSIGNED_TO_SC; - } - - break; - } - } - - // --- "Process" lot (really just sleep) --- - DDS_Duration_t busySleep; - busySleep.sec = currentStep.seconds; - busySleep.nanosec = 0; - - // --- Print an update --- - string controllerKindString; - StationControllerType::GetControllerPrettyName( - _stationControllerKind, controllerKindString); - cout << "Station controller " - << controllerKindString.c_str() - << " processing lot #" - << updatedState.lotID - << " for " - << currentStep.seconds - << " seconds" << endl; - NDDSUtility::sleep(busySleep); - - // --- Prepare the next state to publish --- - - // Add the ingredients from this station controller to the - // ingredient list in this lot. - - // Increase the length of the ingredients list by 1 - nextState.ingredients.ensure_length( - nextState.ingredients.length() + 1, - nextState.ingredients.length() + 1); - string ingredientName; - - // Add the ingredient to the list in the chocolate lot state - StationControllerType::GetControllerIngredientName( - _stationControllerKind, ingredientName); - nextState.ingredients[nextState.ingredients.length() - 1] = - new char [ingredientName.size() + 1]; - strcpy(nextState.ingredients[nextState.ingredients.length() - 1], - const_cast(ingredientName.c_str())); - - // Fill in the next controller based on the recipe we queried - // earlier - string nextControllerKindString; - StationControllerType::GetControllerPrettyName( - nextState.nextController, nextControllerKindString); - cout << "Station controller " - << controllerKindString.c_str() - << " sending lot #" - << nextState.lotID - << " to " - << nextControllerKindString.c_str() << endl; - - // --- Publish updated state --- - // Update to say we are done with lot, and it is time for - // the next station controller to process it, or that it is - // completed. - _networkInterface->GetChocolateLotStateWriter()-> - PublishChocolateLotState(nextState); - + // If this lot is completed, don't process it. + if (LotStatusKind::LOT_COMPLETED == lotState.lotStatus()) { + return; + } + + // I am the current controller, and the current state is I am processing it + lotState.controller(_stationControllerKind); + lotState.lotStatus(LotStatusKind::PROCESSING_AT_SC); + + // No next controller assigned until I am done + lotState.nextController(StationControllerKind::INVALID_CONTROLLER); + + // Write the chocolate lot state over the network + _networkInterface.WriterChocolateLotState().write(lotState); + + // --- Query recipe for this lot --- + + // The GetRecipe() call queries recipes that are stored in the + // middleware's queue. + ChocolateRecipe recipe; + bool haveRecipe = false; + while (recipe.recipeName().empty()) { + recipe = _networkInterface.GetRecipe(lotState.recipeName()); + if (recipe.recipeName() != lotState.recipeName()) { + dds::core::Duration recipeWait(10, 0); // 10 s + + cout << "Have not received the required recipe. Waiting for " + << recipeWait.sec() << " seconds for recipe." << endl; + + rti::util::sleep(recipeWait); + } + } + + // Get the current recipe step information to know how to + // process the lot + RecipeStep currentStep; + + // Start to fill in the next state of the chocolate lot based + // on the next recipe step. + ChocolateLotState nextState(lotState); + + // Iterate over the recipe steps + for (auto step = begin(recipe.steps()); step != end(recipe.steps()); ++step) { + // Iterate over the recipe until reaching the current step + // in the process. + if (step->stationController() == _stationControllerKind) { + // Set currentStep to the current recipe step + currentStep = *step; + + // If this is the last step in the recipe, we can mark + // this lot as completed. + if (step == end(recipe.steps())) { + nextState.nextController(StationControllerKind::INVALID_CONTROLLER); + nextState.lotStatus(LotStatusKind::LOT_COMPLETED); + } else { + nextState.nextController((++step)->stationController()); + step--; + nextState.lotStatus(LotStatusKind::ASSIGNED_TO_SC); + } + break; + } + } + + // --- "Process" lot (really just sleep) --- + dds::core::Duration busySleep(currentStep.seconds(), 0); + + // --- Print an update --- + cout << "Station controller " + << StationControllerType::ControllerPrettyName(_stationControllerKind) + << " processing lot #" << lotState.lotID() << " for " + << currentStep.seconds() << " seconds" << endl; + rti::util::sleep(busySleep); + + // --- Prepare the next state to publish --- + + // Add the ingredients from this station controller to the + // ingredient list in this lot. + + // Add the ingredient to the list in the chocolate lot state + nextState.ingredients().push_back(StationControllerType::ControllerIngredientName(_stationControllerKind)); + + // Fill in the next controller based on the recipe we queried + // earlier + cout << "Station controller " << StationControllerType::ControllerIngredientName(_stationControllerKind) + << " sending lot #" << nextState.lotID() << " to " + << StationControllerType::ControllerPrettyName(nextState.nextController()) << endl; + + // --- Publish updated state --- + // Update to say we are done with lot, and it is time for + // the next station controller to process it, or that it is + // completed. + _networkInterface.WriterChocolateLotState().write(nextState); } // ---------------------------------------------------------------------------- // PrintHelp: -// Function that prints out the help if somebody runs the application with +// Function that prints out the help if somebody runs the application with // --help // void PrintHelp() { - cout << "Valid options are: " << endl; - cout << - " --controller-type [number]" << - " Valid values 1-5. Type of controller this app " - << endl - << " " - << "represents" - << endl; - cout << - " --no-multicast" << - " Do not use multicast " << - "(note you must edit XML" << endl << - " " << - "config to include IP addresses)" - << endl; - + cout << "Valid options are: " << endl; + cout << " --controller-type [number]" + << " Valid values 1-5. Type of controller this app " << endl + << " " + << "represents" << endl; + cout << " --no-multicast" + << " Do not use multicast " + << "(note you must edit XML" << endl + << " " + << "configuration to include IP addresses)" << endl; } diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationController.h b/ChocolateFactory/ExampleCode/src/StationController/StationController.h deleted file mode 100644 index 645467d3..00000000 --- a/ChocolateFactory/ExampleCode/src/StationController/StationController.h +++ /dev/null @@ -1,48 +0,0 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ - -#ifndef STATION_CONTROLLER_H -#define STATION_CONTROLLER_H - -#include "StationControllerInterface.h" -#include "../Generated/ChocolateFactory.h" - -class StationController -{ - -public: - // --- Constructor --- - StationController( - com::chocolatefactory::generated::StationControllerKind kind, - StationControllerInterface *scInterface); - - // --- Process lots --- - void ProcessLots(); - - // --- Update lot state --- - void UpdateState( - DdsAutoType - *updatedState); - - // --- Process lot --- - void ProcessLot( - DdsAutoType - *lotState); - -private: - - // --- Private members --- - StationControllerInterface *_networkInterface; - bool _shuttingDown; - com::chocolatefactory::generated::StationControllerKind - _stationControllerKind; -}; - -#endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationController.hpp b/ChocolateFactory/ExampleCode/src/StationController/StationController.hpp new file mode 100644 index 00000000..c0b8a657 --- /dev/null +++ b/ChocolateFactory/ExampleCode/src/StationController/StationController.hpp @@ -0,0 +1,40 @@ +/********************************************************************************************* +(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. +RTI grants Licensee a license to use, modify, compile, and create derivative +works of the Software. Licensee has the right to distribute object form only +for use with RTI products. The Software is provided as is, with no warranty +of any type, including any warranty for fitness for any purpose. RTI is under no +obligation to maintain or support the Software. RTI shall not be liable for any +incidental or consequential damages arising out of the use or inability to use +the software. +**********************************************************************************************/ + +#ifndef STATION_CONTROLLER_H +#define STATION_CONTROLLER_H + +#include "StationControllerInterface.hpp" +#include "../Generated/ChocolateFactory.hpp" + +using namespace com::chocolatefactory::generated; + +class StationController { +public: + // --- Constructor --- + StationController(StationControllerKind kind, StationControllerInterface& scInterface); + + // --- Process lots --- + void ProcessLots(); + + // --- Update lot state --- + void UpdateState(ChocolateLotState& updatedState); + + // --- Process lot --- + void ProcessLot(ChocolateLotState& lotState); + +private: + // --- Private members --- + StationControllerInterface& _networkInterface; + StationControllerKind _stationControllerKind; +}; + +#endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx index 3e386881..03f49c9b 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx @@ -1,46 +1,51 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ #include #include #include -#include "../Generated/ChocolateFactory.h" -#include "../Generated/ChocolateFactorySupport.h" -#include "StationControllerInterface.h" +#include "../Generated/ChocolateFactory.hpp" +#include "../CommonInfrastructure/EnumPrintHelpers.hpp" +#include "StationControllerInterface.hpp" -using namespace DDS; +using namespace std; using namespace com::chocolatefactory::generated; - +using namespace dds::topic; +using namespace dds::pub; +using namespace dds::sub; // ------------------------------------------------------------------------- // -// The StationControllerInterface is the network interface to the whole +// The StationControllerInterface is the network interface to the whole // Station Controller application. This creates DataReaders and DataWriters -// in order to receive and send data. +// in order to receive and send data. // // This interface is built from: // 1. Network data types and topic names defined in the IDL file -// 2. XML configuration files that describe the QoS profiles that should be -// used by individual DataWriters and DataReaders. These describe the +// 2. XML configuration files that describe the QoS profiles that should be +// used by individual DataWriters and DataReaders. These describe the // movement and persistence characteristics of the data (how reliable should // this be?), as well as other QoS such as resource limits. -// 3. The code itself creates DataReaders and DataWriters, and selects which +// 3. The code itself creates DataReaders and DataWriters, and selects which // profile to use when creating the DataReaders and DataWriters. // // Reading ChocolateLotState data: // ------------------------------ -// The station controller listens to chocolate lot state data that indicates that -// a chocolate lot is on the way to this station controller. +// The station controller listens to chocolate lot state data that indicates +// that a chocolate lot is on the way to this station controller. // // It uses a DDS DataReader, with a content filter to receive only updates // that indicate that it is the next station controller to process the lot. -// +// // Writing ChocolateLotState data: // ---------------------------- // This application sends chocolate lot state data, announcing that the current @@ -49,9 +54,9 @@ using namespace com::chocolatefactory::generated; // 2. Being processed by this station controller // 3. Done being processed by this station controller/ready to be processed // by the next station controller. -// -// For information on the ChocolateRecipe or ChocolateLotState types, please see the -// ChocolateFactory.idl file. +// +// For information on the ChocolateRecipe or ChocolateLotState types, please see +// the ChocolateFactory.idl file. // // For information on the quality of service for state data, please see the // recipe_profiles_multicast.xml file. @@ -67,7 +72,7 @@ using namespace com::chocolatefactory::generated; // 1. It is sent reliably (RELIABLE_RELIABILITY_QOS) // 2. It is made available to late-joining applications as soon as they start // (TRANSIENT_LOCAL_DURABILITY_QOS) -// 3. A predetermined amount of state is sent to any late-joiners. In this +// 3. A predetermined amount of state is sent to any late-joiners. In this // case, applications are only interested in the current state of each // chocolate lot (or the current chocolate recipe), which translates to a // history with depth = 1, kind = KEEP_LAST_HISTORY_QOS @@ -75,268 +80,54 @@ using namespace com::chocolatefactory::generated; // ------------------------------------------------------------------------- // +StationControllerInterface::StationControllerInterface(StationControllerKind id, + vector qosFileNames, string lotStateQosProfile, + string recipeQosProfile) : + _comm(DDSCommunicator(qosFileNames, (QOS_LIBRARY + "::" + + QOS_PROFILE_STATE_DATA))), + _topicChocolateLotState(Topic(_comm.Participant(), + CHOCOLATE_LOT_TOPIC, _comm.Qos().topic_qos(lotStateQosProfile))), + _cftChocolateLotState(ContentFilteredTopic( + _topicChocolateLotState, "ContentFilter", Filter( + "lotStatus = 'LOT_COMPLETED' OR nextController = %0", { + StationControllerType::ControllerEnumName(id) + }) + )), + _topicChocolateRecipe(Topic(_comm.Participant(), + RECIPE_TOPIC, _comm.Qos().topic_qos(recipeQosProfile))), + _writerChocolateLotState(DataWriter(_comm.Publisher(), + _topicChocolateLotState, _comm.Qos().datawriter_qos(lotStateQosProfile))), + _readerChocolateLotState(DataReader(_comm.Subscriber(), + _cftChocolateLotState, _comm.Qos().datareader_qos(lotStateQosProfile))), + _readerRecipe(DataReader(_comm.Subscriber(), + _topicChocolateRecipe, _comm.Qos().datareader_qos(recipeQosProfile))) +{ + _stationControllerID = id; -StationControllerInterface::StationControllerInterface( - StationControllerKind stationControllerID, - std::vectorqosFileNames) -{ - - _stationControllerID = stationControllerID; - - // Creating the communicator object - _communicator = new DDSCommunicator(); - - // All data in this example is "state data." The string constants with the - // QoS library name and the QoS profile name are configured as constants in - // the .idl file. The profiles themselves are configured in the .xml file. - // Look in the XML for more details on the definition of state data. - - - // Calling the DDSCommunicator class's CreateParticipant method. - // This creates the DomainParticpant, the first step in creating a DDS - // application. This starts the discovery process. For more information - // on what the DomainParticipant is responsible for, and how to configure - // it, see DDSCommunicator class - if (NULL == GetCommunicator()->CreateParticipant( - 0, - qosFileNames, - QOS_LIBRARY, - QOS_PROFILE_STATE_DATA)) - { - std::stringstream errss; - errss << "Failed to create DomainParticipant object"; - throw errss.str(); - } - - - // Calling the DDSCommunicator class's CreatePublisher method. - // You do _not_ need to create one publisher per DataWriter. - Publisher *publisher = GetCommunicator()->CreatePublisher(); - - if (publisher == NULL) - { - std::stringstream errss; - errss << "Failed to create Publisher object"; - throw errss.str(); - } - - // Creating the application's ChocolateLotStateWriter object. - // This could use the RTI Connext DDS writer directly as a way to write. - // This DataWriter is configured with QoS for state data. - _chocolateLotStateWriter = new ChocolateLotStateWriter( - GetCommunicator(), - publisher, - QOS_LIBRARY, QOS_PROFILE_STATE_DATA); - if (_chocolateLotStateWriter == NULL) - { - std::stringstream errss; - errss << "Failed to create ChocolateLotState DataWriter object"; - throw errss.str(); - } - - - // Creating a DDS subscriber. - // You do _not_ need to create one subscriber per DataReader. - Subscriber *subscriber = GetCommunicator()->CreateSubscriber(); - if (subscriber == NULL) - { - std::stringstream errss; - errss << "Failed to create Subscriber object"; - throw errss.str(); - } - - // Creating the application's ChocolateLotStateReader object. - // We could give the application access to the DataReader directly, but - // this simplifies the application's access - this creates the objects that - // allow the application to block a thread until a ChocolateLotState update - // is received that notifies this Station Controller that it needs to - // process a chocolate lot. - // This DataReader is configured with QoS for state data. - _chocolateLotStateReader = new ChocolateLotStateReader( - GetCommunicator(), - subscriber, - "RTIExampleQosLibrary", - "FactoryStateData", - _stationControllerID); - - if (_chocolateLotStateReader == NULL) - { - std::stringstream errss; - errss << "Failed to create ChocolateLotState DataReader object"; - throw errss.str(); - } - - // Creating the application's ChocolateRecipe DataReader object. - // We could give the application access to the DataReader directly, but - // this simplifies the application's access - this receives and stores - // all recipes in the middleware's queue, and contains the logic to look up - // a single recipe by name. This DataReader is configured with QoS for - // state data - _recipeReader = new ChocolateRecipeReader(this, subscriber, - "RTIExampleQosLibrary", - "FactoryStateData"); - - if (_recipeReader == NULL) - { - std::stringstream errss; - errss << "Failed to create Recipe DataReader object"; - throw errss.str(); - } + // All data in this example is "state data." The string constants with the + // QoS library name and the QoS profile name are configured as constants in + // the .idl file. The profiles themselves are configured in the .xml file. + // Look in the XML for more details on the definition of state data. + // Creating the application's ChocolateLotStateWriter object. + // This could use the RTI Connext DDS writer directly as a way to write. + // This DataWriter is configured with QoS for state data. + } // ------------------------------------------------------------------------- // -// Deleting the ChocolateLotState DataWriter, the ChocolateLotState DataReader, the -// ChocolateRecipeDataReader, and the communicator infrastructure. See the +// Deleting the ChocolateLotState DataWriter, the ChocolateLotState DataReader, +// the ChocolateRecipeDataReader, and the communicator infrastructure. See the // individual destructors to see how these are deleted. StationControllerInterface::~StationControllerInterface() -{ - - delete _chocolateLotStateWriter; - delete _chocolateLotStateReader; - delete _recipeReader; -} - - - - - - -// ------------------------------------------------------------------------- // -// This creates the DDS DataReader that receives updates about recipes. -ChocolateRecipeReader::ChocolateRecipeReader( - StationControllerInterface *comm, - Subscriber *sub, - const std::string &qosLibrary, - const std::string &qosProfile) -{ - - if (comm == NULL) - { - std::stringstream errss; - errss << "ChocolateRecipeReader(): bad parameter \"comm\""; - throw errss.str(); - } - - _communicator = comm; - - // Creating a Topic - // The topic object is the description of the data that you will be - // sending. It associates a particular data type with a name that - // describes the meaning of the data. Along with the data types, and - // whether your application is reading or writing particular data, this - // is the data interface of your application. - - // This topic has the name RECIPE_TOPIC - a constant string - // that is defined in the .idl file. (It is not required that you define - // your topic name in IDL, but it is a best practice for ensuring the data - // interface of an application is all defined in one place. - // Generally you can register all topics and types up-front if - // necessary. - Topic *topic = (DDS::Topic *) - _communicator->GetCommunicator()-> - GetParticipant()->lookup_topicdescription(RECIPE_TOPIC); - - if (topic == NULL) - { - - topic = _communicator->GetCommunicator()->CreateTopic( - RECIPE_TOPIC); - } - - // Creating a DataReader - // This DataReader will receive the recipe, and will store it in the - // middleware's queue to be queried by the application - DataReader *reader = sub->create_datareader_with_profile(topic, - qosLibrary.c_str(), - qosProfile.c_str(), - NULL, - DDS_STATUS_MASK_NONE); +{ } - // Down casting to the type-specific reader - _reader = ChocolateRecipeDataReader::narrow(reader); - - -} - -// ------------------------------------------------------------------------- // -// Destory the chocolate recipe DataReader. Note that this uses -// the DDS factories that created various objects to later delete them. -ChocolateRecipeReader::~ChocolateRecipeReader() +ChocolateRecipe StationControllerInterface::GetRecipe(const string recipeName) { - _reader->delete_contained_entities(); - Subscriber *sub = _reader->get_subscriber(); - sub->delete_datareader(_reader); - + // Create a placeholder with only the key field filled in. This will be + // used to retrieve the recipe instance (if it exists). + for (auto sample : _readerRecipe.read()) { + if (recipeName == sample.data().recipeName()) + return sample.data(); + } } - -// This example uses instance information to query the middleware's queue for -// recipes that have previously been sent to this application. This uses -// option #3 of the three options for getting data from RTI Connext DDS. -// -// There are three options for getting data from RTI Connext DDS: -// 1. Being notified in the application's thread of data arriving. -// This mechanism has slightly higher latency than option #2, but low -// latency is not important for this use case. In addition, this is safer -// than using option #2, because you do not have to worry about the effect -// on the middleware's thread. -// This uses WaitSet objects to be notified of data arriving. -// A simple of example of this can be found at: -// http://community.rti.com/examples/waitset-status-condition -// 2. Being notified in a listener callback of data arriving. -// This has lower latency than using a WaitSet, but is more dangerous -// because you have to worry about not blocking the middleware's thread. -// 3. Polling for data. (Used here) -// You can call read() or take() at any time to view or remove the data that -// is currently in the queue. -// A simple example of this can be found at: -// http://community.rti.com/examples/polling-read - -bool ChocolateRecipeReader::GetRecipe( - std::string recipeName, - DdsAutoType *recipe) -{ - - // Create a placeholder with only the key field filled in. This will be - // used to retrieve the recipe instance (if it exists). - DdsAutoType recipeHolder; - strcpy(recipeHolder.recipeName, recipeName.c_str()); - - // Look up the particular instance - const DDS_InstanceHandle_t handle = - _reader->lookup_instance(recipeHolder); - - // If we have received a lot that uses a recipe we do not have, this is an - // error! - if (DDS_InstanceHandle_is_nil(&handle)) - { - std::cout << "GetRecipe(): warning - " << - "Do not have the recipe needed to process this lot." << std::endl; - return false; - - } - - ChocolateRecipeSeq recipeSeq; - SampleInfoSeq infoSeq; - - // Reading just the data for the recipe we are interested in - _reader->read_instance(recipeSeq, infoSeq, - DDS_LENGTH_UNLIMITED, - handle); - - - if (recipeSeq.length() > 0) - { - - if (infoSeq[0].valid_data) - { - // DdsAutoType has a copy constructor that calls - // the appropriate TypeSupport::copy_data method - *recipe = recipeSeq[0]; - } - } - _reader->return_loan(recipeSeq, infoSeq); - - return true; -} - diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.h b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.h deleted file mode 100644 index c5181a6a..00000000 --- a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.h +++ /dev/null @@ -1,248 +0,0 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative works -of the Software. Licensee has the right to distribute object form only for use with RTI -products. The Software is provided as is, with no warranty of any type, including -any warranty for fitness for any purpose. RTI is under no obligation to maintain or -support the Software. RTI shall not be liable for any incidental or consequential -damages arising out of the use or inability to use the software. -**********************************************************************************************/ -#ifndef STATION_CONTROLLER_INTERFACE_H -#define STATION_CONTROLLER_INTERFACE_H - - -#include "ndds/ndds_cpp.h" -#include "ndds/ndds_namespace_cpp.h" -#include "../CommonInfrastructure/DDSCommunicator.h" -#include "../CommonInfrastructure/DDSTypeWrapper.h" -#include "../CommonInfrastructure/ChocolateLotStateEntities.h" -#include "../Generated/ChocolateFactory.h" -#include "../Generated/ChocolateFactorySupport.h" - -#include - - -// ---------------------------------------------------------------------------- -// A station controller is responsible for: -// 1. Listing for chocolate lot state data that indicates it should be -// responsible for the next step in a chocolate recipe for a given lot. -// 2. Updating the chocolate lot state to indicate that it is processing a -// lot, or to send the chocolate lot to the next station controller. -// -// The station controller interface is composed of two parts: -// -// Reading ChocolateLotState data: -// ------------------------------ -// The station controller listens to chocolate lot state data that indicates -// that a chocolate lot is on the way to this station controller. -// -// It uses a DDS DataReader, with a content filter to receive only updates -// that indicate that it is the next station controller to process the lot. -// -// Writing ChocolateLotState data: -// ---------------------------- -// This application sends chocolate lot state data, announcing that the current -// lot of chocolates is either: -// 1. Waiting to be processed by this station controller -// 2. Being processed by this station controller -// 3. Done being processed by this station controller/ready to be processed -// by the next station controller. -// -// For information on the ChocolateRecipe or ChocolateLotState types, please see -// the ChocolateFactory.idl file. -// -// For information on the quality of service for state data, please see the -// recipe_profiles_multicast.xml file. -// -// Reading Recipe data: -// -------------------- -// This application reads recipe data to know which state controller to send -// the chocolate lot to when it is done. -// -// Quality of Service: -// ------------------- -// All of the data in this example is modeled as "state data," which means that: -// 1. It is sent reliably (RELIABLE_RELIABILITY_QOS) -// 2. It is made available to late-joining applications as soon as they start -// (TRANSIENT_LOCAL_DURABILITY_QOS) -// 3. A predetermined amount of state is sent to any late-joiners. In this -// case, applications are only interested in the current state of each -// chocolate lot (or the current chocolate recipe), which translates to a -// history with depth = 1, kind = KEEP_LAST_HISTORY_QOS -// - -class ChocolateLotStateWriter; -class ChocolateLotStateReader; -class ChocolateRecipeReader; - - -// ------------------------------------------------------------------------- // -// -// StationControllerInterface: -// A class that sets up the DDS interface (the network interface) of this -// chocolate factory's station controller applications. -// -// This includes creating appropriate DDS DataWriters, DDS DataReaders, and -// all other DDS objects. -// -// ------------------------------------------------------------------------- // -class StationControllerInterface -{ - -public: - - // This takes in the ID of the station controller, - - // The station controller ID is used both when updating the chocolate lot - // state, and when listening for a chocolate lot state. - - // When listening for the chocolate lot state, this either: - // 1. Installs a content filtered topic to listen only for lots that - // are assigned to it, or - // 2. Installs a normal topic and monitors all updates to the chocolate - // lot state. - - - // --- Constructor --- - StationControllerInterface( - com::chocolatefactory::generated::StationControllerKind - stationControllerID, - std::vectorqosFileNames); - - // --- Destructor --- - virtual ~StationControllerInterface(); - - // --- Getter for the ChocolateLotStateWriter --- - // This returns a ChocolateLotStateWriter object, which is the part of the - // network interface that sends the chocolate lot's current state data over - // the network. Look at the ChocolateLotStateWriter class to see how to write - // data in RTI Connext DDS. - ChocolateLotStateWriter *GetChocolateLotStateWriter() - { - return _chocolateLotStateWriter; - } - - // --- Getter for the ChocolateLotStateReader --- - // This returns the ChocolateLotState reader - a small wrapper around the - // ChocolateLotStateReader that initializes the reader, the content filtered - // topic, and uses the DDS "WaitSet" object to wait for the chocolate lot - // state updates - ChocolateLotStateReader *GetChocolateLotStateReader() - { - return _chocolateLotStateReader; - } - - // --- Getter for the RecipeReader --- - // This returns the Chocolate recipe reader - a small wrapper around the - // ChocolateRecipeDataReader that initializes the reader and uses the - // DDS "WaitSet" object to wait for recipes - ChocolateRecipeReader *GetRecipeReader() - { - return _recipeReader; - } - - - // --- Getter for Communicator --- - // Accessor for the communicator (the class that sets up the basic - // DDS infrastructure like the DomainParticipant). - // This allows access to the DDS DomainParticipant/Publisher/Subscriber - // classes - DDSCommunicator *GetCommunicator() - { - return _communicator; - } - - // --- Getter for Controller ID --- - // Accessor for the controller ID - const com::chocolatefactory::generated::StationControllerKind - GetStationControllerID() - { - return _stationControllerID; - } - -private: - // --- Private members --- - - // This contains the calls that allow the interface to create a - // "DomainParticipant", the first object that must be created to - // communicate over a DDS middleware. - DDSCommunicator *_communicator; - - // If this is a controller, this filed is used to identify which station - // controller this is, and what part of the recipe it is responsible for. - // If this is not a station controller, this is set to invalid - com::chocolatefactory::generated::StationControllerKind - _stationControllerID; - - // Wrapper class around RTI Connext DDS for writing chocolate lot state - ChocolateLotStateWriter *_chocolateLotStateWriter; - - // Used for receiving chocolate lot state data, and being notified about - // the arrival of chocolate lot updates that are specific to this control - // station. - ChocolateLotStateReader *_chocolateLotStateReader; - - // Used for receiving recipe data, and for looking up received recipes. - ChocolateRecipeReader *_recipeReader; - -}; - - - -// ------------------------------------------------------------------------- // -// -// ChocolateRecipeReader: -// Used for receiving the chocolate recipes. This encapsulates the concepts of -// a DDS type-specific DataReader (for type ChocolateRecipe), along with the -// mechanisms for accessing data - in this case, this allows the application -// to block one of its threads to wait for data from the ChocolateRecipeReader. -// -// ------------------------------------------------------------------------- // -class ChocolateRecipeReader -{ - -public: - - // --- Constructor --- - // This creates a DDS DataReader that subscribes to recipe information. - // This uses the _communicator object to access the DomainParticipant, and - // it uses the QoS profiles specified when creating the DataReader. The - // XML QoS fileswere previously configured when the - // StationControllerInterface's DDSCommunicator was created. - ChocolateRecipeReader(StationControllerInterface *comm, - DDS::Subscriber *sub, - const std::string &qosLibrary, - const std::string &qosProfile); - - - // --- Destructor --- - ~ChocolateRecipeReader(); - - // --- Retrieve recipes --- - // This example receives all recipes, and leaves them in the middleware's - // queue. It queries for a particular recipe when it receives an update - // about a lot and it needs to check the recipe for that lot. - bool GetRecipe( - std::string recipeName, - DdsAutoType - *recipe); - - -private: - // --- Private methods --- - - - // --- Private members --- - - // Contains all the components needed to create the DataReader - StationControllerInterface *_communicator; - - // Application-specific DDS DataReader for receiving recipe data - com::chocolatefactory::generated::ChocolateRecipeDataReader *_reader; - -}; - - - - -#endif diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp new file mode 100644 index 00000000..c2e95043 --- /dev/null +++ b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp @@ -0,0 +1,179 @@ +/* + * (c) 2021 Copyright, Real-Time Innovations, Inc. (RTI) All rights reserved. + * + * RTI grants Licensee a license to use, modify, compile, and create derivative + * works of the software solely for use with RTI Connext DDS. Licensee may + * redistribute copies of the software provided that all such copies are + * subject to this license. The software is provided "as is", with no warranty + * of any type, including any warranty for fitness for any purpose. RTI is + * under no obligation to maintain or support the software. RTI shall not be + * liable for any incidental or consequential damages arising out of the use or + * inability to use the software. + */ +#ifndef STATION_CONTROLLER_INTERFACE_H +#define STATION_CONTROLLER_INTERFACE_H + +#include +#include "dds/dds.hpp" +#include "../CommonInfrastructure/DDSCommunicator.hpp" +#include "../Generated/ChocolateFactory.hpp" + +using namespace std; +using namespace com::chocolatefactory::generated; + +// ---------------------------------------------------------------------------- +// A station controller is responsible for: +// 1. Listing for chocolate lot state data that indicates it should be +// responsible for the next step in a chocolate recipe for a given lot. +// 2. Updating the chocolate lot state to indicate that it is processing a +// lot, or to send the chocolate lot to the next station controller. +// +// The station controller interface is composed of two parts: +// +// Reading ChocolateLotState data: +// ------------------------------ +// The station controller listens to chocolate lot state data that indicates +// that a chocolate lot is on the way to this station controller. +// +// It uses a DDS DataReader, with a content filter to receive only updates +// that indicate that it is the next station controller to process the lot. +// +// Writing ChocolateLotState data: +// ---------------------------- +// This application sends chocolate lot state data, announcing that the current +// lot of chocolates is either: +// 1. Waiting to be processed by this station controller +// 2. Being processed by this station controller +// 3. Done being processed by this station controller/ready to be processed +// by the next station controller. +// +// For information on the ChocolateRecipe or ChocolateLotState types, please see +// the ChocolateFactory.idl file. +// +// For information on the quality of service for state data, please see the +// recipe_profiles_multicast.xml file. +// +// Reading Recipe data: +// -------------------- +// This application reads recipe data to know which state controller to send +// the chocolate lot to when it is done. +// +// Quality of Service: +// ------------------- +// All of the data in this example is modeled as "state data," which means that: +// 1. It is sent reliably (RELIABLE_RELIABILITY_QOS) +// 2. It is made available to late-joining applications as soon as they start +// (TRANSIENT_LOCAL_DURABILITY_QOS) +// 3. A predetermined amount of state is sent to any late-joiners. In this +// case, applications are only interested in the current state of each +// chocolate lot (or the current chocolate recipe), which translates to a +// history with depth = 1, kind = KEEP_LAST_HISTORY_QOS +// + +// ------------------------------------------------------------------------- // +// +// StationControllerInterface: +// A class that sets up the DDS interface (the network interface) of this +// chocolate factory's station controller applications. +// +// This includes creating appropriate DDS DataWriters, DDS DataReaders, and +// all other DDS objects. +// +// ------------------------------------------------------------------------- // +class StationControllerInterface { +public: + // This takes in the ID of the station controller, + + // The station controller ID is used both when updating the chocolate lot + // state, and when listening for a chocolate lot state. + + // When listening for the chocolate lot state, this either: + // 1. Installs a content filtered topic to listen only for lots that + // are assigned to it, or + // 2. Installs a normal topic and monitors all updates to the chocolate + // lot state. + + + // --- Constructor --- + StationControllerInterface(StationControllerKind stationControllerID, + vector qosFileNames, string lotStateQosProfile, + string recipeQosProfile); + + // --- Destructor --- + virtual ~StationControllerInterface(); + + // --- Getter for the ChocolateLotStateWriter --- + // This returns a ChocolateLotStateWriter object, which is the part of the + // network interface that sends the chocolate lot's current state data over + // the network. Look at the ChocolateLotStateWriter class to see how to + // write data in RTI Connext DDS. + dds::pub::DataWriter& WriterChocolateLotState() + { + return _writerChocolateLotState; + } + + // --- Getter for the ChocolateLotStateReader --- + // This returns the ChocolateLotState reader - a small wrapper around the + // ChocolateLotStateReader that initializes the reader, the content filtered + // topic, and uses the DDS "WaitSet" object to wait for the chocolate lot + // state updates + dds::sub::DataReader& ReaderChocolateLotState() + { + return _readerChocolateLotState; + } + + // --- Getter for the RecipeReader --- + // This returns the Chocolate recipe reader - a small wrapper around the + // ChocolateRecipeDataReader that initializes the reader and uses the + // DDS "WaitSet" object to wait for recipes + dds::sub::DataReader& ReaderRecipe() + { + return _readerRecipe; + } + + // --- Getter for Controller ID --- + // Accessor for the controller ID + const StationControllerKind StationControllerID() + { + return _stationControllerID; + } + + // --- Retrieve recipes --- + // This example receives all recipes, and leaves them in the middleware's + // queue. It queries for a particular recipe when it receives an update + // about a lot and it needs to check the recipe for that lot. + ChocolateRecipe GetRecipe(const string recipeName); + +private: + // --- Private members --- + + // This contains the calls that allow the interface to create a + // "DomainParticipant", the first object that must be created to + // communicate over a DDS middleware. + DDSCommunicator& _comm; + + // If this is a controller, this filed is used to identify which station + // controller this is, and what part of the recipe it is responsible for. + // If this is not a station controller, this is set to invalid + StationControllerKind _stationControllerID; + + // Topic object used to define the datatype use by the ChocolateLotState + // DataWriter + dds::topic::Topic& _topicChocolateLotState; + // Topic object used to define the datatype use by the ChocolateLotState + // DataReader + dds::topic::ContentFilteredTopic& _cftChocolateLotState; + // Topic object used for Chocolate Recipe reader + dds::topic::Topic& _topicChocolateRecipe; + + // DataWriter object for ChocolateLotState + dds::pub::DataWriter& _writerChocolateLotState; + + // DataReader used for receiving chocolate lot state data + dds::sub::DataReader& _readerChocolateLotState; + + // Used for receiving recipe data, and for looking up received recipes. + dds::sub::DataReader& _readerRecipe; +}; + +#endif diff --git a/ChocolateFactory/ExampleCode/win/MES_vs2017.vcxproj b/ChocolateFactory/ExampleCode/win/MES_vs2017.vcxproj index f07f567a..4bcbee3c 100644 --- a/ChocolateFactory/ExampleCode/win/MES_vs2017.vcxproj +++ b/ChocolateFactory/ExampleCode/win/MES_vs2017.vcxproj @@ -23,34 +23,34 @@ Win32Proj FlightPlanPublisher ManufacturingExecutionSystem - 10.0.17763.0 + 10.0 Application true Unicode - v141 + v142 Application true Unicode - v141 + v142 Application false true Unicode - v141 + v142 Application false true Unicode - v141 + v142 @@ -92,12 +92,13 @@ Level3 Disabled _CRT_SECURE_NO_WARNINGS;RTI_WIN32;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)/include;$(NDDSHOME)/include/ndds + $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp MultiThreadedDebugDLL + stdcpp17 Console @@ -135,8 +136,9 @@ true true _CRT_SECURE_NO_WARNINGS;RTI_WIN32;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)/include;$(NDDSHOME)/include/ndds + $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp MultiThreadedDLL + stdcpp17 Console @@ -169,20 +171,19 @@ - - - - - - + + + + + - + @@ -195,6 +196,9 @@ {e287142f-0d1e-49bf-b3bc-a218c1d1629f} + + + diff --git a/ChocolateFactory/ExampleCode/win/RecipeGenerator_vs2017.vcxproj b/ChocolateFactory/ExampleCode/win/RecipeGenerator_vs2017.vcxproj index 83d7e629..6a70fbb8 100644 --- a/ChocolateFactory/ExampleCode/win/RecipeGenerator_vs2017.vcxproj +++ b/ChocolateFactory/ExampleCode/win/RecipeGenerator_vs2017.vcxproj @@ -22,32 +22,32 @@ RecipeGenerator RadarDataRaw_publisher {F5CD402E-66A5-E16C-4A72-08BEEA388FEA} - 10.0.17763.0 + 10.0 Application false MultiByte - v141 + v142 Application false MultiByte - v141 + v142 Application false MultiByte - v141 + v142 Application false MultiByte - v141 + v142 @@ -85,7 +85,7 @@ Disabled - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;%(AdditionalIncludeDirectories) + $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp WIN32;RTI_WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL @@ -100,6 +100,7 @@ true EditAndContinue Default + stdcpp17 _DEBUG;%(PreprocessorDefinitions) @@ -153,7 +154,7 @@ MaxSpeed OnlyExplicitInline - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;%(AdditionalIncludeDirectories) + $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp WIN32;RTI_WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDLL @@ -168,6 +169,7 @@ Level3 true Default + stdcpp17 NDEBUG;%(PreprocessorDefinitions) @@ -218,15 +220,14 @@ - + - - - - + + + @@ -241,6 +242,9 @@ {e287142f-0d1e-49bf-b3bc-a218c1d1629f} + + + diff --git a/ChocolateFactory/ExampleCode/win/SharedDataTypes_vs2017.vcxproj b/ChocolateFactory/ExampleCode/win/SharedDataTypes_vs2017.vcxproj index a643261e..6cf7ecc8 100644 --- a/ChocolateFactory/ExampleCode/win/SharedDataTypes_vs2017.vcxproj +++ b/ChocolateFactory/ExampleCode/win/SharedDataTypes_vs2017.vcxproj @@ -43,46 +43,44 @@ - - - - + + {E287142F-0D1E-49BF-B3BC-A218C1D1629F} Win32Proj SharedDataTypes SharedDataTypes - 10.0.17763.0 + 10.0 StaticLibrary true Unicode - v141 + v142 StaticLibrary true Unicode - v141 + v142 StaticLibrary false true Unicode - v141 + v142 StaticLibrary false true Unicode - v141 + v142 @@ -122,7 +120,8 @@ Disabled RTI_WIN32;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDebugDLL - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds + $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp + stdcpp17 Windows @@ -153,9 +152,10 @@ true true RTI_WIN32;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds + $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp MultiThreadedDLL false + stdcpp17 Windows diff --git a/ChocolateFactory/ExampleCode/win/StationController_vs2017.vcxproj b/ChocolateFactory/ExampleCode/win/StationController_vs2017.vcxproj index 1da34506..e7a7307e 100644 --- a/ChocolateFactory/ExampleCode/win/StationController_vs2017.vcxproj +++ b/ChocolateFactory/ExampleCode/win/StationController_vs2017.vcxproj @@ -23,34 +23,34 @@ Win32Proj TrackGUI StationController - 10.0.17763.0 + 10.0 Application true Unicode - v141 + v142 Application true Unicode - v141 + v142 Application false true Unicode - v141 + v142 Application false true Unicode - v141 + v142 @@ -92,10 +92,11 @@ Level3 Disabled _CRTDBG_MAPALLOC;WIN32;RTI_WIN32;_CRT_SECURE_NO_WARNINGS;wxUSE_GUI=1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds; + $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp MultiThreadedDebugDLL + stdcpp17 Console @@ -132,12 +133,13 @@ true true __WXMSW__;_WINDOWS;WIN32;RTI_WIN32;_CRT_SECURE_NO_WARNINGS;wxUSE_GUI=1;NDEBUG;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds + $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp MultiThreadedDLL + stdcpp17 Console @@ -183,17 +185,14 @@ - - - - + + - @@ -208,6 +207,9 @@ {e287142f-0d1e-49bf-b3bc-a218c1d1629f} + + + diff --git a/ChocolateFactory/README.md b/ChocolateFactory/README.md index 0ca5b36b..bff7e60d 100644 --- a/ChocolateFactory/README.md +++ b/ChocolateFactory/README.md @@ -1,5 +1,5 @@ -![Image](https://www.rti.com/hubfs/RTI_Oct2016/Images/rti-logounit.png) - RTI Connext DDS Use Case: +![Image](https://www.rti.com/hubfs/RTI_Oct2016/Images/rti-logounit.png) + RTI Connext DDS Use Case: Industrial Automation in a Chocolate Factory ======================================================================= @@ -57,54 +57,51 @@ can use to visualize and debug your distributed system. Visit: https://www.rti.com/downloads -How to Build this Code ----------------------- -o run this example on all platforms, an environment variable called `NDDSHOME` -must be set to point to the RTI Connext DDS installation directory, such as -rti_connext_dds-6.0.x. -For more information on how to set an environment variable, please see the RTI -Core Libraries and Utilities Getting Started Guide. - +Building the Example :wrench: +----------------------------- -We will refer to the location where you unzipped the example in this document -as EXAMPLE_HOME. +To build this example, first run CMake to generate the corresponding build +files. We recommend you use a separate directory to store all the generated +files (e.g., ./build). -All source and build files are located in EXAMPLE_HOME/ExampleCode/. Before -building or running, change directories into EXAMPLE_HOME/ExampleCode. +Starting from the `ExampleCode` directory +```sh +mkdir build +cd build +cmake ../src +``` +Once you have run CMake, you will find a number of new files in your build +directory (the list of generated files will depend on the specific CMake +Generator). To build the example, run CMake as follows: -Windows Systems ---------------- -On a Windows system, start by opening the file -`win32\ChocolateFactory-.sln`. - -This code is made up of a combination of libraries, source, and IDL files that -represent the interface to the application. The Visual Studio solution files -are set up to automatically generate the necessary code and link against the -required libraries. +```sh +cmake --build . +``` +**Note**: if you are using a multi-configuration generator, such as Visual +Studio solutions, you can specify the configuration mode to build as follows: -Linux Systems -------------- -To build the applications on a Linux system, change directories to the -ExampleCode directory and use the command: -``` -(g)make -f make/Makefile. +```sh +cmake --build . --config Release|Debug ``` -The platform you choose will be the combination of your processor, OS, and -compiler version. Right now this example only supports x64Linux3gcc5.4.0 +Alternatively, you can use directly the generated infrastructure (e.g., +Makefiles or Visual Studio Solutions) to build the example. If you generated +Makefiles in the configuration process, run make to build the example. Likewise, +if you generated a Visual Studio solution, open the solution and follow the +regular build process. Run the Example --------------- -On Windows systems, navigate to the EXAMPLE_HOME\ExampleCode\scripts directory. +On Windows systems, navigate to the EXAMPLE_HOME\ExampleCode\scripts directory. In this directory are four batch files to start the applications: - RecipeGenerator.bat - MES.bat - StationController.bat (to start a single station controller) - AllStationControllers.bat (to start all station controllers) -On Linux systems, navigate to the EXAMPLE_HOME/ExampleCode/scripts directory. +On Linux systems, navigate to the EXAMPLE_HOME/ExampleCode/scripts directory. In this directory are four batch files to start the applications: - RecipeGenerator.sh - MES.sh From a782e12e3cb8408a1684af60debc7ce844831172 Mon Sep 17 00:00:00 2001 From: DanKing-RTI <81592978+DanKing-RTI@users.noreply.github.com> Date: Mon, 9 Aug 2021 11:08:00 -0400 Subject: [PATCH 02/14] Update README.md --- ChocolateFactory/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ChocolateFactory/README.md b/ChocolateFactory/README.md index bff7e60d..d7531bba 100644 --- a/ChocolateFactory/README.md +++ b/ChocolateFactory/README.md @@ -1,4 +1,5 @@ ![Image](https://www.rti.com/hubfs/RTI_Oct2016/Images/rti-logounit.png) + RTI Connext DDS Use Case: Industrial Automation in a Chocolate Factory ======================================================================= @@ -61,8 +62,8 @@ Building the Example :wrench: ----------------------------- To build this example, first run CMake to generate the corresponding build -files. We recommend you use a separate directory to store all the generated -files (e.g., ./build). +files. You need to use a separate directory to store all the generated +files (./build). Starting from the `ExampleCode` directory ```sh From 9130c39af29c225969781d4e6d31f65bf1126afc Mon Sep 17 00:00:00 2001 From: DanKing-RTI Date: Mon, 9 Aug 2021 11:11:54 -0400 Subject: [PATCH 03/14] Removed all visual studio files from repo --- .../win/ChocolateFactory-vs2015.sln | 57 ---- .../win/ChocolateFactory-vs2017.sln | 57 ---- .../ExampleCode/win/MES_vs2015.vcxproj | 201 -------------- .../ExampleCode/win/MES_vs2017.vcxproj | 205 -------------- .../win/RecipeGenerator_vs2015.vcxproj | 247 ----------------- .../win/RecipeGenerator_vs2017.vcxproj | 251 ------------------ .../win/SharedDataTypes_vs2015.vcxproj | 195 -------------- .../win/SharedDataTypes_vs2017.vcxproj | 196 -------------- .../win/StationController_vs2015.vcxproj | 214 --------------- .../win/StationController_vs2017.vcxproj | 216 --------------- 10 files changed, 1839 deletions(-) delete mode 100644 ChocolateFactory/ExampleCode/win/ChocolateFactory-vs2015.sln delete mode 100644 ChocolateFactory/ExampleCode/win/ChocolateFactory-vs2017.sln delete mode 100644 ChocolateFactory/ExampleCode/win/MES_vs2015.vcxproj delete mode 100644 ChocolateFactory/ExampleCode/win/MES_vs2017.vcxproj delete mode 100644 ChocolateFactory/ExampleCode/win/RecipeGenerator_vs2015.vcxproj delete mode 100644 ChocolateFactory/ExampleCode/win/RecipeGenerator_vs2017.vcxproj delete mode 100644 ChocolateFactory/ExampleCode/win/SharedDataTypes_vs2015.vcxproj delete mode 100644 ChocolateFactory/ExampleCode/win/SharedDataTypes_vs2017.vcxproj delete mode 100644 ChocolateFactory/ExampleCode/win/StationController_vs2015.vcxproj delete mode 100644 ChocolateFactory/ExampleCode/win/StationController_vs2017.vcxproj diff --git a/ChocolateFactory/ExampleCode/win/ChocolateFactory-vs2015.sln b/ChocolateFactory/ExampleCode/win/ChocolateFactory-vs2015.sln deleted file mode 100644 index c8ec3da1..00000000 --- a/ChocolateFactory/ExampleCode/win/ChocolateFactory-vs2015.sln +++ /dev/null @@ -1,57 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ManufacturingExecutionSystem", "MES_vs2015.vcxproj", "{FA2857A7-83A2-426C-82A5-87F5A54EECFF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SharedDataTypes", "SharedDataTypes_vs2015.vcxproj", "{E287142F-0D1E-49BF-B3BC-A218C1D1629F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RecipeGenerator", "RecipeGenerator_vs2015.vcxproj", "{F5CD402E-66A5-E16C-4A72-08BEEA388FEA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StationController", "StationController_vs2015.vcxproj", "{BF91B58A-6407-4AFE-A17D-8C541C298A4F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Debug|Win32.ActiveCfg = Debug|Win32 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Debug|Win32.Build.0 = Debug|Win32 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Debug|x64.ActiveCfg = Debug|x64 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Debug|x64.Build.0 = Debug|x64 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Release|Win32.ActiveCfg = Release|Win32 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Release|Win32.Build.0 = Release|Win32 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Release|x64.ActiveCfg = Release|x64 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Release|x64.Build.0 = Release|x64 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Debug|Win32.ActiveCfg = Debug|Win32 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Debug|Win32.Build.0 = Debug|Win32 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Debug|x64.ActiveCfg = Debug|x64 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Debug|x64.Build.0 = Debug|x64 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Release|Win32.ActiveCfg = Release|Win32 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Release|Win32.Build.0 = Release|Win32 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Release|x64.ActiveCfg = Release|x64 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Release|x64.Build.0 = Release|x64 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Debug|Win32.ActiveCfg = Debug|Win32 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Debug|Win32.Build.0 = Debug|Win32 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Debug|x64.ActiveCfg = Debug|x64 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Debug|x64.Build.0 = Debug|x64 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Release|Win32.ActiveCfg = Release|Win32 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Release|Win32.Build.0 = Release|Win32 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Release|x64.ActiveCfg = Release|x64 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Release|x64.Build.0 = Release|x64 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Debug|Win32.ActiveCfg = Debug|Win32 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Debug|Win32.Build.0 = Debug|Win32 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Debug|x64.ActiveCfg = Debug|x64 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Debug|x64.Build.0 = Debug|x64 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Release|Win32.ActiveCfg = Release|Win32 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Release|Win32.Build.0 = Release|Win32 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Release|x64.ActiveCfg = Release|x64 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/ChocolateFactory/ExampleCode/win/ChocolateFactory-vs2017.sln b/ChocolateFactory/ExampleCode/win/ChocolateFactory-vs2017.sln deleted file mode 100644 index 6380cebb..00000000 --- a/ChocolateFactory/ExampleCode/win/ChocolateFactory-vs2017.sln +++ /dev/null @@ -1,57 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ManufacturingExecutionSystem", "MES_vs2017.vcxproj", "{FA2857A7-83A2-426C-82A5-87F5A54EECFF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SharedDataTypes", "SharedDataTypes_vs2017.vcxproj", "{E287142F-0D1E-49BF-B3BC-A218C1D1629F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RecipeGenerator", "RecipeGenerator_vs2017.vcxproj", "{F5CD402E-66A5-E16C-4A72-08BEEA388FEA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StationController", "StationController_vs2017.vcxproj", "{BF91B58A-6407-4AFE-A17D-8C541C298A4F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Debug|Win32.ActiveCfg = Debug|Win32 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Debug|Win32.Build.0 = Debug|Win32 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Debug|x64.ActiveCfg = Debug|x64 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Debug|x64.Build.0 = Debug|x64 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Release|Win32.ActiveCfg = Release|Win32 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Release|Win32.Build.0 = Release|Win32 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Release|x64.ActiveCfg = Release|x64 - {FA2857A7-83A2-426C-82A5-87F5A54EECFF}.Release|x64.Build.0 = Release|x64 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Debug|Win32.ActiveCfg = Debug|Win32 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Debug|Win32.Build.0 = Debug|Win32 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Debug|x64.ActiveCfg = Debug|x64 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Debug|x64.Build.0 = Debug|x64 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Release|Win32.ActiveCfg = Release|Win32 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Release|Win32.Build.0 = Release|Win32 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Release|x64.ActiveCfg = Release|x64 - {E287142F-0D1E-49BF-B3BC-A218C1D1629F}.Release|x64.Build.0 = Release|x64 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Debug|Win32.ActiveCfg = Debug|Win32 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Debug|Win32.Build.0 = Debug|Win32 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Debug|x64.ActiveCfg = Debug|x64 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Debug|x64.Build.0 = Debug|x64 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Release|Win32.ActiveCfg = Release|Win32 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Release|Win32.Build.0 = Release|Win32 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Release|x64.ActiveCfg = Release|x64 - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA}.Release|x64.Build.0 = Release|x64 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Debug|Win32.ActiveCfg = Debug|Win32 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Debug|Win32.Build.0 = Debug|Win32 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Debug|x64.ActiveCfg = Debug|x64 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Debug|x64.Build.0 = Debug|x64 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Release|Win32.ActiveCfg = Release|Win32 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Release|Win32.Build.0 = Release|Win32 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Release|x64.ActiveCfg = Release|x64 - {BF91B58A-6407-4AFE-A17D-8C541C298A4F}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/ChocolateFactory/ExampleCode/win/MES_vs2015.vcxproj b/ChocolateFactory/ExampleCode/win/MES_vs2015.vcxproj deleted file mode 100644 index 262d200c..00000000 --- a/ChocolateFactory/ExampleCode/win/MES_vs2015.vcxproj +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {FA2857A7-83A2-426C-82A5-87F5A54EECFF} - Win32Proj - FlightPlanPublisher - ManufacturingExecutionSystem - 8.1 - - - - Application - true - Unicode - v140 - - - Application - true - Unicode - v140 - - - Application - false - true - Unicode - v140 - - - Application - false - true - Unicode - v140 - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)$(Configuration)\i86Win32VS2015\ - $(Configuration)\i86Win32VS2015\$(ProjectName)\ - - - true - $(SolutionDir)\$(Configuration)\x64Win64VS2015 - - - false - $(SolutionDir)$(Configuration)\i86Win32VS2015\ - $(Configuration)\i86Win32VS2015\$(ProjectName)\ - - - false - $(SolutionDir)\$(Configuration)\x64Win64VS2015 - - - - NotUsing - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;RTI_WIN32;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)/include;$(NDDSHOME)/include/ndds - - - - - MultiThreadedDebugDLL - - - Console - true - nddscppzd.lib;nddsczd.lib;nddscorezd.lib;netapi32.lib;WS2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(NDDSHOME)/lib/i86Win32VS2015 - - - - - NotUsing - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;RTI_WIN32;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)/include;$(NDDSHOME)/include/ndds - - - - - MultiThreadedDebugDLL - - - Console - true - nddscppzd.lib;nddsczd.lib;nddscorezd.lib;netapi32.lib;WS2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(NDDSHOME)/lib/x64Win64VS2015 - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;RTI_WIN32;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)/include;$(NDDSHOME)/include/ndds - MultiThreadedDLL - - - Console - false - true - true - $(NDDSHOME)/lib/i86Win32VS2015 - nddscppz.lib;nddscz.lib;nddscorez.lib;netapi32.lib;WS2_32.lib;advapi32.lib;shell32.lib;%(AdditionalDependencies) - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;RTI_WIN32;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)/include;$(NDDSHOME)/include/ndds - MultiThreadedDLL - - - Console - false - true - true - $(NDDSHOME)/lib/x64Win64VS2015 - nddscppz.lib;nddscz.lib;nddscorez.lib;netapi32.lib;WS2_32.lib;advapi32.lib;shell32.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - {e287142f-0d1e-49bf-b3bc-a218c1d1629f} - - - - - - \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/win/MES_vs2017.vcxproj b/ChocolateFactory/ExampleCode/win/MES_vs2017.vcxproj deleted file mode 100644 index 4bcbee3c..00000000 --- a/ChocolateFactory/ExampleCode/win/MES_vs2017.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {FA2857A7-83A2-426C-82A5-87F5A54EECFF} - Win32Proj - FlightPlanPublisher - ManufacturingExecutionSystem - 10.0 - - - - Application - true - Unicode - v142 - - - Application - true - Unicode - v142 - - - Application - false - true - Unicode - v142 - - - Application - false - true - Unicode - v142 - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)$(Configuration)\i86Win32VS2017\ - $(Configuration)\i86Win32VS2017\$(ProjectName)\ - - - true - $(SolutionDir)\$(Configuration)\x64Win64VS2017 - - - false - $(SolutionDir)$(Configuration)\i86Win32VS2017\ - $(Configuration)\i86Win32VS2017\$(ProjectName)\ - - - false - $(SolutionDir)\$(Configuration)\x64Win64VS2017 - - - - NotUsing - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;RTI_WIN32;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp - - - - - MultiThreadedDebugDLL - stdcpp17 - - - Console - true - nddscppzd.lib;nddsczd.lib;nddscorezd.lib;netapi32.lib;WS2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(NDDSHOME)/lib/i86Win32VS2017 - - - - - NotUsing - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;RTI_WIN32;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)/include;$(NDDSHOME)/include/ndds - - - - - MultiThreadedDebugDLL - - - Console - true - nddscppzd.lib;nddsczd.lib;nddscorezd.lib;netapi32.lib;WS2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(NDDSHOME)/lib/x64Win64VS2017 - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;RTI_WIN32;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp - MultiThreadedDLL - stdcpp17 - - - Console - false - true - true - $(NDDSHOME)/lib/i86Win32VS2017 - nddscppz.lib;nddscz.lib;nddscorez.lib;netapi32.lib;WS2_32.lib;advapi32.lib;shell32.lib;%(AdditionalDependencies) - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;RTI_WIN32;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)/include;$(NDDSHOME)/include/ndds - MultiThreadedDLL - - - Console - false - true - true - $(NDDSHOME)/lib/x64Win64VS2017 - nddscppz.lib;nddscz.lib;nddscorez.lib;netapi32.lib;WS2_32.lib;advapi32.lib;shell32.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - {e287142f-0d1e-49bf-b3bc-a218c1d1629f} - - - - - - - - - \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/win/RecipeGenerator_vs2015.vcxproj b/ChocolateFactory/ExampleCode/win/RecipeGenerator_vs2015.vcxproj deleted file mode 100644 index 0a181da2..00000000 --- a/ChocolateFactory/ExampleCode/win/RecipeGenerator_vs2015.vcxproj +++ /dev/null @@ -1,247 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - RecipeGenerator - RadarDataRaw_publisher - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA} - 8.1 - - - - Application - false - MultiByte - v140 - - - Application - false - MultiByte - v140 - - - Application - false - MultiByte - v140 - - - Application - false - MultiByte - v140 - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.21006.1 - $(SolutionDir)$(Configuration)\i86Win32VS2015\ - $(Configuration)\i86Win32VS2015\$(ProjectName)\ - - - $(SolutionDir)$(Configuration)\i86Win32VS2015\ - $(Configuration)\i86Win32VS2015\$(ProjectName)\ - - - - - $(SolutionDir)\$(Configuration)\x64Win64VS2015 - - - $(SolutionDir)\$(Configuration)\x64Win64VS2015 - - - - Disabled - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;%(AdditionalIncludeDirectories) - WIN32;RTI_WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - - - - - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - nddscppzd.lib;nddsczd.lib;nddscorezd.lib;netapi32.lib;advapi32.lib;user32.lib;WS2_32.lib;;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(NDDSHOME)\lib\i86Win32VS2015;%(AdditionalLibraryDirectories) - true - $(TargetDir)$(TargetName).pdb - Console - MachineX86 - - - - - Disabled - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;%(AdditionalIncludeDirectories) - WIN32;RTI_WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - - - - - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - nddscppzd.lib;nddsczd.lib;nddscorezd.lib;netapi32.lib;advapi32.lib;user32.lib;WS2_32.lib;;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(NDDSHOME)\lib\x64Win64VS2015;%(AdditionalLibraryDirectories) - true - $(TargetDir)$(TargetName).pdb - Console - - - - - MaxSpeed - OnlyExplicitInline - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;%(AdditionalIncludeDirectories) - WIN32;RTI_WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - - - - - .\objs\i86Win32VS2015\ - .\objs\i86Win32VS2015\ - .\objs\i86Win32VS2015\ - Level3 - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - nddscppz.lib;nddscz.lib;nddscorez.lib;netapi32.lib;advapi32.lib;user32.lib;WS2_32.lib;;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(NDDSHOME)\lib\i86Win32VS2015;%(AdditionalLibraryDirectories) - .\objs\i86Win32VS2015\RadarDataRaw_publisher.pdb - Console - MachineX86 - - - - - MaxSpeed - OnlyExplicitInline - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;%(AdditionalIncludeDirectories) - WIN32;RTI_WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - - - - - .\objs\x64Win64VS2015\ - .\objs\x64Win64VS2015\ - .\objs\x64Win64VS2015\ - Level3 - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - nddscppz.lib;nddscz.lib;nddscorez.lib;netapi32.lib;advapi32.lib;user32.lib;WS2_32.lib;;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(NDDSHOME)\lib\x64Win64VS2015;%(AdditionalLibraryDirectories) - .\objs\i86Win32VS2015\RadarDataRaw_publisher.pdb - Console - - - - - - - - - - - - - - - - - - - Designer - - - - - - {e287142f-0d1e-49bf-b3bc-a218c1d1629f} - - - - - - \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/win/RecipeGenerator_vs2017.vcxproj b/ChocolateFactory/ExampleCode/win/RecipeGenerator_vs2017.vcxproj deleted file mode 100644 index 6a70fbb8..00000000 --- a/ChocolateFactory/ExampleCode/win/RecipeGenerator_vs2017.vcxproj +++ /dev/null @@ -1,251 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - RecipeGenerator - RadarDataRaw_publisher - {F5CD402E-66A5-E16C-4A72-08BEEA388FEA} - 10.0 - - - - Application - false - MultiByte - v142 - - - Application - false - MultiByte - v142 - - - Application - false - MultiByte - v142 - - - Application - false - MultiByte - v142 - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.21006.1 - $(SolutionDir)$(Configuration)\i86Win32VS2017\ - $(Configuration)\i86Win32VS2017\$(ProjectName)\ - - - $(SolutionDir)$(Configuration)\i86Win32VS2017\ - $(Configuration)\i86Win32VS2017\$(ProjectName)\ - - - - - $(SolutionDir)\$(Configuration)\x64Win64VS2017 - - - $(SolutionDir)\$(Configuration)\x64Win64VS2017 - - - - Disabled - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp - WIN32;RTI_WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - - - - - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - Default - stdcpp17 - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - nddscppzd.lib;nddsczd.lib;nddscorezd.lib;netapi32.lib;advapi32.lib;user32.lib;WS2_32.lib;;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(NDDSHOME)\lib\i86Win32VS2017;%(AdditionalLibraryDirectories) - true - $(TargetDir)$(TargetName).pdb - Console - MachineX86 - - - - - Disabled - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;%(AdditionalIncludeDirectories) - WIN32;RTI_WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - - - - - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - nddscppzd.lib;nddsczd.lib;nddscorezd.lib;netapi32.lib;advapi32.lib;user32.lib;WS2_32.lib;;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(NDDSHOME)\lib\x64Win64VS2017;%(AdditionalLibraryDirectories) - true - $(TargetDir)$(TargetName).pdb - Console - - - - - MaxSpeed - OnlyExplicitInline - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp - WIN32;RTI_WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - - - - - .\objs\i86Win32VS2017\ - .\objs\i86Win32VS2017\ - .\objs\i86Win32VS2017\ - Level3 - true - Default - stdcpp17 - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - nddscppz.lib;nddscz.lib;nddscorez.lib;netapi32.lib;advapi32.lib;user32.lib;WS2_32.lib;;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(NDDSHOME)\lib\i86Win32VS2017;%(AdditionalLibraryDirectories) - .\objs\i86Win32VS2017\RadarDataRaw_publisher.pdb - Console - MachineX86 - - - - - MaxSpeed - OnlyExplicitInline - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;%(AdditionalIncludeDirectories) - WIN32;RTI_WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - - - - - .\objs\x64Win64VS2017\ - .\objs\x64Win64VS2017\ - .\objs\x64Win64VS2017\ - Level3 - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - nddscppz.lib;nddscz.lib;nddscorez.lib;netapi32.lib;advapi32.lib;user32.lib;WS2_32.lib;;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(NDDSHOME)\lib\x64Win64VS2017;%(AdditionalLibraryDirectories) - .\objs\i86Win32VS2017\RadarDataRaw_publisher.pdb - Console - - - - - - - - - - - - - - - - - - Designer - - - - - - {e287142f-0d1e-49bf-b3bc-a218c1d1629f} - - - - - - - - - \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/win/SharedDataTypes_vs2015.vcxproj b/ChocolateFactory/ExampleCode/win/SharedDataTypes_vs2015.vcxproj deleted file mode 100644 index 783a0bcc..00000000 --- a/ChocolateFactory/ExampleCode/win/SharedDataTypes_vs2015.vcxproj +++ /dev/null @@ -1,195 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - "$(NDDSHOME)\bin\rtiddsgen" ..\src\Idl\ChocolateFactory.idl -replace -namespace -language C++ -d ..\src\Generated - "$(NDDSHOME)\bin\rtiddsgen" ..\src\Idl\ChocolateFactory.idl -replace -namespace -language C++ -d ..\src\Generated - "$(NDDSHOME)\bin\rtiddsgen" ..\src\Idl\ChocolateFactory.idl -replace -namespace -language C++ -d ..\src\Generated - "$(NDDSHOME)\bin\rtiddsgen" ..\src\Idl\ChocolateFactory.idl -replace -namespace -language C++ -d ..\src\Generated - Generating .cxx files from .idl ... - Generating .cxx files from .idl ... - Generating .cxx files from .idl ... - Generating .cxx files from .idl ... - %(RootDir)%(Directory)..\Generated\%(Filename).h;%(RootDir)%(Directory)..\Generated\%(Filename).cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.h;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Support.h;%(RootDir)%(Directory)..\Generated\%(Filename)Support.cxx;%(Outputs) - %(RootDir)%(Directory)..\Generated\%(Filename).h;%(RootDir)%(Directory)..\Generated\%(Filename).cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.h;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Support.h;%(RootDir)%(Directory)..\Generated\%(Filename)Support.cxx;%(Outputs) - %(RootDir)%(Directory)..\Generated\%(Filename).h;%(RootDir)%(Directory)..\Generated\%(Filename).cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.h;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Support.h;%(RootDir)%(Directory)..\Generated\%(Filename)Support.cxx;%(Outputs) - %(RootDir)%(Directory)..\Generated\%(Filename).h;%(RootDir)%(Directory)..\Generated\%(Filename).cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.h;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Support.h;%(RootDir)%(Directory)..\Generated\%(Filename)Support.cxx;%(Outputs) - - - - - - - - - - - - - - - - - - - - {E287142F-0D1E-49BF-B3BC-A218C1D1629F} - Win32Proj - SharedDataTypes - SharedDataTypes - - - - StaticLibrary - true - Unicode - v140 - - - StaticLibrary - true - Unicode - v140 - - - StaticLibrary - false - true - Unicode - v140 - - - StaticLibrary - false - true - Unicode - v140 - - - - - - - - - - - - - - - - - - - $(Configuration)\i86Win32VS2015\$(ProjectName)\ - $(ProjectName) - - - $(ProjectName) - - - $(Configuration)\i86Win32VS2015\$(ProjectName)\ - $(ProjectName) - - - $(ProjectName) - - - - - - Level3 - Disabled - RTI_WIN32;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds - - - Windows - true - - - - - - - Level3 - Disabled - RTI_WIN32;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds - - - Windows - true - - - - - Level3 - - - MaxSpeed - true - true - RTI_WIN32;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds - MultiThreadedDLL - false - - - Windows - true - true - true - - - false - - - - - Level3 - - - MaxSpeed - true - true - RTI_WIN32;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds - MultiThreadedDLL - false - - - Windows - true - true - true - - - false - - - - - - \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/win/SharedDataTypes_vs2017.vcxproj b/ChocolateFactory/ExampleCode/win/SharedDataTypes_vs2017.vcxproj deleted file mode 100644 index 6cf7ecc8..00000000 --- a/ChocolateFactory/ExampleCode/win/SharedDataTypes_vs2017.vcxproj +++ /dev/null @@ -1,196 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - "$(NDDSHOME)\bin\rtiddsgen" ..\src\Idl\ChocolateFactory.idl -replace -namespace -language C++ -d ..\src\Generated - "$(NDDSHOME)\bin\rtiddsgen" ..\src\Idl\ChocolateFactory.idl -replace -namespace -language C++ -d ..\src\Generated - "$(NDDSHOME)\bin\rtiddsgen" ..\src\Idl\ChocolateFactory.idl -replace -namespace -language C++ -d ..\src\Generated - "$(NDDSHOME)\bin\rtiddsgen" ..\src\Idl\ChocolateFactory.idl -replace -namespace -language C++ -d ..\src\Generated - Generating .cxx files from .idl ... - Generating .cxx files from .idl ... - Generating .cxx files from .idl ... - Generating .cxx files from .idl ... - %(RootDir)%(Directory)..\Generated\%(Filename).h;%(RootDir)%(Directory)..\Generated\%(Filename).cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.h;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Support.h;%(RootDir)%(Directory)..\Generated\%(Filename)Support.cxx;%(Outputs) - %(RootDir)%(Directory)..\Generated\%(Filename).h;%(RootDir)%(Directory)..\Generated\%(Filename).cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.h;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Support.h;%(RootDir)%(Directory)..\Generated\%(Filename)Support.cxx;%(Outputs) - %(RootDir)%(Directory)..\Generated\%(Filename).h;%(RootDir)%(Directory)..\Generated\%(Filename).cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.h;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Support.h;%(RootDir)%(Directory)..\Generated\%(Filename)Support.cxx;%(Outputs) - %(RootDir)%(Directory)..\Generated\%(Filename).h;%(RootDir)%(Directory)..\Generated\%(Filename).cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.h;%(RootDir)%(Directory)..\Generated\%(Filename)Plugin.cxx;%(RootDir)%(Directory)..\Generated\%(Filename)Support.h;%(RootDir)%(Directory)..\Generated\%(Filename)Support.cxx;%(Outputs) - - - - - - - - - - - - - - - - - - {E287142F-0D1E-49BF-B3BC-A218C1D1629F} - Win32Proj - SharedDataTypes - SharedDataTypes - 10.0 - - - - StaticLibrary - true - Unicode - v142 - - - StaticLibrary - true - Unicode - v142 - - - StaticLibrary - false - true - Unicode - v142 - - - StaticLibrary - false - true - Unicode - v142 - - - - - - - - - - - - - - - - - - - $(Configuration)\i86Win32VS2017\$(ProjectName)\ - $(ProjectName) - - - $(ProjectName) - - - $(Configuration)\i86Win32VS2017\$(ProjectName)\ - $(ProjectName) - - - $(ProjectName) - - - - - - Level3 - Disabled - RTI_WIN32;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp - stdcpp17 - - - Windows - true - - - - - - - Level3 - Disabled - RTI_WIN32;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds - - - Windows - true - - - - - Level3 - - - MaxSpeed - true - true - RTI_WIN32;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp - MultiThreadedDLL - false - stdcpp17 - - - Windows - true - true - true - - - false - - - - - Level3 - - - MaxSpeed - true - true - RTI_WIN32;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds - MultiThreadedDLL - false - - - Windows - true - true - true - - - false - - - - - - \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/win/StationController_vs2015.vcxproj b/ChocolateFactory/ExampleCode/win/StationController_vs2015.vcxproj deleted file mode 100644 index 4c43c012..00000000 --- a/ChocolateFactory/ExampleCode/win/StationController_vs2015.vcxproj +++ /dev/null @@ -1,214 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {BF91B58A-6407-4AFE-A17D-8C541C298A4F} - Win32Proj - TrackGUI - StationController - 8.1 - - - - Application - true - Unicode - v140 - - - Application - true - Unicode - v140 - - - Application - false - true - Unicode - v140 - - - Application - false - true - Unicode - v140 - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)$(Configuration)\i86Win32VS2015\ - $(Configuration)\i86Win32VS2015\$(ProjectName)\ - - - true - $(SolutionDir)\$(Configuration)\x64Win64VS2015 - - - false - $(SolutionDir)$(Configuration)\i86Win32VS2015\ - $(Configuration)\i86Win32VS2015\$(ProjectName)\ - - - false - $(SolutionDir)\$(Configuration)\x64Win64VS2015 - - - - NotUsing - Level3 - Disabled - _CRTDBG_MAPALLOC;WIN32;RTI_WIN32;_CRT_SECURE_NO_WARNINGS;wxUSE_GUI=1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds; - - - MultiThreadedDebugDLL - - - Console - true - $(NDDSHOME)\lib\i86Win32VS2015 - nddscppzd.lib;nddsczd.lib;nddscorezd.lib;netapi32.lib;comctl32.lib;rpcrt4.lib;winmm.lib;wsock32.lib;ws2_32.lib;%(AdditionalDependencies) - NotSet - - - - - NotUsing - Level3 - Disabled - _CRTDBG_MAPALLOC;WIN32;RTI_WIN32;_CRT_SECURE_NO_WARNINGS;wxUSE_GUI=1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds; - - - MultiThreadedDebugDLL - - - Console - true - $(NDDSHOME)\lib\x64Win64VS2015 - nddscppzd.lib;nddsczd.lib;nddscorezd.lib;netapi32.lib;comctl32.lib;rpcrt4.lib;winmm.lib;wsock32.lib;ws2_32.lib;%(AdditionalDependencies) - NotSet - - - - - Level3 - NotUsing - MaxSpeed - true - true - __WXMSW__;_WINDOWS;WIN32;RTI_WIN32;_CRT_SECURE_NO_WARNINGS;wxUSE_GUI=1;NDEBUG;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds - MultiThreadedDLL - - - - - - - Console - true - true - true - nddscppz.lib;nddscz.lib;nddscorez.lib;WS2_32.lib;netapi32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) - $(NDDSHOME)\lib\i86Win32VS2015 - NotSet - - - true - - - - - Level3 - NotUsing - MaxSpeed - true - true - __WXMSW__;_WINDOWS;WIN32;RTI_WIN32;_CRT_SECURE_NO_WARNINGS;wxUSE_GUI=1;NDEBUG;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds - MultiThreadedDLL - - - - - - - Console - true - true - true - nddscppz.lib;nddscz.lib;nddscorez.lib;WS2_32.lib;netapi32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) - $(NDDSHOME)\lib\x64Win64VS2015 - NotSet - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - {e287142f-0d1e-49bf-b3bc-a218c1d1629f} - - - - - - \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/win/StationController_vs2017.vcxproj b/ChocolateFactory/ExampleCode/win/StationController_vs2017.vcxproj deleted file mode 100644 index e7a7307e..00000000 --- a/ChocolateFactory/ExampleCode/win/StationController_vs2017.vcxproj +++ /dev/null @@ -1,216 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {BF91B58A-6407-4AFE-A17D-8C541C298A4F} - Win32Proj - TrackGUI - StationController - 10.0 - - - - Application - true - Unicode - v142 - - - Application - true - Unicode - v142 - - - Application - false - true - Unicode - v142 - - - Application - false - true - Unicode - v142 - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)$(Configuration)\i86Win32VS2017\ - $(Configuration)\i86Win32VS2017\$(ProjectName)\ - - - true - $(SolutionDir)\$(Configuration)\x64Win64VS2017 - - - false - $(SolutionDir)$(Configuration)\i86Win32VS2017\ - $(Configuration)\i86Win32VS2017\$(ProjectName)\ - - - false - $(SolutionDir)\$(Configuration)\x64Win64VS2017 - - - - NotUsing - Level3 - Disabled - _CRTDBG_MAPALLOC;WIN32;RTI_WIN32;_CRT_SECURE_NO_WARNINGS;wxUSE_GUI=1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp - - - MultiThreadedDebugDLL - stdcpp17 - - - Console - true - $(NDDSHOME)\lib\i86Win32VS2017 - nddscppzd.lib;nddsczd.lib;nddscorezd.lib;netapi32.lib;comctl32.lib;rpcrt4.lib;winmm.lib;wsock32.lib;ws2_32.lib;%(AdditionalDependencies) - NotSet - - - - - NotUsing - Level3 - Disabled - _CRTDBG_MAPALLOC;WIN32;RTI_WIN32;_CRT_SECURE_NO_WARNINGS;wxUSE_GUI=1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds; - - - MultiThreadedDebugDLL - - - Console - true - $(NDDSHOME)\lib\x64Win64VS2017 - nddscppzd.lib;nddsczd.lib;nddscorezd.lib;netapi32.lib;comctl32.lib;rpcrt4.lib;winmm.lib;wsock32.lib;ws2_32.lib;%(AdditionalDependencies) - NotSet - - - - - Level3 - NotUsing - MaxSpeed - true - true - __WXMSW__;_WINDOWS;WIN32;RTI_WIN32;_CRT_SECURE_NO_WARNINGS;wxUSE_GUI=1;NDEBUG;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp - MultiThreadedDLL - - - - - stdcpp17 - - - Console - true - true - true - nddscppz.lib;nddscz.lib;nddscorez.lib;WS2_32.lib;netapi32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) - $(NDDSHOME)\lib\i86Win32VS2017 - NotSet - - - true - - - - - Level3 - NotUsing - MaxSpeed - true - true - __WXMSW__;_WINDOWS;WIN32;RTI_WIN32;_CRT_SECURE_NO_WARNINGS;wxUSE_GUI=1;NDEBUG;%(PreprocessorDefinitions) - $(NDDSHOME)\include;$(NDDSHOME)\include\ndds - MultiThreadedDLL - - - - - - - Console - true - true - true - nddscppz.lib;nddscz.lib;nddscorez.lib;WS2_32.lib;netapi32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;wsock32.lib;comctl32.lib;%(AdditionalDependencies) - $(NDDSHOME)\lib\x64Win64VS2017 - NotSet - - - true - - - - - - - - - - - - - - - - - - - - - - - - - {e287142f-0d1e-49bf-b3bc-a218c1d1629f} - - - - - - - - - \ No newline at end of file From 23439b11f7bbe41c1dc19072e58883b67f76e83f Mon Sep 17 00:00:00 2001 From: Dan King Date: Mon, 9 Aug 2021 12:13:29 -0400 Subject: [PATCH 04/14] Updated private dds members to pointers rather than references --- .../CommonInfrastructure/DDSCommunicator.cxx | 77 +++++++++---------- .../CommonInfrastructure/DDSCommunicator.hpp | 8 +- .../MESInterface.cxx | 21 ++--- .../MESInterface.hpp | 10 +-- .../RecipePublisherInterface.cxx | 13 ++-- .../RecipePublisherInterface.hpp | 4 +- .../StationControllerInterface.cxx | 40 +++++----- .../StationControllerInterface.hpp | 18 ++--- 8 files changed, 93 insertions(+), 98 deletions(-) diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx index 400edab1..d0b83591 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx @@ -48,29 +48,30 @@ using namespace std; // For more information on participant QoS, see the USER_QOS_PROFILES.xml // file // ------------------------------------------------------------------------- // -DDSCommunicator::DDSCommunicator() : - _qos(dds::core::QosProvider::Default()), - _participant(dds::domain::DomainParticipant(0)), - _pub(dds::pub::Publisher(_participant)), - _sub(dds::sub::Subscriber(_participant)) -{ } -DDSCommunicator::DDSCommunicator(std::string& qosFile) : - _qos(dds::core::QosProvider(qosFile)), - _participant(dds::domain::DomainParticipant(0, _qos.participant_qos())), - _pub(dds::pub::Publisher(_participant, _qos.publisher_qos())), - _sub(dds::sub::Subscriber(_participant, _qos.subscriber_qos())) -{ } -DDSCommunicator::DDSCommunicator(std::string& qosFile, std::string& profile) : - _qos(dds::core::QosProvider(qosFile, profile)), - _participant(dds::domain::DomainParticipant(0, _qos.participant_qos(profile))), - _pub(dds::pub::Publisher(_participant, _qos.publisher_qos(profile))), - _sub(dds::sub::Subscriber(_participant, _qos.subscriber_qos(profile))) -{ } -DDSCommunicator::DDSCommunicator(dds::core::StringSeq& qosFiles) : - _qos(dds::core::QosProvider(dds::core::null)), - _participant(dds::domain::DomainParticipant(dds::core::null)), - _pub(dds::pub::Publisher(dds::core::null)), - _sub(dds::sub::Subscriber(dds::core::null)) +DDSCommunicator::DDSCommunicator() +{ + _qos = new dds::core::QosProvider(dds::core::null); + *_qos = dds::core::QosProvider::Default(); + + _participant = new dds::domain::DomainParticipant(0); + _pub = new dds::pub::Publisher(*_participant); + _sub = new dds::sub::Subscriber(*_participant); +} +DDSCommunicator::DDSCommunicator(std::string& qosFile) +{ + _qos = new dds::core::QosProvider(qosFile); + _participant = new dds::domain::DomainParticipant(0, _qos->participant_qos()); + _pub = new dds::pub::Publisher(*_participant, _qos->publisher_qos()); + _sub = new dds::sub::Subscriber(*_participant, _qos->subscriber_qos()); +} +DDSCommunicator::DDSCommunicator(std::string& qosFile, std::string& profile) +{ + _qos = new dds::core::QosProvider(qosFile, profile); + _participant = new dds::domain::DomainParticipant(0, _qos->participant_qos(profile)); + _pub = new dds::pub::Publisher(*_participant, _qos->publisher_qos(profile)); + _sub = new dds::sub::Subscriber(*_participant, _qos->subscriber_qos(profile)); +} +DDSCommunicator::DDSCommunicator(dds::core::StringSeq& qosFiles) { ostringstream fileString; if (!qosFiles.empty()) { @@ -78,16 +79,12 @@ DDSCommunicator::DDSCommunicator(dds::core::StringSeq& qosFiles) : fileString << qosFiles.back(); } - _qos = dds::core::QosProvider(fileString.str()); - _participant = dds::domain::DomainParticipant(0, _qos.participant_qos()); - _pub = dds::pub::Publisher(_participant, _qos.publisher_qos()); - _sub = dds::sub::Subscriber(_participant, _qos.subscriber_qos()); + _qos = new dds::core::QosProvider(fileString.str()); + _participant = new dds::domain::DomainParticipant(0, _qos->participant_qos()); + _pub = new dds::pub::Publisher(*_participant, _qos->publisher_qos()); + _sub = new dds::sub::Subscriber(*_participant, _qos->subscriber_qos()); } -DDSCommunicator::DDSCommunicator(std::vector& qosFiles, std::string& profile) : - _qos(dds::core::QosProvider(dds::core::null)), - _participant(dds::domain::DomainParticipant(dds::core::null)), - _pub(dds::pub::Publisher(dds::core::null)), - _sub(dds::sub::Subscriber(dds::core::null)) +DDSCommunicator::DDSCommunicator(std::vector& qosFiles, std::string& profile) { ostringstream fileString; if (!qosFiles.empty()) { @@ -95,10 +92,10 @@ DDSCommunicator::DDSCommunicator(std::vector& qosFiles, std::string fileString << qosFiles.back(); } - _qos = dds::core::QosProvider(fileString.str()); - _participant = dds::domain::DomainParticipant(0, _qos.participant_qos(profile)); - _pub = dds::pub::Publisher(_participant, _qos.publisher_qos(profile)); - _sub = dds::sub::Subscriber(_participant, _qos.subscriber_qos(profile)); + _qos = new dds::core::QosProvider(fileString.str()); + _participant = new dds::domain::DomainParticipant(0, _qos->participant_qos(profile)); + _pub = new dds::pub::Publisher(*_participant, _qos->publisher_qos(profile)); + _sub = new dds::sub::Subscriber(*_participant, _qos->subscriber_qos(profile)); } @@ -122,19 +119,19 @@ DDSCommunicator::~DDSCommunicator() // Getters for QoS, Publisher, and Subscriber. dds::core::QosProvider& DDSCommunicator::Qos() { - return _qos; + return *_qos; } dds::domain::DomainParticipant& DDSCommunicator::Participant() { - return _participant; + return *_participant; } dds::pub::Publisher& DDSCommunicator::Publisher() { - return _pub; + return *_pub; } dds::sub::Subscriber& DDSCommunicator::Subscriber() { - return _sub; + return *_sub; } diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp index e496333c..7902362e 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp @@ -61,16 +61,16 @@ class DDSCommunicator { // --- Protected members --- // Used to create a QOS Provider to be used by other elements - dds::core::QosProvider& _qos; + dds::core::QosProvider* _qos; // Used to create other DDS entities - dds::domain::DomainParticipant& _participant; + dds::domain::DomainParticipant* _participant; // Used to create DataWriters - dds::pub::Publisher& _pub; + dds::pub::Publisher* _pub; // Used to create DataReaders - dds::sub::Subscriber& _sub; + dds::sub::Subscriber* _sub; }; diff --git a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx index 0a2fb611..834d22ac 100644 --- a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx @@ -71,22 +71,23 @@ using namespace com::chocolatefactory::generated; MESInterface::MESInterface(std::vector& qosFileNames) : _profile(QOS_PROFILE_STATE_DATA), - _communicator(DDSCommunicator(qosFileNames, _profile)), - _topicChocolateLotState(dds::topic::Topic( - _communicator.Participant(), CHOCOLATE_LOT_TOPIC, - _communicator.Qos().topic_qos(_profile))), - _writerChocolateLotState(dds::pub::DataWriter( - _communicator.Publisher(), _topicChocolateLotState, - _communicator.Qos().datawriter_qos(_profile))), - _readerChocolateLotState(dds::sub::DataReader( - _communicator.Subscriber(), _topicChocolateLotState, - _communicator.Qos().datareader_qos(_profile))) + _communicator(DDSCommunicator(qosFileNames, _profile)) { // Note: all data in this example is "state data." The string constants // with the QoS library name and the QoS profile name are configured as // constants in the .idl file. The profiles themselves are configured in // the .xml file. Look in the XML for more details on the definition of // state data. + + _topicChocolateLotState = new dds::topic::Topic( + _communicator.Participant(), CHOCOLATE_LOT_TOPIC, + _communicator.Qos().topic_qos(_profile)); + _writerChocolateLotState = new dds::pub::DataWriter( + _communicator.Publisher(), *_topicChocolateLotState, + _communicator.Qos().datawriter_qos(_profile)); + _readerChocolateLotState = new dds::sub::DataReader( + _communicator.Subscriber(), *_topicChocolateLotState, + _communicator.Qos().datareader_qos(_profile)); } // ------------------------------------------------------------------------- // diff --git a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp index 45af29b9..d957f733 100644 --- a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp @@ -61,7 +61,7 @@ class MESInterface { // the network. dds::pub::DataWriter& WriterChocolateLotState() { - return _writerChocolateLotState; + return *_writerChocolateLotState; } // --- Getter for the ChocolateLotStateReader --- @@ -71,7 +71,7 @@ class MESInterface { // state updates dds::sub::DataReader& ReaderChocolateLotState() { - return _readerChocolateLotState; + return *_readerChocolateLotState; } private: @@ -87,13 +87,13 @@ class MESInterface { // Topic object used to define the datatype use by the ChocolateLotState // DataReader and DataWriter - dds::topic::Topic& _topicChocolateLotState; + dds::topic::Topic* _topicChocolateLotState; // DataWriter object for ChocolateLotState - dds::pub::DataWriter& _writerChocolateLotState; + dds::pub::DataWriter* _writerChocolateLotState; // DataReader used for receiving chocolate lot state data - dds::sub::DataReader& _readerChocolateLotState; + dds::sub::DataReader* _readerChocolateLotState; }; #endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx index 7ab376d8..7566ab60 100644 --- a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx @@ -46,17 +46,18 @@ using namespace com::chocolatefactory::generated; RecipePublisherInterface::RecipePublisherInterface( std::vector& xmlFiles) : - _communicator(DDSCommunicator(xmlFiles)), - _topic(dds::topic::Topic(_communicator.Participant(), - RECIPE_TOPIC, _communicator.Qos().topic_qos())), - _writer(dds::pub::DataWriter(_communicator.Publisher(), - _topic, _communicator.Qos().datawriter_qos())) + _communicator(DDSCommunicator(xmlFiles)) { // Note: all data in this example is "state data." The string constants // with the QoS library name and the QoS profile name are configured as // constants in the .idl file. The profiles themselves are configured in // the .xml file. Look in the XML for more details on the definition of // state data. + + _topic = new dds::topic::Topic(_communicator.Participant(), + RECIPE_TOPIC, _communicator.Qos().topic_qos()); + _writer = new dds::pub::DataWriter(_communicator.Publisher(), + *_topic, _communicator.Qos().datawriter_qos()); } // ---------------------------------------------------------------------------- @@ -82,6 +83,6 @@ void RecipePublisherInterface::Write(ChocolateRecipe data) // throughput, so we are not bothering to pre-register the instance // handle. If we did pre-register the instance handle, this could // potentially speed up the writing. - _writer.write(data); + _writer->write(data); } diff --git a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp index d4ce8f7d..e8e5be08 100644 --- a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp @@ -65,10 +65,10 @@ class RecipePublisherInterface { DDSCommunicator& _communicator; // Topic object used by writer - dds::topic::Topic& _topic; + dds::topic::Topic* _topic; // Recipe publisher specific to this application - dds::pub::DataWriter& _writer; + dds::pub::DataWriter* _writer; }; #endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx index 03f49c9b..a0849393 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx @@ -84,23 +84,7 @@ StationControllerInterface::StationControllerInterface(StationControllerKind id, vector qosFileNames, string lotStateQosProfile, string recipeQosProfile) : _comm(DDSCommunicator(qosFileNames, (QOS_LIBRARY + "::" + - QOS_PROFILE_STATE_DATA))), - _topicChocolateLotState(Topic(_comm.Participant(), - CHOCOLATE_LOT_TOPIC, _comm.Qos().topic_qos(lotStateQosProfile))), - _cftChocolateLotState(ContentFilteredTopic( - _topicChocolateLotState, "ContentFilter", Filter( - "lotStatus = 'LOT_COMPLETED' OR nextController = %0", { - StationControllerType::ControllerEnumName(id) - }) - )), - _topicChocolateRecipe(Topic(_comm.Participant(), - RECIPE_TOPIC, _comm.Qos().topic_qos(recipeQosProfile))), - _writerChocolateLotState(DataWriter(_comm.Publisher(), - _topicChocolateLotState, _comm.Qos().datawriter_qos(lotStateQosProfile))), - _readerChocolateLotState(DataReader(_comm.Subscriber(), - _cftChocolateLotState, _comm.Qos().datareader_qos(lotStateQosProfile))), - _readerRecipe(DataReader(_comm.Subscriber(), - _topicChocolateRecipe, _comm.Qos().datareader_qos(recipeQosProfile))) + QOS_PROFILE_STATE_DATA))) { _stationControllerID = id; @@ -109,10 +93,22 @@ StationControllerInterface::StationControllerInterface(StationControllerKind id, // the .idl file. The profiles themselves are configured in the .xml file. // Look in the XML for more details on the definition of state data. - // Creating the application's ChocolateLotStateWriter object. - // This could use the RTI Connext DDS writer directly as a way to write. - // This DataWriter is configured with QoS for state data. - + _topicChocolateLotState = new Topic(_comm.Participant(), + CHOCOLATE_LOT_TOPIC, _comm.Qos().topic_qos(lotStateQosProfile)); + _cftChocolateLotState = new ContentFilteredTopic( + *_topicChocolateLotState, "ContentFilter", Filter( + "lotStatus = 'LOT_COMPLETED' OR nextController = %0", { + StationControllerType::ControllerEnumName(id) + }) + ); + _topicChocolateRecipe = new Topic(_comm.Participant(), + RECIPE_TOPIC, _comm.Qos().topic_qos(recipeQosProfile)); + _writerChocolateLotState = new DataWriter(_comm.Publisher(), + *_topicChocolateLotState, _comm.Qos().datawriter_qos(lotStateQosProfile)); + _readerChocolateLotState = new DataReader(_comm.Subscriber(), + *_cftChocolateLotState, _comm.Qos().datareader_qos(lotStateQosProfile)); + _readerRecipe = new DataReader(_comm.Subscriber(), + *_topicChocolateRecipe, _comm.Qos().datareader_qos(recipeQosProfile)); } // ------------------------------------------------------------------------- // @@ -126,7 +122,7 @@ ChocolateRecipe StationControllerInterface::GetRecipe(const string recipeName) { // Create a placeholder with only the key field filled in. This will be // used to retrieve the recipe instance (if it exists). - for (auto sample : _readerRecipe.read()) { + for (auto sample : _readerRecipe->read()) { if (recipeName == sample.data().recipeName()) return sample.data(); } diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp index c2e95043..9c8df584 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp @@ -109,7 +109,7 @@ class StationControllerInterface { // write data in RTI Connext DDS. dds::pub::DataWriter& WriterChocolateLotState() { - return _writerChocolateLotState; + return *_writerChocolateLotState; } // --- Getter for the ChocolateLotStateReader --- @@ -119,7 +119,7 @@ class StationControllerInterface { // state updates dds::sub::DataReader& ReaderChocolateLotState() { - return _readerChocolateLotState; + return *_readerChocolateLotState; } // --- Getter for the RecipeReader --- @@ -128,7 +128,7 @@ class StationControllerInterface { // DDS "WaitSet" object to wait for recipes dds::sub::DataReader& ReaderRecipe() { - return _readerRecipe; + return *_readerRecipe; } // --- Getter for Controller ID --- @@ -159,21 +159,21 @@ class StationControllerInterface { // Topic object used to define the datatype use by the ChocolateLotState // DataWriter - dds::topic::Topic& _topicChocolateLotState; + dds::topic::Topic* _topicChocolateLotState; // Topic object used to define the datatype use by the ChocolateLotState // DataReader - dds::topic::ContentFilteredTopic& _cftChocolateLotState; + dds::topic::ContentFilteredTopic* _cftChocolateLotState; // Topic object used for Chocolate Recipe reader - dds::topic::Topic& _topicChocolateRecipe; + dds::topic::Topic* _topicChocolateRecipe; // DataWriter object for ChocolateLotState - dds::pub::DataWriter& _writerChocolateLotState; + dds::pub::DataWriter* _writerChocolateLotState; // DataReader used for receiving chocolate lot state data - dds::sub::DataReader& _readerChocolateLotState; + dds::sub::DataReader* _readerChocolateLotState; // Used for receiving recipe data, and for looking up received recipes. - dds::sub::DataReader& _readerRecipe; + dds::sub::DataReader* _readerRecipe; }; #endif From df1660b3e767a6434f15e3f810e03847c9259d6f Mon Sep 17 00:00:00 2001 From: DanKing-RTI <81592978+DanKing-RTI@users.noreply.github.com> Date: Mon, 9 Aug 2021 12:55:43 -0400 Subject: [PATCH 05/14] Update CMakeLists.txt --- ChocolateFactory/ExampleCode/src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChocolateFactory/ExampleCode/src/CMakeLists.txt b/ChocolateFactory/ExampleCode/src/CMakeLists.txt index 1b626137..e6cfa342 100644 --- a/ChocolateFactory/ExampleCode/src/CMakeLists.txt +++ b/ChocolateFactory/ExampleCode/src/CMakeLists.txt @@ -9,7 +9,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake #Find the ConnextDDS libraries.This will look fo the core and API libraries #only find_package(RTIConnextDDS - "6.0.1" + "6.1.0" REQUIRED COMPONENTS core) From e19dbaabbc7a5b9f9cd62c8118262f04c37380be Mon Sep 17 00:00:00 2001 From: Dan King Date: Mon, 9 Aug 2021 14:12:44 -0400 Subject: [PATCH 06/14] added inlude for std::find (algorithm) --- .../ExampleCode/src/CommonInfrastructure/InputParser.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/InputParser.cxx b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/InputParser.cxx index ce89bcd6..a028478c 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/InputParser.cxx +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/InputParser.cxx @@ -12,6 +12,7 @@ */ #include "InputParser.hpp" +#include InputParser::InputParser(int& argc, char* argv[]) { for (int i = 1; i < argc; ++i) From 0c5977ba27745f3d548019d5680382f0121b7eb9 Mon Sep 17 00:00:00 2001 From: Dan King Date: Mon, 9 Aug 2021 14:22:07 -0400 Subject: [PATCH 07/14] fixed QoS profile string in DDSCommunicator initialization --- .../src/StationController/StationControllerInterface.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx index a0849393..b4bec4f5 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx @@ -83,8 +83,8 @@ using namespace dds::sub; StationControllerInterface::StationControllerInterface(StationControllerKind id, vector qosFileNames, string lotStateQosProfile, string recipeQosProfile) : - _comm(DDSCommunicator(qosFileNames, (QOS_LIBRARY + "::" + - QOS_PROFILE_STATE_DATA))) + _profile(QOS_PROFILE_STATE_DATA), + _comm(DDSCommunicator(qosFileNames, _profile)) { _stationControllerID = id; From 88d5b387064f4ae0300273f4b99833722f4536c8 Mon Sep 17 00:00:00 2001 From: Dan King Date: Mon, 9 Aug 2021 14:24:09 -0400 Subject: [PATCH 08/14] forgot to save all files --- .../src/StationController/StationControllerInterface.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp index 9c8df584..49885306 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp @@ -147,6 +147,8 @@ class StationControllerInterface { private: // --- Private members --- + std::string _profile; + // This contains the calls that allow the interface to create a // "DomainParticipant", the first object that must be created to // communicate over a DDS middleware. From 8af4d0d225697294fb264810106ee256fefe02fc Mon Sep 17 00:00:00 2001 From: Dan King Date: Mon, 9 Aug 2021 14:39:17 -0400 Subject: [PATCH 09/14] Changed DDSCommunicator objects to const objects within interfaces --- .../src/CommonInfrastructure/DDSCommunicator.cxx | 8 ++++---- .../src/CommonInfrastructure/DDSCommunicator.hpp | 8 ++++---- .../src/ManufacturingExecutionSystem/MESInterface.hpp | 2 +- .../src/RecipeGenerator/RecipePublisherInterface.hpp | 2 +- .../src/StationController/StationControllerInterface.hpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx index d0b83591..ba0e2024 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx @@ -117,21 +117,21 @@ DDSCommunicator::~DDSCommunicator() // ------------------------------------------------------------------------- // // Getters for QoS, Publisher, and Subscriber. -dds::core::QosProvider& DDSCommunicator::Qos() +dds::core::QosProvider& DDSCommunicator::Qos() const { return *_qos; } -dds::domain::DomainParticipant& DDSCommunicator::Participant() +dds::domain::DomainParticipant& DDSCommunicator::Participant() const { return *_participant; } -dds::pub::Publisher& DDSCommunicator::Publisher() +dds::pub::Publisher& DDSCommunicator::Publisher() const { return *_pub; } -dds::sub::Subscriber& DDSCommunicator::Subscriber() +dds::sub::Subscriber& DDSCommunicator::Subscriber() const { return *_sub; } diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp index 7902362e..dabe6ef8 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp @@ -52,10 +52,10 @@ class DDSCommunicator { // to pull the QoS, Publisher, and Subscriber to create DataReaders and // DataWriters - dds::core::QosProvider& Qos(); - dds::domain::DomainParticipant& Participant(); - dds::pub::Publisher& Publisher(); - dds::sub::Subscriber& Subscriber(); + dds::core::QosProvider& Qos() const; + dds::domain::DomainParticipant& Participant() const; + dds::pub::Publisher& Publisher() const; + dds::sub::Subscriber& Subscriber() const; private: // --- Protected members --- diff --git a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp index d957f733..8adf9796 100644 --- a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp @@ -83,7 +83,7 @@ class MESInterface { // This contains the calls that allow the interface to create a // "DomainParticipant", the first object that must be created to // communicate over a DDS middleware. - DDSCommunicator& _communicator; + const DDSCommunicator& _communicator; // Topic object used to define the datatype use by the ChocolateLotState // DataReader and DataWriter diff --git a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp index e8e5be08..ae7c5253 100644 --- a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp @@ -62,7 +62,7 @@ class RecipePublisherInterface { // --- Private members --- // Used to create basic DDS entities that all applications need - DDSCommunicator& _communicator; + const DDSCommunicator& _communicator; // Topic object used by writer dds::topic::Topic* _topic; diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp index 49885306..bd79889d 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp @@ -152,7 +152,7 @@ class StationControllerInterface { // This contains the calls that allow the interface to create a // "DomainParticipant", the first object that must be created to // communicate over a DDS middleware. - DDSCommunicator& _comm; + const DDSCommunicator& _comm; // If this is a controller, this filed is used to identify which station // controller this is, and what part of the recipe it is responsible for. From ad255ceed1d44ee1f2fb30e3de699e5a618036f7 Mon Sep 17 00:00:00 2001 From: Dan King Date: Mon, 9 Aug 2021 14:41:55 -0400 Subject: [PATCH 10/14] added return to GetRecipe function for NULL case. --- .../src/StationController/StationControllerInterface.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx index b4bec4f5..c2272e54 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx @@ -126,4 +126,6 @@ ChocolateRecipe StationControllerInterface::GetRecipe(const string recipeName) if (recipeName == sample.data().recipeName()) return sample.data(); } + + return ChocolateRecipe(); } From ad835a49907cc10b0519a943bd5250bba6f9394b Mon Sep 17 00:00:00 2001 From: Dan King Date: Mon, 16 Aug 2021 11:15:28 -0400 Subject: [PATCH 11/14] Updated classes to remove topics as class members --- .../MESInterface.cxx | 17 ++++----- .../MESInterface.hpp | 10 ++---- .../RecipePublisherInterface.cxx | 9 ++--- .../RecipePublisherInterface.hpp | 6 ++-- .../StationController/StationController.cxx | 2 +- .../StationControllerInterface.cxx | 25 ++++++------- .../StationControllerInterface.hpp | 35 +------------------ 7 files changed, 31 insertions(+), 73 deletions(-) diff --git a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx index 834d22ac..28733280 100644 --- a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx @@ -14,6 +14,7 @@ #include "MESInterface.hpp" using namespace com::chocolatefactory::generated; +using namespace std; // ------------------------------------------------------------------------- // // The MESInterface is the network interface to the whole Manufacturing @@ -70,8 +71,7 @@ using namespace com::chocolatefactory::generated; // ------------------------------------------------------------------------- // MESInterface::MESInterface(std::vector& qosFileNames) : - _profile(QOS_PROFILE_STATE_DATA), - _communicator(DDSCommunicator(qosFileNames, _profile)) + _communicator(DDSCommunicator(qosFileNames, string(QOS_PROFILE_STATE_DATA))) { // Note: all data in this example is "state data." The string constants // with the QoS library name and the QoS profile name are configured as @@ -79,15 +79,16 @@ MESInterface::MESInterface(std::vector& qosFileNames) : // the .xml file. Look in the XML for more details on the definition of // state data. - _topicChocolateLotState = new dds::topic::Topic( + auto topicChocolateLotState = dds::topic::Topic( _communicator.Participant(), CHOCOLATE_LOT_TOPIC, - _communicator.Qos().topic_qos(_profile)); + _communicator.Qos().topic_qos(QOS_PROFILE_STATE_DATA)); + _writerChocolateLotState = new dds::pub::DataWriter( - _communicator.Publisher(), *_topicChocolateLotState, - _communicator.Qos().datawriter_qos(_profile)); + _communicator.Publisher(), topicChocolateLotState, + _communicator.Qos().datawriter_qos(QOS_PROFILE_STATE_DATA)); _readerChocolateLotState = new dds::sub::DataReader( - _communicator.Subscriber(), *_topicChocolateLotState, - _communicator.Qos().datareader_qos(_profile)); + _communicator.Subscriber(), topicChocolateLotState, + _communicator.Qos().datareader_qos(QOS_PROFILE_STATE_DATA)); } // ------------------------------------------------------------------------- // diff --git a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp index 8adf9796..b8378267 100644 --- a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp @@ -17,6 +17,7 @@ the software. #include "../CommonInfrastructure/DDSCommunicator.hpp" using namespace com::chocolatefactory::generated; +using namespace std; // ---------------------------------------------------------------------------- // @@ -50,7 +51,7 @@ class MESInterface { // DomainParticipant, creating all publishers and subscribers, topics // writers and readers. Takes as input a vector of xml QoS files that // should be loaded to find QoS profiles and libraries. - MESInterface(std::vector& xmlFiles); + MESInterface(vector& xmlFiles); // --- Destructor --- ~MESInterface(); @@ -77,18 +78,11 @@ class MESInterface { private: // --- Private members --- - // Stores profile based on elements from IDL file - std::string _profile; - // This contains the calls that allow the interface to create a // "DomainParticipant", the first object that must be created to // communicate over a DDS middleware. const DDSCommunicator& _communicator; - // Topic object used to define the datatype use by the ChocolateLotState - // DataReader and DataWriter - dds::topic::Topic* _topicChocolateLotState; - // DataWriter object for ChocolateLotState dds::pub::DataWriter* _writerChocolateLotState; diff --git a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx index 7566ab60..1709b1e0 100644 --- a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx @@ -14,6 +14,7 @@ #include "RecipePublisherInterface.hpp" using namespace com::chocolatefactory::generated; +using namespace std; // ---------------------------------------------------------------------------- // The RecipePublisherInterface is the network interface to the whole @@ -44,8 +45,7 @@ using namespace com::chocolatefactory::generated; // file. // ------------------------------------------------------------------------- // -RecipePublisherInterface::RecipePublisherInterface( - std::vector& xmlFiles) : +RecipePublisherInterface::RecipePublisherInterface(vector& xmlFiles) : _communicator(DDSCommunicator(xmlFiles)) { // Note: all data in this example is "state data." The string constants @@ -54,10 +54,11 @@ RecipePublisherInterface::RecipePublisherInterface( // the .xml file. Look in the XML for more details on the definition of // state data. - _topic = new dds::topic::Topic(_communicator.Participant(), + auto topic = dds::topic::Topic(_communicator.Participant(), RECIPE_TOPIC, _communicator.Qos().topic_qos()); + _writer = new dds::pub::DataWriter(_communicator.Publisher(), - *_topic, _communicator.Qos().datawriter_qos()); + topic, _communicator.Qos().datawriter_qos()); } // ---------------------------------------------------------------------------- diff --git a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp index ae7c5253..14d01655 100644 --- a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp @@ -19,6 +19,7 @@ #include "../Generated/ChocolateFactory.hpp" using namespace com::chocolatefactory::generated; +using namespace std; // ---------------------------------------------------------------------------- // @@ -46,7 +47,7 @@ class RecipePublisherInterface { // DomainParticipant, creating all publishers and subscribers, topics // writers and readers. Takes as input a vector of xml QoS files that // should be loaded to find QoS profiles and libraries. - RecipePublisherInterface(std::vector& xmlFiles); + RecipePublisherInterface(vector& xmlFiles); // --- Destructor --- ~RecipePublisherInterface(); @@ -64,9 +65,6 @@ class RecipePublisherInterface { // Used to create basic DDS entities that all applications need const DDSCommunicator& _communicator; - // Topic object used by writer - dds::topic::Topic* _topic; - // Recipe publisher specific to this application dds::pub::DataWriter* _writer; }; diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationController.cxx b/ChocolateFactory/ExampleCode/src/StationController/StationController.cxx index a77f8681..29c26d52 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationController.cxx +++ b/ChocolateFactory/ExampleCode/src/StationController/StationController.cxx @@ -119,7 +119,7 @@ int main(int argc, char* argv[]) // the network StationControllerInterface stationControllerInterface( (StationControllerKind) controllerType, - xmlFiles, QOS_PROFILE_STATE_DATA, QOS_PROFILE_STATE_DATA); + xmlFiles, QOS_PROFILE_STATE_DATA); // Create a new Station Controller object. StationController controller((StationControllerKind) controllerType, diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx index c2272e54..217d13b0 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx @@ -81,34 +81,31 @@ using namespace dds::sub; // ------------------------------------------------------------------------- // StationControllerInterface::StationControllerInterface(StationControllerKind id, - vector qosFileNames, string lotStateQosProfile, - string recipeQosProfile) : - _profile(QOS_PROFILE_STATE_DATA), - _comm(DDSCommunicator(qosFileNames, _profile)) + vector qosFileNames, string lotStateQosProfile) : + _comm(DDSCommunicator(qosFileNames, string(QOS_PROFILE_STATE_DATA))) { - _stationControllerID = id; - // All data in this example is "state data." The string constants with the // QoS library name and the QoS profile name are configured as constants in // the .idl file. The profiles themselves are configured in the .xml file. // Look in the XML for more details on the definition of state data. - _topicChocolateLotState = new Topic(_comm.Participant(), + auto topicChocolateLotState = Topic(_comm.Participant(), CHOCOLATE_LOT_TOPIC, _comm.Qos().topic_qos(lotStateQosProfile)); - _cftChocolateLotState = new ContentFilteredTopic( - *_topicChocolateLotState, "ContentFilter", Filter( + auto cftChocolateLotState = ContentFilteredTopic( + topicChocolateLotState, "ContentFilter", Filter( "lotStatus = 'LOT_COMPLETED' OR nextController = %0", { StationControllerType::ControllerEnumName(id) }) ); - _topicChocolateRecipe = new Topic(_comm.Participant(), - RECIPE_TOPIC, _comm.Qos().topic_qos(recipeQosProfile)); + auto topicChocolateRecipe = Topic(_comm.Participant(), + RECIPE_TOPIC, _comm.Qos().topic_qos()); + _writerChocolateLotState = new DataWriter(_comm.Publisher(), - *_topicChocolateLotState, _comm.Qos().datawriter_qos(lotStateQosProfile)); + topicChocolateLotState, _comm.Qos().datawriter_qos(lotStateQosProfile)); _readerChocolateLotState = new DataReader(_comm.Subscriber(), - *_cftChocolateLotState, _comm.Qos().datareader_qos(lotStateQosProfile)); + cftChocolateLotState, _comm.Qos().datareader_qos(lotStateQosProfile)); _readerRecipe = new DataReader(_comm.Subscriber(), - *_topicChocolateRecipe, _comm.Qos().datareader_qos(recipeQosProfile)); + topicChocolateRecipe, _comm.Qos().datareader_qos()); } // ------------------------------------------------------------------------- // diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp index bd79889d..fb048d83 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp @@ -96,8 +96,7 @@ class StationControllerInterface { // --- Constructor --- StationControllerInterface(StationControllerKind stationControllerID, - vector qosFileNames, string lotStateQosProfile, - string recipeQosProfile); + vector qosFileNames, string lotStateQosProfile); // --- Destructor --- virtual ~StationControllerInterface(); @@ -122,22 +121,6 @@ class StationControllerInterface { return *_readerChocolateLotState; } - // --- Getter for the RecipeReader --- - // This returns the Chocolate recipe reader - a small wrapper around the - // ChocolateRecipeDataReader that initializes the reader and uses the - // DDS "WaitSet" object to wait for recipes - dds::sub::DataReader& ReaderRecipe() - { - return *_readerRecipe; - } - - // --- Getter for Controller ID --- - // Accessor for the controller ID - const StationControllerKind StationControllerID() - { - return _stationControllerID; - } - // --- Retrieve recipes --- // This example receives all recipes, and leaves them in the middleware's // queue. It queries for a particular recipe when it receives an update @@ -147,27 +130,11 @@ class StationControllerInterface { private: // --- Private members --- - std::string _profile; - // This contains the calls that allow the interface to create a // "DomainParticipant", the first object that must be created to // communicate over a DDS middleware. const DDSCommunicator& _comm; - // If this is a controller, this filed is used to identify which station - // controller this is, and what part of the recipe it is responsible for. - // If this is not a station controller, this is set to invalid - StationControllerKind _stationControllerID; - - // Topic object used to define the datatype use by the ChocolateLotState - // DataWriter - dds::topic::Topic* _topicChocolateLotState; - // Topic object used to define the datatype use by the ChocolateLotState - // DataReader - dds::topic::ContentFilteredTopic* _cftChocolateLotState; - // Topic object used for Chocolate Recipe reader - dds::topic::Topic* _topicChocolateRecipe; - // DataWriter object for ChocolateLotState dds::pub::DataWriter* _writerChocolateLotState; From c12f7842444114d447184e672691ebb1c78437fb Mon Sep 17 00:00:00 2001 From: DanKing-RTI Date: Mon, 16 Aug 2021 11:21:42 -0400 Subject: [PATCH 12/14] Updated DDSCommunicator class to be able to reference class constants in constructor --- .../src/CommonInfrastructure/DDSCommunicator.cxx | 10 +++++----- .../src/CommonInfrastructure/DDSCommunicator.hpp | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx index ba0e2024..0905259b 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx @@ -58,21 +58,21 @@ DDSCommunicator::DDSCommunicator() _sub = new dds::sub::Subscriber(*_participant); } DDSCommunicator::DDSCommunicator(std::string& qosFile) -{ +{ _qos = new dds::core::QosProvider(qosFile); _participant = new dds::domain::DomainParticipant(0, _qos->participant_qos()); _pub = new dds::pub::Publisher(*_participant, _qos->publisher_qos()); _sub = new dds::sub::Subscriber(*_participant, _qos->subscriber_qos()); } -DDSCommunicator::DDSCommunicator(std::string& qosFile, std::string& profile) -{ +DDSCommunicator::DDSCommunicator(std::string& qosFile, std::string profile) +{ _qos = new dds::core::QosProvider(qosFile, profile); _participant = new dds::domain::DomainParticipant(0, _qos->participant_qos(profile)); _pub = new dds::pub::Publisher(*_participant, _qos->publisher_qos(profile)); _sub = new dds::sub::Subscriber(*_participant, _qos->subscriber_qos(profile)); } DDSCommunicator::DDSCommunicator(dds::core::StringSeq& qosFiles) -{ +{ ostringstream fileString; if (!qosFiles.empty()) { copy(qosFiles.begin(), qosFiles.end() - 1, ostream_iterator(fileString, "; ")); @@ -84,7 +84,7 @@ DDSCommunicator::DDSCommunicator(dds::core::StringSeq& qosFiles) _pub = new dds::pub::Publisher(*_participant, _qos->publisher_qos()); _sub = new dds::sub::Subscriber(*_participant, _qos->subscriber_qos()); } -DDSCommunicator::DDSCommunicator(std::vector& qosFiles, std::string& profile) +DDSCommunicator::DDSCommunicator(std::vector& qosFiles, std::string profile) { ostringstream fileString; if (!qosFiles.empty()) { diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp index dabe6ef8..c4d759b8 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp @@ -40,9 +40,9 @@ class DDSCommunicator { // --- Constructor and Destructor --- DDSCommunicator(); DDSCommunicator(std::string& qosFile); - DDSCommunicator(std::string& qosFiles, std::string& profile); + DDSCommunicator(std::string& qosFiles, std::string profile); DDSCommunicator(dds::core::StringSeq& qosFiles); - DDSCommunicator(std::vector& qosFiles, std::string& profile); + DDSCommunicator(std::vector& qosFiles, std::string profile); ~DDSCommunicator(); From 4928473f40e46547c389223be854a8a968ed13ee Mon Sep 17 00:00:00 2001 From: Dan King Date: Tue, 24 Aug 2021 13:04:47 -0400 Subject: [PATCH 13/14] Removed superfluous code --- .../ChocolateLotStateEntities.cxx | 186 ------------------ .../ChocolateLotStateEntities.hpp | 121 ------------ .../CommonInfrastructure/DDSCommunicator.cxx | 8 +- 3 files changed, 1 insertion(+), 314 deletions(-) delete mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.cxx delete mode 100644 ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.hpp diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.cxx b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.cxx deleted file mode 100644 index af5902d8..00000000 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.cxx +++ /dev/null @@ -1,186 +0,0 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative -works of the Software. Licensee has the right to distribute object form only -for use with RTI products. The Software is provided as is, with no warranty -of any type, including any warranty for fitness for any purpose. RTI is under no -obligation to maintain or support the Software. RTI shall not be liable for any -incidental or consequential damages arising out of the use or inability to use -the software. -**********************************************************************************************/ -#include "ChocolateLotStateEntities.hpp" -#include "EnumPrintHelpers.hpp" - -using namespace com::chocolatefactory::generated; -using namespace dds::topic; -using namespace dds::pub; -using namespace dds::sub; - -// ------------------------------------------------------------------------- // -// Constructors for the ChocolateLotStateCommon base class. The topic object is -// the description of the data that you will be sending. It associates a -// particular data type with a name that describes the meaning of the data. -// Along with the data types, and whether your application is reading or -// writing particular data, this is the data interface of your application. - -// This topic has the name CHOCOLATE_LOT_TOPIC - a constant string that is -// defined in the .idl file. (It is not required that you define your topic -// name in IDL, but it is a best practice for ensuring the data interface of -// an application is all defined in one place.) Generally you can register all -// topics and types up-front if necessary. - -// This can be done at any time before creating the DataWriters and -// DataReaders. In some systems, this is done in a separate initialization all -// at once - especially in applications that read and write the same topic. -ChocolateLotStateCommon::ChocolateLotStateCommon(DDSCommunicator& comm) : - _topic(dds::topic::Topic(comm.Participant(), CHOCOLATE_LOT_TOPIC)) -{} -ChocolateLotStateCommon::ChocolateLotStateCommon(DDSCommunicator& comm, - const std::string& profile) : - _topic(dds::topic::Topic(comm.Participant(), - CHOCOLATE_LOT_TOPIC, comm.Qos().topic_qos(profile))) -{} - -// Accessor for the private Topic data -const dds::topic::Topic& ChocolateLotStateCommon::Topic() -{ - return _topic; -} - -// ------------------------------------------------------------------------- // -// Create the ChocolateLotState DataWriter. This uses the -// DDSCommunicator's DomainParticipant object to create a -// DataWriter and Topic. -ChocolateLotStateWriter::ChocolateLotStateWriter(DDSCommunicator& comm, - const std::string& profile) : - ChocolateLotStateCommon(comm, profile), - _writer(CreateWriter(comm, profile)) -{ -} - -// ------------------------------------------------------------------------- // -// Destructor for the ChocolateLotStateWriter -ChocolateLotStateWriter::~ChocolateLotStateWriter() -{ -} - -dds::pub::DataWriter& ChocolateLotStateWriter::CreateWriter( - DDSCommunicator& comm, const std::string& profile) -{ - // Create a DataWriter The topic object is the description of the data that - // you will be sending. It associates a particular data type with a name - // that describes the meaning of the data. Along with the data types, and - // whether your application is reading or writing particular data, this is - // the data interface of your application. - - // This topic has the name CHOCOLATE_LOT_TOPIC - a constant string that was - // defined in the .idl file. (It is not required that you define your topic - // name in IDL, but it is a best practice for ensuring the data interface of - // an application is all defined in one place. Generally you can register - // all topics and types up-front if necessary. - - // Use QoS loaded from the XML file - - // Create the DDS DataWriter object that sends data over the network (or - // shared memory) - - auto writer = rti::pub::find_datawriter_by_topic_name - >(comm.Publisher(), CHOCOLATE_LOT_TOPIC); - - if (writer == dds::core::null) - return DataWriter( - comm.Publisher(), Topic(), comm.Qos().datawriter_qos(profile)); - else - return writer; -} - -// ------------------------------------------------------------------------- // -// Write the data into the DDS "cloud" - in other words, write the data, -// within the numbered domain that the DomainParticipant was created with, -// to whichever DataReaders of the same topic were discovered over the -// available transports. -void ChocolateLotStateWriter::PublishChocolateLotState(const ChocolateLotState& lotState) -{ - _writer.write(lotState); -} - -// ------------------------------------------------------------------------- // -// Unregisters the lot state published by this station controller. This says -// that this station controller no longer wants to provide an update to the -// state of a particular lot. -// (The application calls this when a lot has completed all stages of -// processing so there is no need for a station controller to continue to -// provide its processing state for that lot). -void ChocolateLotStateWriter::UnregisterChocolateLotState(const ChocolateLotState& lotState) -{ - auto handle = dds::core::InstanceHandle::nil(); - - // Retrieve the handle of the instance we were disposing - handle = _writer.lookup_instance(lotState); - - // Note that DDS has two ways to indicate that an instance has gone away - // it can unregister the instance or dispose it. Also, by default when - // the DataWriter unregisters an instance, it also disposes it. If you - // dispose and instance, the memory for the instance is not cleaned up, - // with the expectation that it will be reused. - // In this case, the next station controller in the factory will start - // writing the lot state for this lot instance. We don't want to dispose - // that lot, but only unregister it. - _writer.unregister_instance(handle); -} - -// ------------------------------------------------------------------------- // -// This creates the DDS DataReader that receives updates about chocolate lots. -ChocolateLotStateReader::ChocolateLotStateReader(DDSCommunicator& comm, - const std::string& profile, const StationControllerKind kind) : - ChocolateLotStateCommon(comm, profile), - _reader(CreateReader(comm, profile, kind)) -{ } - -// ------------------------------------------------------------------------- // -// Destory the chocolate lot DataReader and WaitSet. -ChocolateLotStateReader::~ChocolateLotStateReader() -{ } - -// Create the DataReader -// -// If this ChocolateLotStateReader is receiving data for a real station -// controller, it filters data so it receives data only for that controller If -// it is being used by another object such as the MES, it does not filter, so -// all ChocolateLotState updates are received by the DataReader. This DataReader -// will receive the chocolate lot, and will store that data in the middleware's -// queue to be queried by the application Note that if this DataReader belongs -// to a particular StationController type, it will filter to only receive -// updates for that station controller. If it belongs to a non-station -// controller it does not filter. -dds::sub::DataReader& ChocolateLotStateReader::CreateReader( - DDSCommunicator& comm, const std::string& profile, const StationControllerKind kind) -{ - // Get the QoS profile from the QoS Provider - auto qos = comm.Qos().datareader_qos(profile); - - if (kind != StationControllerKind::INVALID_CONTROLLER) { - // Static helper method that converts an enumeration into the string - // that represents that enumeration - std::vector parameters = { StationControllerType::ControllerEnumName(kind) }; - - // Filter to receive updates if: 1) This is assigned to me or 2) this - // lot is in state LOT_COMPLETED (at which point I unregister the - // instance) Note: The _parameters StringSeq will delete this - // char * when the ChocolateLotStateReader class is deleted, so must - // duplicate the string using DDS::String_dup. - auto cft = ContentFilteredTopic - (Topic(), "ContentFilter", - Filter("lotStatus = 'LOT_COMPLETED' OR nextController = %0", parameters)); - - return DataReader(comm.Subscriber(), cft, qos); - } - else { - return DataReader(comm.Subscriber(), Topic(), qos); - } -} - -const dds::sub::DataReader& ChocolateLotStateReader::Reader() -{ - return _reader; -} \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.hpp b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.hpp deleted file mode 100644 index ef19e6a9..00000000 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/ChocolateLotStateEntities.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/********************************************************************************************* -(c) 2005-2013 Copyright, Real-Time Innovations, Inc. All rights reserved. -RTI grants Licensee a license to use, modify, compile, and create derivative -works of the Software. Licensee has the right to distribute object form only -for use with RTI products. The Software is provided as is, with no warranty -of any type, including any warranty for fitness for any purpose. RTI is under no -obligation to maintain or support the Software. RTI shall not be liable for any -incidental or consequential damages arising out of the use or inability to use -the software. -**********************************************************************************************/ - -#ifndef CHOCOLATE_LOT_STATE_ENTITIES_H -#define CHOCOLATE_LOT_STATE_ENTITIES_H - -#include -#include "DDSCommunicator.hpp" -#include "../Generated/ChocolateFactory.hpp" - -using namespace com::chocolatefactory::generated; - -// ------------------------------------------------------------------------- // -// -// ChocolateLotStateCommon: -// Used for dealing with the chocolate lot state. This encapsulates the topic -// used for DataReaders and DataWriters of the state data. -// -// ------------------------------------------------------------------------- // -class ChocolateLotStateCommon { -protected: - // --- Constructors --- - // Default constructor that creates the topic from the default profile - // provided by the DDSCommunicator object - ChocolateLotStateCommon(DDSCommunicator& comm); - // Constructor that creates the topic from the specified profile - ChocolateLotStateCommon(DDSCommunicator& comm, const std::string& profile); - - // --- Accessors --- - // Accessor for the topic data created in initialization - const dds::topic::Topic& Topic(); - -private: - dds::topic::Topic& _topic; -}; - -// ------------------------------------------------------------------------- // -// -// ChocolateLotStateReader: -// Used for receiving the chocolate lot state. This encapsulates the concepts -// of a DDS type-specific DataReader (for type ChocolateLotState), along with -// the mechanisms for accessing data - in this case, this allows the -// application to block one of its threads to wait for data from the -// ChocolateLotStateReader. -// -// ------------------------------------------------------------------------- // -class ChocolateLotStateReader : ChocolateLotStateCommon { -public: - // --- Constructor --- - // This creates a DDS DataReader that subscribes to chocolate lot - // information. This uses the app object to access the DomainParticipant, - // and it uses the QoS profiles specified when creating the DataReader. The - // XML QoS files were previously configured when the - // StationControllerInterface's DDSCommunicator was created. - ChocolateLotStateReader(DDSCommunicator& comm, const std::string& profile, - const StationControllerKind kind); - - // --- Destructor --- - ~ChocolateLotStateReader(); - - const dds::sub::DataReader& Reader(); - -private: - // --- Private methods --- - - // Create reader - dds::sub::DataReader& CreateReader(DDSCommunicator& comm, - const std::string& profile, const StationControllerKind kind); - - // --- Private members --- - - // Application-specific DDS DataReader for receiving chocolate lot state - // data - dds::sub::DataReader& _reader; -}; - -// ------------------------------------------------------------------------- // -// -// ChocolateLotStateWriter: -// This class is used to create a write chocolate lot data over the network. -// -class ChocolateLotStateWriter : ChocolateLotStateCommon { -public: - // --- Constructor --- - // This creates a DDS DataWriter that publishes the chocolate lot state - ChocolateLotStateWriter(DDSCommunicator& comm, const std::string& profile); - - // --- Destructor --- - ~ChocolateLotStateWriter(); - - // --- Sends the Chocolate Lot State --- - // Uses DDS interface to send a chocolate lot state update over the network - // or shared memory to interested applications subscribing to chocolate - // lot state information. - void PublishChocolateLotState(const ChocolateLotState& lotState); - - // --- Unregisters the lot state --- - // When this application sees that the chocolate lot is finished, it - // unregisters the lot state - void UnregisterChocolateLotState(const ChocolateLotState& lotState); - -private: - dds::pub::DataWriter& CreateWriter( - DDSCommunicator& comm, const std::string& profile); - - // --- Private members --- - - // The application-specific DDS DataWriter that sends chocolate lot state - // updates over the network or shared memory - dds::pub::DataWriter& _writer; -}; - -#endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx index 0905259b..d11781ee 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx @@ -107,13 +107,7 @@ DDSCommunicator::DDSCommunicator(std::vector& qosFiles, std::string // all types are not unregistered. Thirdly, this deletes the // DomainParticipant. Lastly, this finalizes the DomainParticipantFactory. DDSCommunicator::~DDSCommunicator() -{ - if (_participant != dds::core::null) { - // RTI Connext provides a finalize_participant_factory() method if you - // want to release memory used by the participant factory singleton. - _participant->finalize_participant_factory(); - } -} +{ } // ------------------------------------------------------------------------- // // Getters for QoS, Publisher, and Subscriber. From cd793a3e3f69d7dc029bcabffaa1fcfbdde18ebb Mon Sep 17 00:00:00 2001 From: Dan King Date: Tue, 21 Sep 2021 12:12:58 -0400 Subject: [PATCH 14/14] Updating code for style considerations --- .../CommonInfrastructure/DDSCommunicator.cxx | 50 +++++++++---------- .../CommonInfrastructure/DDSCommunicator.hpp | 15 +++--- .../MESInterface.cxx | 18 +++---- .../MESInterface.hpp | 10 ++-- .../RecipePublisherInterface.cxx | 14 +++--- .../RecipePublisherInterface.hpp | 6 +-- .../StationController/StationController.hpp | 4 +- .../StationControllerInterface.cxx | 28 +++++------ .../StationControllerInterface.hpp | 16 +++--- 9 files changed, 81 insertions(+), 80 deletions(-) diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx index d11781ee..ad0aa051 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.cxx @@ -50,26 +50,26 @@ using namespace std; // ------------------------------------------------------------------------- // DDSCommunicator::DDSCommunicator() { - _qos = new dds::core::QosProvider(dds::core::null); - *_qos = dds::core::QosProvider::Default(); + qos_ = new dds::core::QosProvider(dds::core::null); + *qos_ = dds::core::QosProvider::Default(); - _participant = new dds::domain::DomainParticipant(0); - _pub = new dds::pub::Publisher(*_participant); - _sub = new dds::sub::Subscriber(*_participant); + participant_ = new dds::domain::DomainParticipant(0); + pub_ = new dds::pub::Publisher(*participant_); + sub_ = new dds::sub::Subscriber(*participant_); } DDSCommunicator::DDSCommunicator(std::string& qosFile) { - _qos = new dds::core::QosProvider(qosFile); - _participant = new dds::domain::DomainParticipant(0, _qos->participant_qos()); - _pub = new dds::pub::Publisher(*_participant, _qos->publisher_qos()); - _sub = new dds::sub::Subscriber(*_participant, _qos->subscriber_qos()); + qos_ = new dds::core::QosProvider(qosFile); + participant_ = new dds::domain::DomainParticipant(0, qos_->participant_qos()); + pub_ = new dds::pub::Publisher(*participant_, qos_->publisher_qos()); + sub_ = new dds::sub::Subscriber(*participant_, qos_->subscriber_qos()); } DDSCommunicator::DDSCommunicator(std::string& qosFile, std::string profile) { - _qos = new dds::core::QosProvider(qosFile, profile); - _participant = new dds::domain::DomainParticipant(0, _qos->participant_qos(profile)); - _pub = new dds::pub::Publisher(*_participant, _qos->publisher_qos(profile)); - _sub = new dds::sub::Subscriber(*_participant, _qos->subscriber_qos(profile)); + qos_ = new dds::core::QosProvider(qosFile, profile); + participant_ = new dds::domain::DomainParticipant(0, qos_->participant_qos(profile)); + pub_ = new dds::pub::Publisher(*participant_, qos_->publisher_qos(profile)); + sub_ = new dds::sub::Subscriber(*participant_, qos_->subscriber_qos(profile)); } DDSCommunicator::DDSCommunicator(dds::core::StringSeq& qosFiles) { @@ -79,10 +79,10 @@ DDSCommunicator::DDSCommunicator(dds::core::StringSeq& qosFiles) fileString << qosFiles.back(); } - _qos = new dds::core::QosProvider(fileString.str()); - _participant = new dds::domain::DomainParticipant(0, _qos->participant_qos()); - _pub = new dds::pub::Publisher(*_participant, _qos->publisher_qos()); - _sub = new dds::sub::Subscriber(*_participant, _qos->subscriber_qos()); + qos_ = new dds::core::QosProvider(fileString.str()); + participant_ = new dds::domain::DomainParticipant(0, qos_->participant_qos()); + pub_ = new dds::pub::Publisher(*participant_, qos_->publisher_qos()); + sub_ = new dds::sub::Subscriber(*participant_, qos_->subscriber_qos()); } DDSCommunicator::DDSCommunicator(std::vector& qosFiles, std::string profile) { @@ -92,10 +92,10 @@ DDSCommunicator::DDSCommunicator(std::vector& qosFiles, std::string fileString << qosFiles.back(); } - _qos = new dds::core::QosProvider(fileString.str()); - _participant = new dds::domain::DomainParticipant(0, _qos->participant_qos(profile)); - _pub = new dds::pub::Publisher(*_participant, _qos->publisher_qos(profile)); - _sub = new dds::sub::Subscriber(*_participant, _qos->subscriber_qos(profile)); + qos_ = new dds::core::QosProvider(fileString.str()); + participant_ = new dds::domain::DomainParticipant(0, qos_->participant_qos(profile)); + pub_ = new dds::pub::Publisher(*participant_, qos_->publisher_qos(profile)); + sub_ = new dds::sub::Subscriber(*participant_, qos_->subscriber_qos(profile)); } @@ -113,19 +113,19 @@ DDSCommunicator::~DDSCommunicator() // Getters for QoS, Publisher, and Subscriber. dds::core::QosProvider& DDSCommunicator::Qos() const { - return *_qos; + return *qos_; } dds::domain::DomainParticipant& DDSCommunicator::Participant() const { - return *_participant; + return *participant_; } dds::pub::Publisher& DDSCommunicator::Publisher() const { - return *_pub; + return *pub_; } dds::sub::Subscriber& DDSCommunicator::Subscriber() const { - return *_sub; + return *sub_; } diff --git a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp index c4d759b8..747000a0 100644 --- a/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp +++ b/ChocolateFactory/ExampleCode/src/CommonInfrastructure/DDSCommunicator.hpp @@ -27,6 +27,7 @@ #include +using namespace std; // ------------------------------------------------------------------------- // // // DDSCommunicator: @@ -39,10 +40,10 @@ class DDSCommunicator { public: // --- Constructor and Destructor --- DDSCommunicator(); - DDSCommunicator(std::string& qosFile); - DDSCommunicator(std::string& qosFiles, std::string profile); + DDSCommunicator(string& qosFile); + DDSCommunicator(string& qosFiles, string profile); DDSCommunicator(dds::core::StringSeq& qosFiles); - DDSCommunicator(std::vector& qosFiles, std::string profile); + DDSCommunicator(vector& qosFiles, string profile); ~DDSCommunicator(); @@ -61,16 +62,16 @@ class DDSCommunicator { // --- Protected members --- // Used to create a QOS Provider to be used by other elements - dds::core::QosProvider* _qos; + dds::core::QosProvider* qos_; // Used to create other DDS entities - dds::domain::DomainParticipant* _participant; + dds::domain::DomainParticipant* participant_; // Used to create DataWriters - dds::pub::Publisher* _pub; + dds::pub::Publisher* pub_; // Used to create DataReaders - dds::sub::Subscriber* _sub; + dds::sub::Subscriber* sub_; }; diff --git a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx index 28733280..7fcd3025 100644 --- a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.cxx @@ -71,7 +71,7 @@ using namespace std; // ------------------------------------------------------------------------- // MESInterface::MESInterface(std::vector& qosFileNames) : - _communicator(DDSCommunicator(qosFileNames, string(QOS_PROFILE_STATE_DATA))) + communicator_(DDSCommunicator(qosFileNames, string(QOS_PROFILE_STATE_DATA))) { // Note: all data in this example is "state data." The string constants // with the QoS library name and the QoS profile name are configured as @@ -80,15 +80,15 @@ MESInterface::MESInterface(std::vector& qosFileNames) : // state data. auto topicChocolateLotState = dds::topic::Topic( - _communicator.Participant(), CHOCOLATE_LOT_TOPIC, - _communicator.Qos().topic_qos(QOS_PROFILE_STATE_DATA)); + communicator_.Participant(), CHOCOLATE_LOT_TOPIC, + communicator_.Qos().topic_qos(QOS_PROFILE_STATE_DATA)); - _writerChocolateLotState = new dds::pub::DataWriter( - _communicator.Publisher(), topicChocolateLotState, - _communicator.Qos().datawriter_qos(QOS_PROFILE_STATE_DATA)); - _readerChocolateLotState = new dds::sub::DataReader( - _communicator.Subscriber(), topicChocolateLotState, - _communicator.Qos().datareader_qos(QOS_PROFILE_STATE_DATA)); + writerChocolateLotState_ = new dds::pub::DataWriter( + communicator_.Publisher(), topicChocolateLotState, + communicator_.Qos().datawriter_qos(QOS_PROFILE_STATE_DATA)); + readerChocolateLotState_ = new dds::sub::DataReader( + communicator_.Subscriber(), topicChocolateLotState, + communicator_.Qos().datareader_qos(QOS_PROFILE_STATE_DATA)); } // ------------------------------------------------------------------------- // diff --git a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp index b8378267..85e350b7 100644 --- a/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/ManufacturingExecutionSystem/MESInterface.hpp @@ -62,7 +62,7 @@ class MESInterface { // the network. dds::pub::DataWriter& WriterChocolateLotState() { - return *_writerChocolateLotState; + return *writerChocolateLotState_; } // --- Getter for the ChocolateLotStateReader --- @@ -72,7 +72,7 @@ class MESInterface { // state updates dds::sub::DataReader& ReaderChocolateLotState() { - return *_readerChocolateLotState; + return *readerChocolateLotState_; } private: @@ -81,13 +81,13 @@ class MESInterface { // This contains the calls that allow the interface to create a // "DomainParticipant", the first object that must be created to // communicate over a DDS middleware. - const DDSCommunicator& _communicator; + const DDSCommunicator& communicator_; // DataWriter object for ChocolateLotState - dds::pub::DataWriter* _writerChocolateLotState; + dds::pub::DataWriter* writerChocolateLotState_; // DataReader used for receiving chocolate lot state data - dds::sub::DataReader* _readerChocolateLotState; + dds::sub::DataReader* readerChocolateLotState_; }; #endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx index 1709b1e0..76c61b3b 100644 --- a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.cxx @@ -46,7 +46,7 @@ using namespace std; // ------------------------------------------------------------------------- // RecipePublisherInterface::RecipePublisherInterface(vector& xmlFiles) : - _communicator(DDSCommunicator(xmlFiles)) + communicator_(DDSCommunicator(xmlFiles)) { // Note: all data in this example is "state data." The string constants // with the QoS library name and the QoS profile name are configured as @@ -54,11 +54,11 @@ RecipePublisherInterface::RecipePublisherInterface(vector& xmlFiles) : // the .xml file. Look in the XML for more details on the definition of // state data. - auto topic = dds::topic::Topic(_communicator.Participant(), - RECIPE_TOPIC, _communicator.Qos().topic_qos()); + auto topic = dds::topic::Topic(communicator_.Participant(), + RECIPE_TOPIC, communicator_.Qos().topic_qos()); - _writer = new dds::pub::DataWriter(_communicator.Publisher(), - topic, _communicator.Qos().datawriter_qos()); + writer_ = new dds::pub::DataWriter(communicator_.Publisher(), + topic, communicator_.Qos().datawriter_qos()); } // ---------------------------------------------------------------------------- @@ -72,7 +72,7 @@ RecipePublisherInterface::~RecipePublisherInterface() // Sends the recipe over a transport (such as shared memory or UDPv4) // This writes the Recipe data using RTI Connext DDS to any DataReader // that shares the same Topic -void RecipePublisherInterface::Write(ChocolateRecipe data) +void RecipePublisherInterface::Write(ChocolateRecipe& data) { // This actually sends the recipe data over the network. @@ -84,6 +84,6 @@ void RecipePublisherInterface::Write(ChocolateRecipe data) // throughput, so we are not bothering to pre-register the instance // handle. If we did pre-register the instance handle, this could // potentially speed up the writing. - _writer->write(data); + writer_->write(data); } diff --git a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp index 14d01655..a2f36d10 100644 --- a/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/RecipeGenerator/RecipePublisherInterface.hpp @@ -56,17 +56,17 @@ class RecipePublisherInterface { // Uses DDS interface to send a recipe efficiently over the network // or shared memory to interested applications subscribing to recipe // information. - void Write(ChocolateRecipe data); + void Write(ChocolateRecipe& data); private: // --- Private members --- // Used to create basic DDS entities that all applications need - const DDSCommunicator& _communicator; + const DDSCommunicator& communicator_; // Recipe publisher specific to this application - dds::pub::DataWriter* _writer; + dds::pub::DataWriter* writer_; }; #endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationController.hpp b/ChocolateFactory/ExampleCode/src/StationController/StationController.hpp index c0b8a657..19f0d9ff 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationController.hpp +++ b/ChocolateFactory/ExampleCode/src/StationController/StationController.hpp @@ -33,8 +33,8 @@ class StationController { private: // --- Private members --- - StationControllerInterface& _networkInterface; - StationControllerKind _stationControllerKind; + StationControllerInterface& networkInterface_; + StationControllerKind stationControllerKind_; }; #endif \ No newline at end of file diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx index 217d13b0..c167e092 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx +++ b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.cxx @@ -81,31 +81,31 @@ using namespace dds::sub; // ------------------------------------------------------------------------- // StationControllerInterface::StationControllerInterface(StationControllerKind id, - vector qosFileNames, string lotStateQosProfile) : - _comm(DDSCommunicator(qosFileNames, string(QOS_PROFILE_STATE_DATA))) + vector& qosFileNames, string& lotStateQosProfile) : + comm_(DDSCommunicator(qosFileNames, string(QOS_PROFILE_STATE_DATA))) { // All data in this example is "state data." The string constants with the // QoS library name and the QoS profile name are configured as constants in // the .idl file. The profiles themselves are configured in the .xml file. // Look in the XML for more details on the definition of state data. - auto topicChocolateLotState = Topic(_comm.Participant(), - CHOCOLATE_LOT_TOPIC, _comm.Qos().topic_qos(lotStateQosProfile)); + auto topicChocolateLotState = Topic(comm_.Participant(), + CHOCOLATE_LOT_TOPIC, comm_.Qos().topic_qos(lotStateQosProfile)); auto cftChocolateLotState = ContentFilteredTopic( topicChocolateLotState, "ContentFilter", Filter( "lotStatus = 'LOT_COMPLETED' OR nextController = %0", { StationControllerType::ControllerEnumName(id) }) ); - auto topicChocolateRecipe = Topic(_comm.Participant(), - RECIPE_TOPIC, _comm.Qos().topic_qos()); + auto topicChocolateRecipe = Topic(comm_.Participant(), + RECIPE_TOPIC, comm_.Qos().topic_qos()); - _writerChocolateLotState = new DataWriter(_comm.Publisher(), - topicChocolateLotState, _comm.Qos().datawriter_qos(lotStateQosProfile)); - _readerChocolateLotState = new DataReader(_comm.Subscriber(), - cftChocolateLotState, _comm.Qos().datareader_qos(lotStateQosProfile)); - _readerRecipe = new DataReader(_comm.Subscriber(), - topicChocolateRecipe, _comm.Qos().datareader_qos()); + writerChocolateLotState_ = new DataWriter(comm_.Publisher(), + topicChocolateLotState, comm_.Qos().datawriter_qos(lotStateQosProfile)); + readerChocolateLotState_ = new DataReader(comm_.Subscriber(), + cftChocolateLotState, comm_.Qos().datareader_qos(lotStateQosProfile)); + readerRecipe_ = new DataReader(comm_.Subscriber(), + topicChocolateRecipe, comm_.Qos().datareader_qos()); } // ------------------------------------------------------------------------- // @@ -115,11 +115,11 @@ StationControllerInterface::StationControllerInterface(StationControllerKind id, StationControllerInterface::~StationControllerInterface() { } -ChocolateRecipe StationControllerInterface::GetRecipe(const string recipeName) +ChocolateRecipe StationControllerInterface::GetRecipe(const string& recipeName) { // Create a placeholder with only the key field filled in. This will be // used to retrieve the recipe instance (if it exists). - for (auto sample : _readerRecipe->read()) { + for (auto sample : readerRecipe_->read()) { if (recipeName == sample.data().recipeName()) return sample.data(); } diff --git a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp index fb048d83..24851875 100644 --- a/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp +++ b/ChocolateFactory/ExampleCode/src/StationController/StationControllerInterface.hpp @@ -96,7 +96,7 @@ class StationControllerInterface { // --- Constructor --- StationControllerInterface(StationControllerKind stationControllerID, - vector qosFileNames, string lotStateQosProfile); + vector& qosFileNames, string& lotStateQosProfile); // --- Destructor --- virtual ~StationControllerInterface(); @@ -108,7 +108,7 @@ class StationControllerInterface { // write data in RTI Connext DDS. dds::pub::DataWriter& WriterChocolateLotState() { - return *_writerChocolateLotState; + return *writerChocolateLotState_; } // --- Getter for the ChocolateLotStateReader --- @@ -118,14 +118,14 @@ class StationControllerInterface { // state updates dds::sub::DataReader& ReaderChocolateLotState() { - return *_readerChocolateLotState; + return *readerChocolateLotState_; } // --- Retrieve recipes --- // This example receives all recipes, and leaves them in the middleware's // queue. It queries for a particular recipe when it receives an update // about a lot and it needs to check the recipe for that lot. - ChocolateRecipe GetRecipe(const string recipeName); + ChocolateRecipe GetRecipe(const string& recipeName); private: // --- Private members --- @@ -133,16 +133,16 @@ class StationControllerInterface { // This contains the calls that allow the interface to create a // "DomainParticipant", the first object that must be created to // communicate over a DDS middleware. - const DDSCommunicator& _comm; + const DDSCommunicator& comm_; // DataWriter object for ChocolateLotState - dds::pub::DataWriter* _writerChocolateLotState; + dds::pub::DataWriter* writerChocolateLotState_; // DataReader used for receiving chocolate lot state data - dds::sub::DataReader* _readerChocolateLotState; + dds::sub::DataReader* readerChocolateLotState_; // Used for receiving recipe data, and for looking up received recipes. - dds::sub::DataReader* _readerRecipe; + dds::sub::DataReader* readerRecipe_; }; #endif