Skip to content
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

Added support for custom class properties #3215

Merged
merged 24 commits into from
Dec 23, 2021
Merged

Conversation

bjorn
Copy link
Member

@bjorn bjorn commented Dec 17, 2021

These changes add the ability to define custom classes for use as properties, even supporting composition with other custom classes:

image

There are also changes adding support for storing enums as int instead of string, as for treating enum values as flags:

image

I'm opening a pull request here to give this some more visibility, and also to request feedback, so I hope there will be some people who'd like to try out the feature in its current state.

Closes #489

bjorn added 24 commits December 23, 2021 10:46
So far all of the changes are just on the data level, no UI changes have
been made yet. Change is WIP since it currently leaves the Enums Editor
broken.

It appears to me that a ClassPropertyType will have some overlap with
the already supported ObjectType. I think it would be nice if we could
merge these.
Just considering that for code organization, wrapping this up in a class
is convenient. I can also imagine, that one PropertyTypes instance may
have dependencies on other PropertyTypes instances loaded from other
files.
Switched to shared ownership over the ObjectTypes, since the lifetime
between the project, the global pointer and the ObjectTypesModel is a
little complicated.
Does not include support for editing classes yet.
Also indicate whether a class member is modified by displaying the name
in bold.
The Enums Editor was extended with the ability to add custom class
properties, and is now again called the Property Types Editor.

Fixed two issues in the CustomPropertiesHelper:

* Don't emit propertyValueChanged on creation of properties
* Fixed deletion of sub-properties to not leave roaming pointers

There are still a few unresolved issues.
* Resolved the loading order problem by delaying the loading of class
  members.
* Added icons to distinguish class and enum property types,
* Fixed another issue in the CustomPropertiesHelper, which could emit
  propertyValueChanged for sub-properties. Added notes about further
  issues.
* Property Types Editor should be fully functional now.
Take circular dependencies into account in the dialog used to add
members to a class.

Still to be done is to sanity-check when loading property types, because
a saved circular dependency can still cause a crash.
Change QtFlagPropertyManager::setEnumNames to not reset the current
value, but rather just clear any invalid flags. This is somewhat less
destructive and at least allows renaming and adding flag values without
issues.

See also a04ad53.
* Fixed resetting the last member of a top-level class property
* Fixed properties to keep their value when the class definition is changed
User can now choose to store enum values as "String" or "Number", for
each defined enum.
This required the property to be re-created, since this option affects
the property type. This already happened for class members anyway, but
not for top-level enum properties.

Also fixed an issue with restoring member values after types are changed

When changing this option, existing values do get messed up, because the
integer index gets interpreted as flags, and vice versa. The value is
even entirely lost when the combined flags result in an out-of-range
index. It could be worth looking into improving this behavior.
Setting the "flagNames" attribute causes the QtFlagPropertyManager to
re-create its child properties. This causes the QtVariantPropertyManager
to re-create its wrapping QtVariantProperty instances.

When this happens with a property that is already added to a property
browser, the value icon and text were requested before the
QtVariantPropertyManager had set up the mapping between the wrapping
QtVariantProperty instance and the internal property. This caused the
returned icon and text for the child flag properties to be empty.
Switched away from std::vector<std::unique_ptr<...>> back to convenient
QVector and plain pointer. The error was:

