Skip to content

Commit

Permalink
Merge pull request #203 from naivisoftware/grouping_rtti_optimizations
Browse files Browse the repository at this point in the history
Grouping & Napkin Optimizations
  • Loading branch information
cklosters committed Jun 29, 2022
2 parents 7c4fd5a + b4bbf43 commit 1d380c9
Show file tree
Hide file tree
Showing 68 changed files with 2,649 additions and 1,275 deletions.
30 changes: 30 additions & 0 deletions core/src/nap/group.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "group.h"

// Group Interface
RTTI_DEFINE_BASE(nap::IGroup)

// Define (common) Resource Group
DEFINE_GROUP(nap::ResourceGroup)

namespace nap
{

IGroup::IGroup(rtti::TypeInfo memberType) : mMemberType(memberType)
{ }


rttr::property IGroup::getMembersProperty() const
{
return get_type().get_property(IGroup::membersPropertyName());
}


rttr::property IGroup::getChildrenProperty() const
{
return get_type().get_property(IGroup::childrenPropertyName());
}
}
202 changes: 202 additions & 0 deletions core/src/nap/group.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#pragma once

// Local Includes
#include "resource.h"
#include "resourceptr.h"
#include "rtti/objectptr.h"
#include "resource.h"

namespace nap
{
//////////////////////////////////////////////////////////////////////////
// Group Interface
//////////////////////////////////////////////////////////////////////////

/**
* Group interface
*/
class NAPAPI IGroup : public Resource
{
RTTI_ENABLE(Resource)
public:
/**
* @param memberType the group member type
*/
IGroup(rtti::TypeInfo memberType);

/**
* @return group member type
*/
rtti::TypeInfo getMemberType() const { return mMemberType; }

/**
* @return member property name
*/
static constexpr const char* membersPropertyName() { return "Members"; }

/**
* @return 'Members' rtti property
*/
rttr::property getMembersProperty() const;

/**
* @return children property name
*/
static constexpr const char* childrenPropertyName() { return "Children"; }

/**
* @return 'Children' rtti property
*/
rttr::property getChildrenProperty() const;

private:
rtti::TypeInfo mMemberType;
};


//////////////////////////////////////////////////////////////////////////
// Group
//////////////////////////////////////////////////////////////////////////

/**
* Groups together a set of objects of a specific type.
*/
template<typename T>
class Group : public IGroup
{
RTTI_ENABLE(IGroup)
public:
/**
* Constructs a group with members of type T
*/
Group() : IGroup(RTTI_OF(T)) { }

/**
* Initialize this group
* @param errorState contains the error if initialization fails
* @return if initialization succeeded
*/
virtual bool init(utility::ErrorState& errorState) override;

/**
* Attempts to find a member in this group with the given ID.
* @param id member ID
* @param attempt to find member in child groups as well
* @return member with the given ID, nullptr if not found
*/
rtti::ObjectPtr<T> findObject(const std::string& id) const;

/**
* Attempts to find a member in this group and all child groups with the given ID.
* @param id member ID
* @return member with the given ID, nullptr if not found
*/
rtti::ObjectPtr<T> findObjectRecursive(const std::string& id) const;

/**
* Attempts to find a member in this group, with the given ID, of type M
* @param id member ID
* @return member with the given ID, nullptr if not found or not of the given type
*/
template<typename M>
rtti::ObjectPtr<M> findObject(const std::string& id) const;

/**
* Attempts to find a member in this group, and all child groups, with the given ID of type M
* @param id member ID
* @return member with the given ID, nullptr if not found or not of the given type
*/
template<typename M>
rtti::ObjectPtr<M> findObjectRecursive(const std::string& id) const;

std::vector<rtti::ObjectPtr<T>> mMembers; ///< Property: 'Members' The members that belong to this group
std::vector<rtti::ObjectPtr<Group<T>>> mChildren; ///< Property: 'Children' The sub groups

private:
std::unordered_map<std::string, T*> mMap; ///< Maps ID to member for faster lookup
};


//////////////////////////////////////////////////////////////////////////
// Group Definitions
//////////////////////////////////////////////////////////////////////////

// Default NAP (resource) group.
using ResourceGroup = Group<Resource>;


//////////////////////////////////////////////////////////////////////////
// Template Definitions
//////////////////////////////////////////////////////////////////////////

template<typename T>
bool nap::Group<T>::init(utility::ErrorState& errorState)
{
mMap.reserve(mMembers.size());
for (const auto& member : mMembers)
{
mMap.emplace(std::make_pair(member->mID, member.get()));
}
return true;
}

template<typename T>
rtti::ObjectPtr<T> nap::Group<T>::findObject(const std::string& id) const
{
// Find in this group
auto it = mMap.find(id);
if (it != mMap.end())
return rtti::ObjectPtr<T>(it->second);
return nullptr;
}

template<typename T>
rtti::ObjectPtr<T> nap::Group<T>::findObjectRecursive(const std::string& id) const
{
// Find in this group
rtti::ObjectPtr<T> object = findObject(id);
if (object != nullptr)
return object;

// Find in sub-groups
for (const auto& child : mChildren)
{
rtti::ObjectPtr<T> object = child->findObject(id);
if (object == nullptr)
continue;
return object;
}
return nullptr;
}

template<typename T>
template<typename M>
rtti::ObjectPtr<M> nap::Group<T>::findObject(const std::string& id) const
{
return rtti::ObjectPtr<M>(findObject(id));
}

template<typename T>
template<typename M>
rtti::ObjectPtr<M> nap::Group<T>::findObjectRecursive(const std::string& id) const
{
return rtti::ObjectPtr<M>(findObjectRecursive(id));
}
}


