helmut.bressler Posted March 29, 2019 Share Posted March 29, 2019 Hello, are there examples available of: how to declare a struct how to create a single parameter of that struct how to create an array of that struct within a header file of custom component in C++? I.e. what would the C++ .h file look like for a Component, which creates the following property file: <property name="MyComponent"> <struct name="MyStruct"> <parameter name="someInt" type="int">0</parameter> <parameter name="someFile" type="file" flags="asset"/> </struct> <parameter name="someArray" type="array" array_type="MyStruct" array_dim="1"/> </property> Many thanks, Helmut Link to comment
alexander Posted April 1, 2019 Share Posted April 1, 2019 Hi Helmut, It's very simple: #pragma once #include "ComponentSystem/ComponentSystem.h" class MyComponent : public ComponentBase { public: COMPONENT(MyComponent, ComponentBase); PROP_NAME("MyComponent"); struct MyStruct : public ComponentStruct { PROP_PARAM(Int, someInt); PROP_PARAM(File, someFile); }; PROP_ARRAY_STRUCT(MyStruct, someArray); }; Best regards, Alexander Link to comment
helmut.bressler Posted April 1, 2019 Author Share Posted April 1, 2019 Hello Alexander, that is exactly what I was looking for. Many thanks, Helmut Link to comment
helmut.bressler Posted April 2, 2019 Author Share Posted April 2, 2019 Just one additional observation (for the implementation in 2.7.3): someArray.size() always returns zero, when I add structs through the editor. Likewise the [ ] operator crashs when I try to access array elments. I can access the array elements by using the getNumChildren() and getChild() methods from the Property and the PropertyParameterPtr class. I don't know if that is a bug or if I'm using the API in a wrong way, just want to mention it here. Cheers Helmut Link to comment
alexander Posted April 3, 2019 Share Posted April 3, 2019 Yes, this is a bug. It was fixed in the SDK v2.7.3.1. To fix it change the ComponentVariableArray class in the ComponentSystem.h file with the following code: template <class C> class ComponentVariableArray : public ComponentVariable { public: ComponentVariableArray(): struct_reference(nullptr) {} ComponentVariableArray(PropertyWrapper *component, const char *name, const char *type_name, const char *title = nullptr, const char *tooltip = nullptr, const char *group = nullptr) : ComponentVariable(component, name, Unigine::Property::PARAMETER_ARRAY, title, tooltip, group) , struct_reference(nullptr) { is_basic_type = is_type_name(type_name); // all basic types ("int", "float") have lower characters instead of structs ("MyStruct") // so, we modify the name if we got "Int" or "Float" string in type_name value_type = type_name; if (is_basic_type) value_type.lower(); // add new struct to the Component if (!is_basic_type) { int index = component->findStructIndex(value_type.get()); if (index == -1) { struct_reference = new C { component, type_name }; ComponentVariableStructBase *struct_reference_base = dynamic_cast<ComponentVariableStructBase*>(struct_reference); component->structs.append({ value_type, struct_reference_base->getBase() }); } } } virtual ~ComponentVariableArray() { delete struct_reference; } UNIGINE_INLINE void resize(int size) { int prev_size = value.size(); // destroy old values for (int i = size; i < prev_size; i++) delete value[i]; // resize value.resize(size); if (parameter) parameter->setArraySize(size); // initialize new values for (int i = prev_size; i < size; i++) { if (is_basic_type) value[i] = new C { holder, "" }; else value[i] = new C { holder, value_type.get() }; } // set actual PropertyParameter to children if (parameter) for (int i = 0; i < size; i++) value[i]->setParameter(parameter->getChild(i)); } UNIGINE_INLINE int size() { refresh(); return (int)value.size(); } UNIGINE_INLINE C &get(int index) { refresh(); return *value[index]; } UNIGINE_INLINE C &operator[](int index) { refresh(); return *value[index]; } UNIGINE_INLINE void save(const Unigine::XmlPtr &xml) override { ComponentVariable::save(xml); xml->setArg("array_type", value_type.get()); } protected: Unigine::String value_type; int is_basic_type; Unigine::Vector<C*> value; C *struct_reference; private: // refresh links from Property to Vector<C> value variable void refresh() { if (parameter && parameter->getArraySize() != value.size()) resize(parameter->getArraySize()); } }; Best regards, Alexander Link to comment
Recommended Posts