diff --git a/cyberiadamlpp.cpp b/cyberiadamlpp.cpp index 85485df..aa59378 100644 --- a/cyberiadamlpp.cpp +++ b/cyberiadamlpp.cpp @@ -633,7 +633,8 @@ ConstElementList ElementCollection::find_elements_by_type(ElementType _type) con const Element* e = *i; if (e->get_type() == _type) { result.push_back(e); - } else if (e->has_children()) { + } + if (e->has_children()) { const ElementCollection* c = static_cast(e); ConstElementList r = c->find_elements_by_type(_type); result.insert(result.end(), r.begin(), r.end()); @@ -649,7 +650,8 @@ ConstElementList ElementCollection::find_elements_by_types(const ElementTypes& t const Element* e = *i; if (std::find(types.begin(), types.end(), e->get_type()) != types.end()) { result.push_back(e); - } else if (e->has_children()) { + } + if (e->has_children()) { const ElementCollection* c = static_cast(e); ConstElementList r = c->find_elements_by_types(types); result.insert(result.end(), r.begin(), r.end()); @@ -665,7 +667,8 @@ ElementList ElementCollection::find_elements_by_type(ElementType _type) Element* e = *i; if (e->get_type() == _type) { result.push_back(e); - } else if (e->has_children()) { + } + if (e->has_children()) { ElementCollection* c = static_cast(e); ElementList r = c->find_elements_by_type(_type); result.insert(result.end(), r.begin(), r.end()); @@ -681,7 +684,8 @@ ElementList ElementCollection::find_elements_by_types(const ElementTypes& types) Element* e = *i; if (std::find(types.begin(), types.end(), e->get_type()) != types.end()) { result.push_back(e); - } else if (e->has_children()) { + } + if (e->has_children()) { ElementCollection* c = static_cast(e); ElementList r = c->find_elements_by_types(types); result.insert(result.end(), r.begin(), r.end()); diff --git a/tests/21-find-elements.cpp b/tests/21-find-elements.cpp new file mode 100644 index 0000000..5528a32 --- /dev/null +++ b/tests/21-find-elements.cpp @@ -0,0 +1,48 @@ +/* ----------------------------------------------------------------------------- + * The Cyberiada GraphML C++ library implemention + * + * The test + * + * Copyright (C) 2024 Alexey Fedoseev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/ + * ----------------------------------------------------------------------------- */ + +#include +#include "cyberiadamlpp.h" + +using namespace Cyberiada; +using namespace std; + +int main(int argc, char** argv) +{ + Document d; + try { + d.load(string(argv[0]) + "-input.graphml", formatLegacyYED); + const StateMachine* sm = d.get_state_machines().front(); + ConstElementList list = sm->find_elements_by_types({Cyberiada::elementSimpleState, + Cyberiada::elementCompositeState, + Cyberiada::elementInitial, + Cyberiada::elementFinal, + Cyberiada::elementChoice, + Cyberiada::elementTerminate}); + for (ConstElementList::const_iterator i = list.begin(); i != list.end(); i++) { + cout << (*i)->dump_to_str() << endl; + } + } catch (const Cyberiada::Exception& e) { + cerr << e.str() << endl; + return 1; + } + return 0; +} diff --git a/tests/21-find-elements.test-input.graphml b/tests/21-find-elements.test-input.graphml new file mode 100644 index 0000000..6492ce8 --- /dev/null +++ b/tests/21-find-elements.test-input.graphml @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Бой + entry/ + +exit/ + + + + + + + + + + + + + + + + + + Сближение + entry/ +МодульДвижения.ДвигатьсяКЦели() + +exit/ + + + + + + + + + + + Атака + entry/ +ОружиеЦелевое.АтаковатьЦель() + +exit/ + + + + + + + + + + + + + Скан + entry/ +Сенсор.ПоискВрагаПоДистанции(мин) + +exit/ +Сенсор.ОстановкаПоиска() + + + + + + + + + + + АнализаторЦели.ЦельПотеряна/ + + + + + + + + + + + АнализаторЦели.ЦельУничтожена/ + + + + + + + + + + + Сенсор.ЦельПолучена/ + + + + + + + + + + + ОружиеЦелевое.ЦельВошлаВЗонуАтаки/ + + + + + + + + + + + ОружиеЦелевое.ЦельВышлаИзЗоныАтаки/ + + + + + + + + + + + + + + + + + + diff --git a/tests/21-output.txt b/tests/21-output.txt new file mode 100644 index 0000000..fa6a787 --- /dev/null +++ b/tests/21-output.txt @@ -0,0 +1,5 @@ +Initial: {id: 'n1', name: '', geometry: (-1623; 753)} +Composite State: {id: 'n0', name: 'Бой', actions: {a {entry}, a {exit}}, geometry: (-786; 492; 517; 770), elements: {Simple State: {id: 'n0::n1', name: 'Сближение', actions: {a {entry, behavior: 'МодульДвижения.ДвигатьсяКЦели()'}, a {exit}}, geometry: (-2; 153; 413; 208)}, Simple State: {id: 'n0::n2', name: 'Атака', actions: {a {entry, behavior: 'ОружиеЦелевое.АтаковатьЦель()'}, a {exit}}, geometry: (2; -181; 413; 208)}}} +Simple State: {id: 'n0::n1', name: 'Сближение', actions: {a {entry, behavior: 'МодульДвижения.ДвигатьсяКЦели()'}, a {exit}}, geometry: (-2; 153; 413; 208)} +Simple State: {id: 'n0::n2', name: 'Атака', actions: {a {entry, behavior: 'ОружиеЦелевое.АтаковатьЦель()'}, a {exit}}, geometry: (2; -181; 413; 208)} +Simple State: {id: 'n3', name: 'Скан', actions: {a {entry, behavior: 'Сенсор.ПоискВрагаПоДистанции(мин)'}, a {exit, behavior: 'Сенсор.ОстановкаПоиска()'}}, geometry: (-1573; 738; 413; 288)}