Use enum to identify AbstractAspect
ClosedPublic

Authored by croick on Jan 20 2019, 9:25 PM.

Details

Summary
  • replace string class name checks by an enum version

Reduce code in GuiObserver

  • use template function for dock widget creation
  • use template function for aspect list casting
Test Plan

Select objects in the project explorer and observe
the dock widget.

Diff Detail

Repository
R262 LabPlot
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
croick created this revision.Jan 20 2019, 9:25 PM
Restricted Application added a project: KDE Edu. · View Herald TranscriptJan 20 2019, 9:25 PM
Restricted Application added a subscriber: kde-edu. · View Herald Transcript
croick requested review of this revision.Jan 20 2019, 9:25 PM

Would you agree on such a change?
case "Worksheet"_hash: is still human-readable (compare to if (className == "Worksheet").
The very unlikely case of a hash collision would appear at compile time (if new dock widgets are introduced).
On the other hand the selection of the right dock is now more efficient than before.

asemke added a subscriber: asemke.Jan 22 2019, 9:16 PM

Would you agree on such a change?

Thanks for addressing this. This part grew historically with the help of copy&paste. It's time to do some cleanup here :-)

case "Worksheet"_hash: is still human-readable (compare to if (className == "Worksheet").
The very unlikely case of a hash collision would appear at compile time (if new dock widgets are introduced).

It's human readable but it's even more readable if we use somethink like this:

enum className {Spreadsheet, Worksheet, ...};
map classNames{ {"Spreadsheet", Spreadsheet}, ...};

switch (name)
     case Spreadsheet:
...

Here we'd would need to register every class name in the enum and to do the mapping of the string class name to the enum value. This would result in some additional maintenance (you need to know that you need to register the new class here) but at costs of better readability. And maybe we can use this (global) enum in future at other places where we probably do some dirty workarounds now because we don't have such an enum.

On the other hand the selection of the right dock is now more efficient than before.

I don't think the performance is relevant here. I'd rather go for a greater readability of the code. Performance-wise I'd say a simple lookup in the map as mentioned above is faster than the calculation of the hash.

Would you agree with such a solution?

asemke added inline comments.Jan 22 2019, 9:18 PM
src/kdefrontend/GuiObserver.cpp
129

let's name this raiseDockSetupConnect to make it explicit that this template functions does both - setup and connect.

asemke added inline comments.Jan 22 2019, 9:29 PM
src/kdefrontend/GuiObserver.cpp
363

as discussed in another email thread and in D18319, we planned to show and to allow to modify the first selected LiveDataSource or MQTTClient only. Do we need another template function?

I still prefer my solution ;)

But I agree, that the enum would be more consistent with the rest of the project. Actually, AbstractAspect could have a type() function that contains the actual type (like in AbstractFileFilter). That would entirely spare the use of a map and string comparisons, but would require touching 20 constructors or so.
What do you think?

src/kdefrontend/GuiObserver.cpp
363

I would first like to finish this and later remove the loops entirely in the other patch to save some work. So there will be no need for another function.

I still prefer my solution ;)

But I agree, that the enum would be more consistent with the rest of the project. Actually, AbstractAspect could have a type() function that contains the actual type (like in AbstractFileFilter). That would entirely spare the use of a map and string comparisons, but would require touching 20 constructors or so.
What do you think?

This would be the best solution I think. We'd maintain this global enum in AbstractAspect.h ("AspectType" maybe to be consistent with FileType in AbstractFileFilter) and use it in the constructors. No map required. But yes, we'd need to touch now some code. Also, every tyme we add a new enum value in AbstractAspect.h we'd need to basically re-compile the whole project since this header file is pulled either directly or indirectly in many places... But let's go for a consistent solution here and benefit from compile time checks. Would you like to do this change as part of this patch?

croick updated this revision to Diff 50352.Jan 26 2019, 9:20 PM
croick retitled this revision from Optimize and reduce code in GuiObserver to Use enum to identify AbstractAspect.
croick edited the summary of this revision. (Show Details)
  • use enum to identify AbstractAspects and use it throughout the project
croick marked an inline comment as done.Jan 26 2019, 9:29 PM

If I had known in advance...

I applied the type() identifier where I thought it reasonable.
The naming is still a little unfortunate, but I cannot name the enum elements as their corresponding classes, because then the compiler doesn't know whether the enum type is meant or the class. Do you have a better idea than a "Type" suffix?
In some place there are checks for a non-existant "FileDataSource". I deleted those for now, since I don't know what they are referring to. Is that called "LiveDataSource" now?

croick updated this revision to Diff 50354.Jan 26 2019, 9:37 PM
  • switch (fix) raiseDockSetupConnect and raiseDockSetup
asemke added a comment.EditedJan 27 2019, 10:09 AM

If I had known in advance...

I applied the type() identifier where I thought it reasonable.
The naming is still a little unfortunate, but I cannot name the enum elements as their corresponding classes, because then the compiler doesn't know whether the enum type is meant or the class. Do you have a better idea than a "Type" suffix?

Yes, the naming is sub-optimal somehow... I think what we're trying to achieve here is kind of compile time reflection capabilities where c++ is lacking a lot of support for. And we're trying to add new stuff on top of Qt's meta-object system which already tries to overcome some of the limitations of the c++ language.

Should we try to utilize QMetaClassInfo and simply set a new property "classtype" to the corresponding value of the new enum you introduced? With this we'd only need to add a Q_CLASSINFO line in every header and don't need to touch the constructors and the cpp files. At run-time, we read this value out of QMetaClassInfo, cast it to the enum and use it in the switch-case block. With this we can probably remove "Type" suffix from the enum values.

In some place there are checks for a non-existant "FileDataSource". I deleted those for now, since I don't know what they are referring to. Is that called "LiveDataSource" now?

Yes, FileDataSource was renamed to LiveDataSource later. Thanks for cleaning up here.

croick updated this revision to Diff 57587.May 5 2019, 10:46 AM
  • Rearrange AbstractAspect type enums
  • Transform AspectType enum into global enum class, rename items

Instead of an enum inside AbstractAspect, there now is an enum class outside of the class. This way, the items can be named properly.

QMetaClassInfo (const char*) and a mapping to enums would again be a source for new bugs once classes are renamed since there are no compile time checks.

asemke added inline comments.May 10 2019, 8:25 AM
src/backend/core/AbstractAspect.h
49

small typo - it should be "if".

142

we moved all small and one-line functions except of the tempate functions into the cpp file to keep the header more clean. The compiler will manage to inline these one-liners :-)

src/backend/core/AspectTreeModel.cpp
276–277

will the range-based for loop work here, too?

src/backend/datasources/projects/LabPlotProjectParser.cpp
40–43

list initialization also here as you did in AxisDock::setModel()?

src/backend/datasources/projects/OriginProjectParser.cpp
63–65

list initialization also here as you did in AxisDock::setModel()?

croick updated this revision to Diff 57932.May 12 2019, 2:45 PM
croick marked 5 inline comments as done.May 12 2019, 2:47 PM
croick added inline comments.
src/backend/core/AbstractAspect.h
49

That actually is an intended "if and only if" to make sure the list is extended correctly.

asemke accepted this revision.May 12 2019, 6:08 PM
This revision is now accepted and ready to land.May 12 2019, 6:08 PM
This revision was automatically updated to reflect the committed changes.