/**
* Use this macro to register your own group.
* ~~~~~{.cpp}
* DEFINE_GROUP(nap::ResourceGroup)
* ~~~~~
*/
#define DEFINE_GROUP(Type) \
RTTI_BEGIN_CLASS(Type) \
RTTI_PROPERTY(nap::IGroup::membersPropertyName(), &Type::mMembers, nap::rtti::EPropertyMetaData::Embedded | nap::rtti::EPropertyMetaData::ReadOnly) \
RTTI_PROPERTY(nap::IGroup::childrenPropertyName(), &Type::mChildren, nap::rtti::EPropertyMetaData::Embedded | nap::rtti::EPropertyMetaData::ReadOnly) \
RTTI_END_CLASS
4 changes: 2 additions & 2 deletions modules/naprender/src/geometryfromfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ namespace nap
*
* For example: Say the file contains 2 meshes, mesh 1 has color data but mesh 2 does not. This means that the color
* data of mesh 2 will be initialized to 0. If both meshes carry no color data at all no color attribute is created.
*
* The operator attempts to extract Vertex, Normal, Color, UV and Tangent information. Up to 8 Color and
*
* The operator attempts to extract Vertex, Normal, Color, UV and Tangent information. Up to 8 Color and
* UV channels are supported. You can choose to generate normals, tangents and bi-tangents. These are only
* generated when not already present on the mesh and 'GenerateNormals' / 'CalculateTangents' is set to true.
*
Expand Down
3 changes: 1 addition & 2 deletions modules/napsequence/src/sequenceplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,9 @@ namespace nap
mReadObjectIDs.clear();
for (auto& read_object : result.mReadObjects)
{
//
if (read_object->get_type().is_derived_from<Sequence>())
{
mSequence = dynamic_cast<Sequence*>(read_object.get());
mSequence = static_cast<Sequence*>(read_object.get());
}

mReadObjectIDs.emplace(read_object->mID);
Expand Down
2 changes: 1 addition & 1 deletion modules/napsequencegui/src/sequenceeditorguiclipboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ namespace nap
for (auto& read_object : result.mReadObjects)
{
if (read_object->get_type().is_derived_from<T>())
root_object = dynamic_cast<T*>(read_object.get());
root_object = static_cast<T*>(read_object.get());
createdObjects.emplace_back(std::move(read_object));
}

Expand Down
1 change: 0 additions & 1 deletion modules/napsequencegui/src/sequenceeventtrackview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,6 @@ namespace nap
{
auto& eventController = getEditor().getController<SequenceControllerEvent>();
const auto *eventSegment = dynamic_cast<const SequenceTrackSegmentEventBase*>(eventController.getSegment(action->mTrackID, action->mSegmentID));

assert(eventSegment != nullptr);

if( eventSegment != nullptr)
Expand Down
4 changes: 2 additions & 2 deletions qt/src/napqt/autosettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void AutoSettings::storeRecursive(QWidget& w, QSettings& s) const

for (auto child : w.children())
{
auto widget = dynamic_cast<QWidget*>(child);
auto widget = qobject_cast<QWidget*>(child);
if (widget != nullptr)
storeRecursive(*widget, s);
}
Expand All @@ -60,7 +60,7 @@ void AutoSettings::restoreRecursive(QWidget& w, const QSettings& s) const

for (const auto child : w.children())
{
auto widget = dynamic_cast<QWidget*>(child);
auto widget = qobject_cast<QWidget*>(child);
if (widget != nullptr && !mExclusions.contains(widget))
restoreRecursive(*widget, s);
}
Expand Down
6 changes: 3 additions & 3 deletions qt/src/napqt/autosettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,21 +135,21 @@ namespace nap

void storeWidget(const QWidget& widget, const QString& key, QSettings& s) const override
{
auto w = dynamic_cast<const T*>(&widget);
auto w = qobject_cast<const T*>(&widget);
assert(w);
store(*w, key, s);
}

void restoreWidget(QWidget& widget, const QString& key, const QSettings& s) const override
{
auto w = dynamic_cast<T*>(&widget);
auto w = qobject_cast<T*>(&widget);
assert(w);
restore(*w, key, s);
}

bool canStore(const QWidget& widget) const override
{
return dynamic_cast<const T*>(&widget) != nullptr;
return qobject_cast<const T*>(&widget) != nullptr;
}
};

Expand Down
11 changes: 7 additions & 4 deletions qt/src/napqt/curveeditor/curveview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,12 @@ void HandleItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option

CurveSegmentItem& HandleItem::curveSegmentItem()
{
return *dynamic_cast<CurveSegmentItem*>(parentItem());
return *static_cast<CurveSegmentItem*>(parentItem());
}

const CurveSegmentItem& HandleItem::curveSegmentItem() const
{
return *dynamic_cast<CurveSegmentItem*>(parentItem());
return *static_cast<CurveSegmentItem*>(parentItem());
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1287,15 +1287,18 @@ const QList<PointHandleItem*> CurveView::pointsFromSelection()
for (auto item : scene()->selectedItems())
{
// If we have a point, include and on to the next
auto point = dynamic_cast<PointHandleItem*>(item);
assert(dynamic_cast<HandleItem*>(item) != nullptr);
auto handle_item = static_cast<HandleItem*>(item);

auto point = qobject_cast<PointHandleItem*>(handle_item);
if (point && !points.contains(point))
{
points << point;
continue;
}

// No point, get point from selected tangent
auto tan = dynamic_cast<TangentHandleItem*>(item);
auto tan = qobject_cast<TangentHandleItem*>(handle_item);
if (tan)
{
auto pt = &tan->pointHandle();
Expand Down
2 changes: 2 additions & 0 deletions qt/src/napqt/curveeditor/curveview.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ namespace nap
*/
class PointHandleItem : public HandleItem
{
Q_OBJECT
public:
explicit PointHandleItem(CurveSegmentItem& parent);

Expand All @@ -87,6 +88,7 @@ namespace nap
*/
class TangentHandleItem : public HandleItem
{
Q_OBJECT
public:
explicit TangentHandleItem(CurveSegmentItem& parent);
void setValue(const QPointF& value) { mValue = value; }
Expand Down
2 changes: 1 addition & 1 deletion qt/src/napqt/curveeditor/standardcurve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ void nap::qt::StandardCurve::removePoint(int index)

StandardCurveModel* StandardCurve::model()
{
return dynamic_cast<StandardCurveModel*>(parent());
return qobject_cast<StandardCurveModel*>(parent());
}

void StandardCurve::removePoints(const QList<int>& indices)
Expand Down
6 changes: 5 additions & 1 deletion qt/src/napqt/fileselector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ void FileSelector::onBrowseButtonClicked()
{
QString dir = getFilename().isEmpty() ? "." : QFileInfo(getFilename()).path();

QString f = QFileDialog::getOpenFileName(this, "Select File", dir, mFileFilter);
#ifdef __linux__
QString f = QFileDialog::getOpenFileName(this, "Select File", dir, mFileFilter, nullptr, QFileDialog::DontUseNativeDialog);
#else
QString f = QFileDialog::getOpenFileName(this, "Select File", dir, mFileFilter, nullptr);
#endif
if (f.isEmpty())
return;

Expand Down
2 changes: 1 addition & 1 deletion qt/src/napqt/filterpopup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ void FilterPopup::updateSize()
auto& model = mFilterTree.getProxyModel();

// Ensure there is always something selected
auto& tree = *dynamic_cast<FilterTree_*>(&mFilterTree.getTreeView());
auto& tree = *qobject_cast<FilterTree_*>(&mFilterTree.getTreeView());
if (!tree.currentIndex().isValid())
tree.setCurrentIndex(model.index(0, 0));

Expand Down
Loading

0 comments on commit 1d380c9

Please sign in to comment.