ERROR: "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64\cl.exe" /nologo /c /EHsc /O2 /MD /IC:\projects\tiled\zstd\lib /IC:\Qt\5.15\msvc2019_64\include /IC:\Qt\5.15\msvc2019_64\include\QtGui /IC:\Qt\5.15\msvc2019_64\include\QtANGLE /IC:\Qt\5.15\msvc2019_64\include\QtCore /IC:\Qt\5.15\msvc2019_64\mkspecs\win32-msvc /IC:\projects\tiled\release\libtiled.080f31f8\qt.headers /experimental:external /external:W0 /DNDEBUG /DUNICODE /D_UNICODE /DWIN32 /DTILED_LIBRARY /DQT_NO_CAST_FROM_ASCII /DQT_NO_CAST_TO_ASCII /DQT_NO_URL_CAST_FROM_STRING "/DQT_DISABLE_DEPRECATED_BEFORE=QT_VERSION_CHECK(5,15,0)" /DQT_NO_DEPRECATED_WARNINGS /D_USE_MATH_DEFINES /DQT_GUI_LIB /DQT_CORE_LIB /DQT_NO_DEBUG "/DWINVER=0x0502" "/D_WIN32_WINNT=0x0502" "/D_WIN32_WINDOWS=0x0502" /FoC:\projects\tiled\release\libtiled.080f31f8\3a52ce780950d4d9\logginginterface.cpp.obj C:\projects\tiled\src\libtiled\logginginterface.cpp /TP /std:c++14 /FS
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\xutility(4198): error C2280: 'std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>> &std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>::operator =(const std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>> &)': attempting to reference a deleted function
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\memory(3270): note: see declaration of 'std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>::operator ='
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\memory(3270): note: 'std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>> &std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>::operator =(const std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>> &)': function was explicitly deleted
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\vector(1175): note: see reference to function template instantiation '_OutIt *std::_Copy_unchecked<_Iter,std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>*>(_InIt,_InIt,_OutIt)' being compiled
        with
        [
            _OutIt=std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>> *,
            _Iter=std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>> *,
            _InIt=std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>> *
        ]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\vector(1189): note: see reference to function template instantiation 'void std::vector<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>,std::allocator<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>>>::_Assign_range<_Iter>(_Iter,_Iter,std::forward_iterator_tag)' being compiled
        with
        [
            _Iter=std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>> *
        ]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\vector(1189): note: see reference to function template instantiation 'void std::vector<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>,std::allocator<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>>>::_Assign_range<_Iter>(_Iter,_Iter,std::forward_iterator_tag)' being compiled
        with
       [
            _Iter=std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>> *
        ]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\vector(1200): note: see reference to function template instantiation 'void std::vector<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>,std::allocator<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>>>::assign<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>*,0>(_Iter,_Iter)' being compiled
        with
        [
           _Iter=std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>> *
        ]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\vector(1200): note: see reference to function template instantiation 'void std::vector<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>,std::allocator<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>>>::assign<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>*,0>(_Iter,_Iter)' being compiled
        with
        [
            _Iter=std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>> *
        ]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\vector(1197): note: while compiling class template member function 'void std::vector<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>,std::allocator<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>>>::_Copy_assign(const std::vector<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>,std::allocator<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>>> &,std::false_type)'
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\vector(1216): note: see reference to function template instantiation 'void std::vector<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>,std::allocator<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>>>::_Copy_assign(const std::vector<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>,std::allocator<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>>> &,std::false_type)' being compiled
C:\projects\tiled\src\libtiled\propertytype.h(153): note: see reference to class template instantiation 'std::vector<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>,std::allocator<std::unique_ptr<Tiled::PropertyType,std::default_delete<Tiled::PropertyType>>>>' being compiled
RROR: Process failed with exit code 2.
The following products could not be built for configuration release:
archive, csv, defold, defoldcollection, distribute, droidcraft, flare, gmx, installer, json, json1, libtiled, libtiledquick, lua, python, qtpropertybrowser, qtsingleapplication, replicaisland, tbin, tengine, terraingenerator, test_mapreader, test_staggeredrenderer, tiled, tiledquick, tiledquickplugin, tmxrasterizer, tmxviewer, translations, yy
Command exited with code 1
QFormLayout::removeRow was added in Qt 5.8. Changed the code to clear
the whole layout instead, and manually set up the name edit field.
Due to the change triggering a rebuild of the class members, the
property pointer became roaming.
Rearranged the conversion to and from "property value" to "export
value", such that the original custom class information can be used when
de-serializing the members of that class. This was necessary to
correctly load nested custom classes and enums, because the custom type
is not saved out for member values.

It should also fix cases where the type is lost. In the JSON format, the
information about whether a property value is a path or an object
reference is not saved on member values of custom classes.
They are exported as a QVariantMap, which is now supported by the
LuaTableWriter.
Object types now need to be loaded after the loading of the custom
property types.
There's probably more that should be said about this, but this'll do
for now.
@bjorn bjorn force-pushed the wip/custom-class-properties branch from 5547586 to 2b61595 Compare December 23, 2021 12:09
@bjorn bjorn merged commit 42ce14a into master Dec 23, 2021
@bjorn bjorn deleted the wip/custom-class-properties branch December 23, 2021 12:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for nested (dictionary-type) properties
1 participant