diff --git a/Test/FMI3/fmi3_import_terminals_and_icons_test.cpp b/Test/FMI3/fmi3_import_terminals_and_icons_test.cpp index 20e7ec59..f3827ce5 100644 --- a/Test/FMI3/fmi3_import_terminals_and_icons_test.cpp +++ b/Test/FMI3/fmi3_import_terminals_and_icons_test.cpp @@ -28,6 +28,20 @@ TEST_CASE("Test parse terminals and icons") { REQUIRE(xml != nullptr); REQUIRE(fmi3_import_get_has_terminals_and_icons(xml) != 0); + SECTION("Testing graphicalRepresentation") { + // TODO: FMI2 + // TODO + ; + SECTION("Testing coordinateSystem") { + // TODO: + ; + } + SECTION("Testing Icon") { + // TODO: + ; + } + } + SECTION("Testing getting terminal by name") { fmi_import_terminal_t* term; @@ -148,3 +162,67 @@ TEST_CASE("Test clearing of attribute buffer with invalid elements") { REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 3); fmi3_testutil_import_free(tfmu); } + +TEST_CASE("Empty graphical representation: Takes default") { + const char* xmldir = FMI3_TEST_XML_DIR "/terminals_and_icons/valid/empty_graphicalRepresentation"; + fmi3_testutil_import_t* tfmu = fmi3_testutil_parse_xml_with_log(xmldir); + fmi3_import_t* fmu = tfmu->fmu; + REQUIRE(fmu != nullptr); // successful parse of modelDescription + REQUIRE(fmi3_import_get_has_terminals_and_icons(fmu) == 1); + + // TODO: Verify default coordinate system + scaling + no icon + + REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 0); + fmi3_testutil_import_free(tfmu); +} + +TEST_CASE("Incomplete graphicaRepresentation->coordinateSystem: Takes default") { + const char* xmldir = FMI3_TEST_XML_DIR "/terminals_and_icons/invalid/incomplete_coordinateSystem"; + fmi3_testutil_import_t* tfmu = fmi3_testutil_parse_xml_with_log(xmldir); + fmi3_import_t* fmu = tfmu->fmu; + REQUIRE(fmu != nullptr); // successful parse of modelDescription + REQUIRE(fmi3_import_get_has_terminals_and_icons(fmu) == 1); + + REQUIRE(fmi3_testutil_log_contains(tfmu, "Parsing XML element 'CoordinateSystem': required attribute 'x2' not found")); + REQUIRE(fmi3_testutil_log_contains(tfmu, "Parsing XML element 'CoordinateSystem': required attribute 'y2' not found")); + + REQUIRE(fmi3_testutil_log_contains(tfmu, "Failed to parse complete CoordinateSystem, using default system (-100, -100), (100, 100).")); + + // TODO: Verify default coordinate system + no icon + + REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 3); + fmi3_testutil_import_free(tfmu); +} + +TEST_CASE("Not well-defined graphicaRepresentation->coordinateSystem") { + const char* xmldir = FMI3_TEST_XML_DIR "/terminals_and_icons/invalid/flipped_coordinateSystem"; + fmi3_testutil_import_t* tfmu = fmi3_testutil_parse_xml_with_log(xmldir); + fmi3_import_t* fmu = tfmu->fmu; + REQUIRE(fmu != nullptr); // successful parse of modelDescription + REQUIRE(fmi3_import_get_has_terminals_and_icons(fmu) == 1); + + REQUIRE(fmi3_testutil_log_contains(tfmu, "'CoordinateSystem' not well-defined, requires x1 = 100.000000 < x2 = -100.000000.")); + REQUIRE(fmi3_testutil_log_contains(tfmu, "'CoordinateSystem' not well-defined, requires y1 = 100.000000 < y2 = -100.000000.")); + + // TODO: Verify coordinates are stored anyways + + REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 2); + fmi3_testutil_import_free(tfmu); +} + +TEST_CASE("Incomplete graphicalRepresentation->Icon") { + const char* xmldir = FMI3_TEST_XML_DIR "/terminals_and_icons/invalid/incomplete_icon"; + fmi3_testutil_import_t* tfmu = fmi3_testutil_parse_xml_with_log(xmldir); + fmi3_import_t* fmu = tfmu->fmu; + REQUIRE(fmu != nullptr); // successful parse of modelDescription + REQUIRE(fmi3_import_get_has_terminals_and_icons(fmu) == 1); + + REQUIRE(fmi3_testutil_log_contains(tfmu, "Parsing XML element 'Icon': required attribute 'x2' not found")); + REQUIRE(fmi3_testutil_log_contains(tfmu, "Parsing XML element 'Icon': required attribute 'y2' not found")); + REQUIRE(fmi3_testutil_log_contains(tfmu, "Failed to parse complete Icon.")); + + // TODO: Verify there is no icon + + REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 3); + fmi3_testutil_import_free(tfmu); +} diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/modelDescription.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/modelDescription.xml new file mode 100644 index 00000000..4e24d976 --- /dev/null +++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/modelDescription.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml new file mode 100644 index 00000000..d58d0580 --- /dev/null +++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/modelDescription.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/modelDescription.xml new file mode 100644 index 00000000..4e24d976 --- /dev/null +++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/modelDescription.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml new file mode 100644 index 00000000..55ca3a4e --- /dev/null +++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/modelDescription.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/modelDescription.xml new file mode 100644 index 00000000..4e24d976 --- /dev/null +++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/modelDescription.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/terminalsAndIcons/terminalsAndIcons.xml new file mode 100644 index 00000000..072bef7c --- /dev/null +++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/terminalsAndIcons/terminalsAndIcons.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/basic/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/basic/terminalsAndIcons/terminalsAndIcons.xml index c2390c33..1551ffeb 100644 --- a/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/basic/terminalsAndIcons/terminalsAndIcons.xml +++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/basic/terminalsAndIcons/terminalsAndIcons.xml @@ -1,5 +1,9 @@ + + + + diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/modelDescription.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/modelDescription.xml new file mode 100644 index 00000000..4e24d976 --- /dev/null +++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/modelDescription.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/terminalsAndIcons/terminalsAndIcons.xml new file mode 100644 index 00000000..6ad178b9 --- /dev/null +++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/terminalsAndIcons/terminalsAndIcons.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/XML/include/FMI/fmi_xml_terminals_and_icons.h b/src/XML/include/FMI/fmi_xml_terminals_and_icons.h index 966ccc37..99176e77 100644 --- a/src/XML/include/FMI/fmi_xml_terminals_and_icons.h +++ b/src/XML/include/FMI/fmi_xml_terminals_and_icons.h @@ -38,6 +38,12 @@ extern "C" { /* Structure encapsulating terminals and icons information */ typedef struct fmi_xml_terminals_and_icons_t fmi_xml_terminals_and_icons_t; +/* Structure encapsulating graphicalRepresentation information */ +typedef struct fmi_xml_graphicalRepresentation_t fmi_xml_graphicalRepresentation_t; +/* Structure encapsulating coordinateSystem information */ +typedef struct fmi_xml_coordinateSystem_t fmi_xml_coordinateSystem_t; +/* Structure encapsulating icon information */ +typedef struct fmi_xml_icon_t fmi_xml_icon_t; /* Structure encapsulating terminal information */ typedef struct fmi_xml_terminal_t fmi_xml_terminal_t; @@ -62,7 +68,22 @@ int fmi2_xml_terminals_and_icons_set_model_description(fmi_xml_terminals_and_ico int fmi3_xml_terminals_and_icons_set_model_description(fmi_xml_terminals_and_icons_t* termIcon, fmi3_xml_model_description_t* md); +/* Top level */ int fmi_xml_get_has_terminals_and_icons(fmi_xml_terminals_and_icons_t* termIcon); + +/* Graphical Representation */ +int fmi_xml_get_has_graphical_representation(fmi_xml_terminals_and_icons_t* termIcon); +/* coordinateSystem*/ +int fmi_xml_get_graphical_representation_system_coordinates(fmi_xml_graphicalRepresentation_t* graphRepr, + double* x1, double* y1, double* x2, double* y2); +int fmi_xml_get_graphical_representation_suggested_scaling(fmi_xml_graphicalRepresentation_t* graphRepr, + double* suggested_scaling); +/* icon */ +int fmi_xml_get_graphical_representation_has_icon(fmi_xml_graphicalRepresentation_t* graphRepr); +int fmi_xml_get_graphical_representation_icon_coordinates(fmi_xml_graphicalRepresentation_t* graphRepr, + double* x1, double* y1, double* x2, double* y2); + +/* Terminals */ fmi_xml_terminal_t* fmi_xml_get_terminal_by_name(fmi_xml_terminals_and_icons_t* termIcon, const char* name); const char* fmi_xml_get_terminal_name(fmi_xml_terminal_t* term); diff --git a/src/XML/include/FMI/fmi_xml_terminals_and_icons_scheme.h b/src/XML/include/FMI/fmi_xml_terminals_and_icons_scheme.h index a731b21e..381b159b 100644 --- a/src/XML/include/FMI/fmi_xml_terminals_and_icons_scheme.h +++ b/src/XML/include/FMI/fmi_xml_terminals_and_icons_scheme.h @@ -26,11 +26,20 @@ extern "C" { #define FMI_XML_ATTRLIST_TERM_ICON(EXPAND_XML_ATTRNAME) \ EXPAND_XML_ATTRNAME(fmiVersion) \ EXPAND_XML_ATTRNAME(name) \ - EXPAND_XML_ATTRNAME(description) + EXPAND_XML_ATTRNAME(description) \ + EXPAND_XML_ATTRNAME(x1) \ + EXPAND_XML_ATTRNAME(y1) \ + EXPAND_XML_ATTRNAME(x2) \ + EXPAND_XML_ATTRNAME(y2) \ + EXPAND_XML_ATTRNAME(suggestedScalingFactorTo_mm) + /* Element names found in terminalsAndIcons.xml */ #define FMI_XML_ELMLIST_TERM_ICON(EXPAND_XML_ELMNAME) \ EXPAND_XML_ELMNAME(fmiTerminalsAndIcons) \ + EXPAND_XML_ELMNAME(GraphicalRepresentation) \ + EXPAND_XML_ELMNAME(CoordinateSystem) \ + EXPAND_XML_ELMNAME(Icon) \ EXPAND_XML_ELMNAME(Terminals) \ EXPAND_XML_ELMNAME(Terminal) \ EXPAND_XML_ELMNAME(TerminalMemberVariable) \ @@ -48,14 +57,18 @@ extern "C" { @multi_elem: if the parent can have multiple elements of this type */ -/* scheme_ID, super_type, parent_ID, sib_idx, multi_elem */ -#define fmi_xml_scheme_termIcon_fmiTerminalsAndIcons {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_none, 0, 0} - -#define fmi_xml_scheme_termIcon_Terminals {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_fmiTerminalsAndIcons, 1, 0} -#define fmi_xml_scheme_termIcon_Terminal {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminals, 0, 1} -#define fmi_xml_scheme_termIcon_TerminalMemberVariable {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminal, 0, 1} -#define fmi_xml_scheme_termIcon_TerminalStreamMemberVariable {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminal, 1, 1} -#define fmi_xml_scheme_termIcon_TerminalGraphicalRepresentation {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminal, 3, 0} +/* scheme_ID, super_type, parent_ID, sib_idx, multi_elem */ +#define fmi_xml_scheme_termIcon_fmiTerminalsAndIcons {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_none, 0, 0} + +#define fmi_xml_scheme_termIcon_GraphicalRepresentation {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_fmiTerminalsAndIcons, 0, 0} +#define fmi_xml_scheme_termIcon_CoordinateSystem {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_GraphicalRepresentation, 0, 0} +#define fmi_xml_scheme_termIcon_Icon {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_GraphicalRepresentation, 1, 0} + +#define fmi_xml_scheme_termIcon_Terminals {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_fmiTerminalsAndIcons, 1, 0} +#define fmi_xml_scheme_termIcon_Terminal {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminals, 0, 1} +#define fmi_xml_scheme_termIcon_TerminalMemberVariable {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminal, 0, 1} +#define fmi_xml_scheme_termIcon_TerminalStreamMemberVariable {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminal, 1, 1} +#define fmi_xml_scheme_termIcon_TerminalGraphicalRepresentation {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminal, 3, 0} // Attribute enum #define FMI_TERMICON_XML_ATTR_ID(attr) fmi_termIcon_attr_id_##attr, diff --git a/src/XML/src/FMI/fmi_xml_terminals_and_icons.c b/src/XML/src/FMI/fmi_xml_terminals_and_icons.c index f7ae5f0a..959311e1 100644 --- a/src/XML/src/FMI/fmi_xml_terminals_and_icons.c +++ b/src/XML/src/FMI/fmi_xml_terminals_and_icons.c @@ -35,6 +35,8 @@ fmi_xml_terminals_and_icons_t* fmi_xml_allocate_terminals_and_icons(jm_callbacks jm_vector_init(char)(&termIcon->fmi3_xml_standard_version, 0, cb); + termIcon->graphicalRepresentation = NULL; + jm_vector_init(jm_voidp)(&termIcon->terminalsOrigOrder, 0, cb); jm_vector_init(jm_named_ptr)(&termIcon->terminalsByName, 0, cb); @@ -61,6 +63,13 @@ void fmi_xml_free_terminals_and_icons(fmi_xml_terminals_and_icons_t* termIcon) { jm_callbacks* callbacks = termIcon->callbacks; if (termIcon) { jm_vector_free_data(char)(&(termIcon->fmi3_xml_standard_version)); + + // free graphicalDescription + if (termIcon->graphicalRepresentation) { + callbacks->free(termIcon->graphicalRepresentation->coordinateSystem); + callbacks->free(termIcon->graphicalRepresentation->icon); + } + callbacks->free(termIcon->graphicalRepresentation); // free terminals for (size_t i = 0; i < jm_vector_get_size(jm_voidp)(&(termIcon->terminalsOrigOrder)); i++) { @@ -139,6 +148,102 @@ int fmi_xml_handle_fmiTerminalsAndIcons(fmi3_xml_parser_context_t* context, cons return 0; } +int fmi_xml_handle_GraphicalRepresentation(fmi3_xml_parser_context_t* context, const char* data) { + fmi_xml_terminals_and_icons_t* termIcon = context->termIcon; + if (!data) { + termIcon->graphicalRepresentation = (fmi_xml_graphicalRepresentation_t*)context->callbacks->calloc(1, sizeof(fmi_xml_graphicalRepresentation_t)); + if (!termIcon->graphicalRepresentation) { + fmi3_xml_parse_fatal(context, "Could not allocate memory"); + return 1; + } + // GraphicalRepresentation has a default coordinateSystem, allocate here directly + termIcon->graphicalRepresentation->coordinateSystem = (fmi_xml_coordinateSystem_t*)context->callbacks->calloc(1, sizeof(fmi_xml_coordinateSystem_t)); + if (!termIcon->graphicalRepresentation->coordinateSystem) { + fmi3_xml_parse_fatal(context, "Could not allocate memory"); + return 1; + } + termIcon->graphicalRepresentation->coordinateSystem->x1 = -100; + termIcon->graphicalRepresentation->coordinateSystem->y1 = -100; + termIcon->graphicalRepresentation->coordinateSystem->x2 = 100; + termIcon->graphicalRepresentation->coordinateSystem->y2 = 100; + termIcon->graphicalRepresentation->coordinateSystem->suggestedScalingFactorTo_mm = 0.1; + } else { + ; + } + return 0; +} + +int fmi_xml_handle_CoordinateSystem(fmi3_xml_parser_context_t* context, const char* data) { + fmi_xml_terminals_and_icons_t* termIcon = context->termIcon; + fmi_xml_coordinateSystem_t* coordSys = termIcon->graphicalRepresentation->coordinateSystem; + if (!data) { + // Allocation in GraphicalRepresentation + int ret = 0; + + ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_CoordinateSystem), + FMI_ATTR_TERMICON(fmi_termIcon_attr_id_x1), 1, &(coordSys->x1), -100); + ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_CoordinateSystem), + FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y1), 1, &(coordSys->y1), -100); + ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_CoordinateSystem), + FMI_ATTR_TERMICON(fmi_termIcon_attr_id_x2), 1, &(coordSys->x2), 100); + ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_CoordinateSystem), + FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y2), 1, &(coordSys->y2), 100); + ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_CoordinateSystem), + FMI_ATTR_TERMICON(fmi_termIcon_attr_id_suggestedScalingFactorTo_mm), 1, &(coordSys->suggestedScalingFactorTo_mm), 0.1); + if (ret) { + fmi3_xml_parse_error(context, "Failed to parse complete CoordinateSystem, using default system (-100, -100), (100, 100)."); + coordSys->x1 = -100; + coordSys->y1 = -100; + coordSys->x2 = 100; + coordSys->y2 = 100; + coordSys->suggestedScalingFactorTo_mm = 0.1; + return 1; + } + } else { + /* SPEC: [...] where the coordinates of the first point shall be less than the coordinates of the second point. */ + if (coordSys->x1 >= coordSys->x2) { + fmi3_xml_parse_warning(context, "'CoordinateSystem' not well-defined, requires x1 = %f < x2 = %f.", + coordSys->x1, coordSys->x2); + } + if (coordSys->y1 >= coordSys->y2) { + fmi3_xml_parse_warning(context, "'CoordinateSystem' not well-defined, requires y1 = %f < y2 = %f.", + coordSys->y1, coordSys->y2); + } + } + return 0; +} + +int fmi_xml_handle_Icon(fmi3_xml_parser_context_t* context, const char* data) { + fmi_xml_terminals_and_icons_t* termIcon = context->termIcon; + fmi_xml_graphicalRepresentation_t* graphRepr = termIcon->graphicalRepresentation; + if (!data) { + int ret; + fmi_xml_icon_t* icon = (fmi_xml_icon_t*)context->callbacks->calloc(1, sizeof(fmi_xml_icon_t)); + if (!icon) { + fmi3_xml_parse_fatal(context, "Could not allocate memory"); + return 1; + } + ret = 0; + ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Icon), + FMI_ATTR_TERMICON(fmi_termIcon_attr_id_x1), 1, &(icon->x1), 0); + ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Icon), + FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y1), 1, &(icon->y1), 0); + ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Icon), + FMI_ATTR_TERMICON(fmi_termIcon_attr_id_x2), 1, &(icon->x2), 0); + ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Icon), + FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y2), 1, &(icon->y2), 0); + if (ret) { + fmi3_xml_parse_error(context, "Failed to parse complete Icon."); + context->callbacks->free(icon); // Discard element + return 1; + } + graphRepr->icon = icon; + } else { + ; + } + return 0; +} + int fmi_xml_handle_Terminals(fmi3_xml_parser_context_t* context, const char* data) { fmi_xml_terminals_and_icons_t* termIcon = context->termIcon; if (!data) { @@ -192,7 +297,7 @@ int fmi_xml_handle_Terminal(fmi3_xml_parser_context_t* context, const char* data // parse name jm_vector(char)* bufName = fmi3_xml_reserve_parse_buffer(context, bufIdx++, 100); if (!bufName) {return -1;} - if (fmi3_xml_parse_attr_as_string(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Terminal), FMI_ATTR_TERMICON(fmi_attr_id_name), 1 /* required */, bufName)) {return -1;} + if (fmi3_xml_parse_attr_as_string(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Terminal), FMI_ATTR_TERMICON(fmi_termIcon_attr_id_name), 1 /* required */, bufName)) {return -1;} /* Add the name to the terminalsAndIcons-wide set and retrieve the pointer */ if (jm_vector_get_size(char)(bufName)) { @@ -237,17 +342,69 @@ int fmi_xml_handle_TerminalGraphicalRepresentation(fmi3_xml_parser_context_t* co return 0; } + +/* Top level*/ int fmi_xml_get_has_terminals_and_icons(fmi_xml_terminals_and_icons_t* termIcon) { return termIcon ? 1 : 0; } -fmi_xml_terminal_t* fmi_xml_get_terminal_by_name(fmi_xml_terminals_and_icons_t* termIcon, const char* name){ - if (!name) return NULL; +/* Graphical Representation */ +int fmi_xml_get_has_graphical_representation(fmi_xml_terminals_and_icons_t* termIcon) { + if (!termIcon) { + return 0; + } + return termIcon->graphicalRepresentation ? 1 : 0; +} + +int fmi_xml_get_graphical_representation_system_coordinates(fmi_xml_graphicalRepresentation_t* graphRepr, + double* x1, double* y1, double* x2, double* y2) { + if (!graphRepr || (!graphRepr->coordinateSystem)) { + return 1; + } + *x1 = graphRepr->coordinateSystem->x1; + *y1 = graphRepr->coordinateSystem->y1; + *x2 = graphRepr->coordinateSystem->x2; + *y2 = graphRepr->coordinateSystem->y2; + return 0; +} + +int fmi_xml_get_graphical_representation_suggested_scaling(fmi_xml_graphicalRepresentation_t* graphRepr, + double* suggested_scaling) { + if (!graphRepr || (!graphRepr->coordinateSystem)) { + return 1; + } + *suggested_scaling = graphRepr->coordinateSystem->suggestedScalingFactorTo_mm; + return 0; +} + +int fmi_xml_get_graphical_representation_has_icon(fmi_xml_graphicalRepresentation_t* graphRepr) { + if (!graphRepr) { + return 0; + } + return graphRepr->icon ? 1 : 0; +} + +int fmi_xml_get_graphical_representation_icon_coordinates(fmi_xml_graphicalRepresentation_t* graphRepr, + double* x1, double* y1, double* x2, double* y2) { + if (!graphRepr || (!graphRepr->icon)) { + return 1; + } + *x1 = graphRepr->icon->x1; + *y1 = graphRepr->icon->y1; + *x2 = graphRepr->icon->x2; + *y2 = graphRepr->icon->y2; + return 0; +} + +/* Terminals*/ +fmi_xml_terminal_t* fmi_xml_get_terminal_by_name(fmi_xml_terminals_and_icons_t* termIcon, const char* name) { + if (!name) { + return NULL; + } jm_named_ptr key, *found; key.name = name; found = jm_vector_bsearch(jm_named_ptr)(&termIcon->terminalsByName, &key, jm_compare_named); - if (!found) return NULL; - return found->ptr; + return found ? found->ptr : NULL; } const char* fmi_xml_get_terminal_name(fmi_xml_terminal_t* term) { diff --git a/src/XML/src/FMI/fmi_xml_terminals_and_icons_impl.h b/src/XML/src/FMI/fmi_xml_terminals_and_icons_impl.h index 277a64bb..53de2482 100644 --- a/src/XML/src/FMI/fmi_xml_terminals_and_icons_impl.h +++ b/src/XML/src/FMI/fmi_xml_terminals_and_icons_impl.h @@ -34,12 +34,28 @@ struct fmi_xml_terminals_and_icons_t { jm_vector(char) fmi3_xml_standard_version; + fmi_xml_graphicalRepresentation_t* graphicalRepresentation; + jm_vector(jm_voidp) terminalsOrigOrder; jm_vector(jm_named_ptr) terminalsByName; jm_string_set names; // storage for all terminal names }; +struct fmi_xml_graphicalRepresentation_t { + fmi_xml_coordinateSystem_t* coordinateSystem; + fmi_xml_icon_t* icon; +}; + +struct fmi_xml_coordinateSystem_t { + double x1, y1, x2, y2; + double suggestedScalingFactorTo_mm; +}; + +struct fmi_xml_icon_t { + double x1, y1, x2, y2; +}; + struct fmi_xml_terminal_t { const char* name; // TODO: Currently only supports name; add remaining attributes.