-
Notifications
You must be signed in to change notification settings - Fork 139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding dynamic data enum example #640
Open
angelrti
wants to merge
4
commits into
master
Choose a base branch
from
example/dynamic_data_enum
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+357
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# This project has a specific makefile / solution | ||
!*.sln | ||
!*.vcxproj | ||
!makefile* |
26 changes: 26 additions & 0 deletions
26
examples/connext_dds/dynamic_data_get_enum_value/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Dynamic Data API: access to complex member example | ||
|
||
## Concept | ||
|
||
*Dynamic Data API* allows to create topic samples in a programmatically manner | ||
without defining an IDL in compile time. | ||
|
||
This example shows how to access enum ordinal values by name from a | ||
dynamic data object. | ||
|
||
## Example description | ||
|
||
In this example, we show three different scenarios to get the ordinal value of | ||
an enum member by using `DynamicData` and `DynamicType` elements. | ||
|
||
The first scenario shows how to get the enum member ordinal value from a | ||
`DynamicType`. In this case, you have to specify the enum field name and | ||
the enum element string. In this case, there is a translation from the | ||
`DynamicType` into a `StructType` and then the element into an `EnumType`. | ||
|
||
In the second scenario, a for loop iterates through all elements and check | ||
which one is an `ENUMERATION_TYPE`. Then, if this enum is the type that we are | ||
looking for, then it prints the specified values. | ||
|
||
In the third scenario, the `EnumType` is gotten from the a DynamicData by using | ||
the `member_type` API. |
49 changes: 49 additions & 0 deletions
49
examples/connext_dds/dynamic_data_get_enum_value/c++11/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# | ||
# (c) 2023 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. | ||
# | ||
cmake_minimum_required(VERSION 3.11) | ||
project(rtiexamples-dynamic-data-access-enum-discriminator) | ||
|
||
set(CMAKE_CXX_STANDARD 11) | ||
set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
|
||
list(APPEND CMAKE_MODULE_PATH | ||
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../resources/cmake/Modules" | ||
) | ||
include(ConnextDdsConfigureCmakeUtils) | ||
connextdds_configure_cmake_utils() | ||
|
||
# Find the ConnextDDS libraries. This will look for core and API libraries | ||
find_package(RTIConnextDDS | ||
"7.0.0" | ||
REQUIRED | ||
COMPONENTS | ||
core | ||
) | ||
|
||
add_executable(dynamic_data_enum_example_cxx2 | ||
"${CMAKE_CURRENT_SOURCE_DIR}/dynamic_data_enum_example.cxx" | ||
) | ||
|
||
target_link_libraries(dynamic_data_enum_example_cxx2 | ||
PRIVATE | ||
RTIConnextDDS::cpp2_api | ||
) | ||
|
||
set_target_properties(dynamic_data_enum_example_cxx2 | ||
PROPERTIES | ||
OUTPUT_NAME "dynamic_data_enum_example") | ||
|
||
if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") | ||
set_target_properties(dynamic_data_enum_example_cxx2 | ||
PROPERTIES | ||
LINK_FLAGS -Wl,--no-as-needed) | ||
endif() |
112 changes: 112 additions & 0 deletions
112
examples/connext_dds/dynamic_data_get_enum_value/c++11/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# Example code: Get Enum Ordinals in Dynamic Data | ||
|
||
## 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). | ||
|
||
```sh | ||
mkdir build | ||
cd build | ||
cmake .. | ||
``` | ||
|
||
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: | ||
|
||
```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: | ||
|
||
```sh | ||
cmake --build . --config Release|Debug | ||
``` | ||
|
||
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. | ||
|
||
## Running the Example | ||
|
||
Run the following command from the example directory to execute the application. | ||
|
||
On *UNIX* systems: | ||
|
||
```bash | ||
./dynamic_data_enum_example | ||
``` | ||
|
||
On *Windows* Systems: | ||
|
||
```bash | ||
dynamic_data_enum_example | ||
``` | ||
|
||
## Customizing the Build | ||
|
||
### Configuring Build Type and Generator | ||
|
||
By default, CMake will generate build files using the most common generator for | ||
your host platform (e.g., Makefiles on Unix-like systems and Visual Studio | ||
Solutions on Windows). You can use the following CMake variables to modify the | ||
default behavior: | ||
|
||
- `-DCMAKE_BUILD_TYPE` - specifies the build mode. Valid values are `Release` | ||
and `Debug`. See the [CMake documentation for more details | ||
(Optional)](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html). | ||
|
||
- `-DBUILD_SHARED_LIBS` - specifies the link mode. Valid values are `ON` for | ||
dynamic linking and `OFF` for static linking. See [CMake documentation for | ||
more details | ||
(Optional)](https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html). | ||
|
||
- `-G` - CMake generator. The generator is the native build system used to | ||
build the source code. All the valid values are described in the CMake | ||
documentation for [CMake | ||
Generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html). | ||
|
||
For example, to build an example in Debug/Dynamic mode run CMake as follows: | ||
|
||
```sh | ||
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON .. -G "Visual Studio 15 2017" -A x64 | ||
``` | ||
|
||
### Configuring Connext Installation Path and Architecture | ||
|
||
The CMake build infrastructure will try to guess the location of your Connext | ||
installation and the Connext architecture based on the default settings | ||
for your host platform. If you installed Connext in a custom location, you | ||
can use the `CONNEXTDDS_DIR` variable to indicate the path to your RTI Connext | ||
installation folder. For example: | ||
|
||
```sh | ||
cmake -DCONNEXTDDS_DIR=/home/rti/rti_connext_dds-x.y.z .. | ||
``` | ||
|
||
Also, if you installed libraries for multiple target architectures on your system | ||
(i.e., you installed more than one target `.rtipkg` file), you can use the | ||
`CONNEXTDDS_ARCH` variable to indicate the architecture of the specific libraries | ||
you want to link against. For example: | ||
|
||
```sh | ||
cmake -DCONNEXTDDS_ARCH=x64Linux3gcc5.4.0 .. | ||
``` | ||
|
||
### CMake Build Infrastructure | ||
|
||
This example does not require the usage of rtiddsgen. Therefore, the | ||
`CMakeLists.txt` script just creates the executable and link it with the Connext | ||
API. | ||
|
||
For a more comprehensive example on how to build an RTI Connext application | ||
using CMake, please refer to the | ||
[hello_world](../../../connext_dds/build_systems/cmake/) example, which includes | ||
a comprehensive `CMakeLists.txt` script with all the steps and instructions | ||
described in detail. |
165 changes: 165 additions & 0 deletions
165
examples/connext_dds/dynamic_data_get_enum_value/c++11/dynamic_data_enum_example.cxx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,165 @@ | ||||||
/******************************************************************************* | ||||||
(c) 2023 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 <cstdlib> | ||||||
#include <iostream> | ||||||
|
||||||
#include <dds/dds.hpp> | ||||||
|
||||||
using namespace dds::core::xtypes; | ||||||
|
||||||
EnumType create_enum_type() | ||||||
{ | ||||||
return EnumType( | ||||||
"EngineState", | ||||||
{ EnumMember("off", 0), EnumMember("on", 42) }); | ||||||
} | ||||||
|
||||||
DynamicType create_struct_dynamic_type() | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
{ | ||||||
// First create the type code for a struct | ||||||
StructType my_struct("EnumStruct"); | ||||||
EnumType inner_enum = create_enum_type(); | ||||||
|
||||||
// Member 1 will be an enum EngineState named engine_state_element | ||||||
my_struct.add_member(Member( | ||||||
"engine_state_element", | ||||||
static_cast<const dds::core::xtypes::DynamicType &>(inner_enum))); | ||||||
|
||||||
return my_struct; | ||||||
} | ||||||
|
||||||
int32_t get_enum_ordinal_value_by_name( | ||||||
DynamicType struct_dynamic_type, | ||||||
std::string enum_element) | ||||||
{ | ||||||
// Get value using scenario 1 of `print_enum_ordinal_value_by_name` | ||||||
const StructType &dynamic_struct = | ||||||
static_cast<const StructType &>(struct_dynamic_type); | ||||||
EnumType enum_type = static_cast<const EnumType &>( | ||||||
dynamic_struct.member("engine_state_element").type()); | ||||||
|
||||||
// Return the specified value | ||||||
return enum_type.member(enum_element).ordinal(); | ||||||
} | ||||||
|
||||||
void print_enum_ordinal_values_from_dynamic_type( | ||||||
DynamicType struct_dynamic_type) | ||||||
{ | ||||||
// If you need a switch/case statement you can use | ||||||
// enum_dynamic_type.kind().underlying() | ||||||
if (struct_dynamic_type.kind() == TypeKind::STRUCTURE_TYPE) { | ||||||
// Different ways of getting the enum ordinals | ||||||
// Scenario 1. We already know the member name and it is an enum | ||||||
|
||||||
// cast the DynamicType into a StructType | ||||||
const StructType &dynamic_struct = | ||||||
static_cast<const StructType &>(struct_dynamic_type); | ||||||
|
||||||
EnumType enum_type = static_cast<const EnumType &>( | ||||||
dynamic_struct.member("engine_state_element").type()); | ||||||
|
||||||
std::cout << "Scenario 1 - print enum ordinals from DynamicType" | ||||||
<< std::endl; | ||||||
std::cout << "On: " << enum_type.member("on").ordinal() << std::endl; | ||||||
std::cout << "Off: " << enum_type.member("off").ordinal() << std::endl | ||||||
<< std::endl; | ||||||
|
||||||
|
||||||
// Scenario 2, iterate through all the elements in the StructType | ||||||
// and do something for the enums | ||||||
for (auto member : dynamic_struct.members()) { | ||||||
// here you may want to use a switch/case | ||||||
if (member.type().kind() == TypeKind::ENUMERATION_TYPE) { | ||||||
EnumType engine_state_type = | ||||||
static_cast<const EnumType &>(member.type()); | ||||||
|
||||||
// This assumes that we know the enum strings | ||||||
if (engine_state_type.name() == "EngineState") { | ||||||
std::cout << "Scenario 2 - print enum ordinals from " | ||||||
"DynamicType iterating members" | ||||||
<< std::endl; | ||||||
std::cout << "On: " | ||||||
<< engine_state_type.member("on").ordinal() | ||||||
<< std::endl; | ||||||
std::cout << "Off: " | ||||||
<< engine_state_type.member("off").ordinal() | ||||||
<< std::endl | ||||||
<< std::endl; | ||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
return; | ||||||
} | ||||||
|
||||||
void print_enum_ordinal_values_from_dynamic_data( | ||||||
DynamicData struct_dynamic_data) | ||||||
{ | ||||||
// Scenario 3, we can get the member type directly as a DynamicType | ||||||
// This assumes that we already know the name "EngineState" and that it is | ||||||
// an Enum. | ||||||
// This is similar to Scenario 1, but getting directly the EngineState as a | ||||||
// DynamicType instead of the struct that contains it. | ||||||
DynamicType enum_member_type = | ||||||
struct_dynamic_data.member_type("engine_state_element"); | ||||||
EnumType enum_type = static_cast<const EnumType &>(enum_member_type); | ||||||
|
||||||
std::cout << "Scenario 3 - print enum ordinals from DynamicData" | ||||||
<< std::endl; | ||||||
std::cout << "On: " << enum_type.member("on").ordinal() << std::endl; | ||||||
std::cout << "Off: " << enum_type.member("off").ordinal() << std::endl | ||||||
<< std::endl; | ||||||
|
||||||
return; | ||||||
} | ||||||
|
||||||
void example() | ||||||
{ | ||||||
// Create the type of the struct with the enum | ||||||
DynamicType enum_dynamic_type = create_struct_dynamic_type(); | ||||||
|
||||||
std::cout << "Print IDL corresponding type" << std::endl; | ||||||
print_idl(enum_dynamic_type); | ||||||
std::cout << std::endl; | ||||||
|
||||||
// Create the DynamicData. | ||||||
DynamicData enum_data(enum_dynamic_type); | ||||||
|
||||||
// Set the value of the current member | ||||||
enum_data.value<int32_t>( | ||||||
"engine_state_element", | ||||||
get_enum_ordinal_value_by_name(enum_dynamic_type, "on")); | ||||||
|
||||||
// Print the values of the enum elements from a dynamic data. It uses | ||||||
// the DynamicType internally. | ||||||
print_enum_ordinal_values_from_dynamic_type(enum_dynamic_type); | ||||||
print_enum_ordinal_values_from_dynamic_data(enum_data); | ||||||
|
||||||
std::cout << "Print enum ordinal value of DynamicData" << std::endl; | ||||||
std::cout << "Value: " << enum_data.value<int32_t>("engine_state_element") | ||||||
<< std::endl; | ||||||
|
||||||
return; | ||||||
} | ||||||
|
||||||
int main(int argc, char *argv[]) | ||||||
{ | ||||||
try { | ||||||
example(); | ||||||
} catch (const std::exception &ex) { | ||||||
std::cerr << "Caught exception: " << ex.what() << std::endl; | ||||||
return -1; | ||||||
} | ||||||
|
||||||
return 0; | ||||||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be simplified: