Skip to content

Commit

Permalink
Update new / removed entity GUI events (#1213)
Browse files Browse the repository at this point in the history
Signed-off-by: Louise Poubel <[email protected]>
  • Loading branch information
chapulina authored Nov 17, 2021
1 parent 97f2e9c commit ee90892
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 50 deletions.
72 changes: 33 additions & 39 deletions include/ignition/gazebo/gui/GuiEvents.hh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include <utility>
#include <vector>
#include <ignition/math/Vector3.hh>
#include <ignition/utils/ImplPtr.hh>
#include "ignition/gazebo/gui/Export.hh"
#include "ignition/gazebo/Entity.hh"
#include "ignition/gazebo/config.hh"

Expand All @@ -38,7 +40,7 @@ inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
namespace events
{
/// \brief Event that notifies when new entities have been selected.
class EntitiesSelected : public QEvent
class IGNITION_GAZEBO_GUI_VISIBLE EntitiesSelected : public QEvent
{
/// \brief Constructor
/// \param[in] _entities All the selected entities
Expand Down Expand Up @@ -76,7 +78,7 @@ namespace events
};

/// \brief Event that notifies when all entities have been deselected.
class DeselectAllEntities : public QEvent
class IGNITION_GAZEBO_GUI_VISIBLE DeselectAllEntities : public QEvent
{
/// \brief Constructor
/// \param[in] _fromUser True if the event was directly generated by the
Expand All @@ -100,68 +102,60 @@ namespace events
private: bool fromUser{false};
};

/// \brief Event that contains newly created and removed entities
class AddedRemovedEntities : public QEvent
/// \brief Event that contains entities newly created or removed from the
/// GUI, but that aren't present on the server yet.
/// \sa NewRemovedEntities
class IGNITION_GAZEBO_GUI_VISIBLE GuiNewRemovedEntities : public QEvent
{
/// \brief Constructor
/// \param[in] _newEntities Set of newly created entities
/// \param[in] _removedEntities Set of recently removed entities
public: AddedRemovedEntities(const std::set<Entity> &_newEntities,
const std::set<Entity> &_removedEntities)
: QEvent(kType), newEntities(_newEntities),
removedEntities(_removedEntities)
{
}
public: GuiNewRemovedEntities(const std::set<Entity> &_newEntities,
const std::set<Entity> &_removedEntities);

/// \brief Get the set of newly created entities
public: const std::set<Entity> &NewEntities() const
{
return this->newEntities;
}
public: const std::set<Entity> &NewEntities() const;

/// \brief Get the set of recently removed entities
public: const std::set<Entity> &RemovedEntities() const
{
return this->removedEntities;
}
public: const std::set<Entity> &RemovedEntities() const;

/// \brief Unique type for this event.
static const QEvent::Type kType = QEvent::Type(QEvent::User + 3);

/// \brief Set of newly created entities
private: std::set<Entity> newEntities;

/// \brief Set of recently removed entities
private: std::set<Entity> removedEntities;
/// \internal
/// \brief Private data pointer
IGN_UTILS_IMPL_PTR(dataPtr)
};

/// \brief Event that notifies when new entities have been removed.
class RemovedEntities : public QEvent
/// \brief Event that notifies when new entities have been created or removed
/// on the server. This is a duplication of what `GuiSystem`s would get from
/// `EachNew` / `EachRemoved` ECM calls.
/// \sa GuiNewRemovedEntities
class IGNITION_GAZEBO_GUI_VISIBLE NewRemovedEntities : public QEvent
{
/// \brief Constructor
/// \param[in] _entities All the removed entities
public: explicit RemovedEntities(const std::vector<Entity> &_entities)
: QEvent(kType), entities(_entities)
{
}
/// \param[in] _newEntities Set of newly created entities
/// \param[in] _removedEntities Set of recently removed entities
public: NewRemovedEntities(const std::set<Entity> &_newEntities,
const std::set<Entity> &_removedEntities);

/// \brief Get the data sent with the event.
/// \return The entities being removed.
public: std::vector<Entity> Data() const
{
return this->entities;
}
/// \brief Get the set of newly created entities
public: const std::set<Entity> &NewEntities() const;

/// \brief Get the set of recently removed entities
public: const std::set<Entity> &RemovedEntities() const;

/// \brief Unique type for this event.
static const QEvent::Type kType = QEvent::Type(QEvent::User + 4);

/// \brief The removed entities.
private: std::vector<Entity> entities;
/// \internal
/// \brief Private data pointer
IGN_UTILS_IMPL_PTR(dataPtr)
};

/// \brief True if a transform control is currently active (translate /
/// rotate / scale). False if we're in selection mode.
class TransformControlModeActive : public QEvent
class IGNITION_GAZEBO_GUI_VISIBLE TransformControlModeActive : public QEvent
{
/// \brief Constructor
/// \param[in] _tranformModeActive is the transform control mode active
Expand Down
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
set (gui_sources
AboutDialogHandler.cc
Gui.cc
GuiEvents.cc
GuiFileHandler.cc
GuiRunner.cc
PathManager.cc
)

set (gtest_sources
Gui_TEST.cc
GuiEvents_TEST.cc
)

add_subdirectory(plugins)
Expand Down
85 changes: 85 additions & 0 deletions src/gui/GuiEvents.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#include "ignition/gazebo/gui/GuiEvents.hh"

class ignition::gazebo::gui::events::GuiNewRemovedEntities::Implementation
{
/// \brief Set of newly created entities
public: std::set<Entity> newEntities;

/// \brief Set of recently removed entities
public: std::set<Entity> removedEntities;
};

class ignition::gazebo::gui::events::NewRemovedEntities::Implementation
{
/// \brief Set of newly created entities
public: std::set<Entity> newEntities;

/// \brief Set of recently removed entities
public: std::set<Entity> removedEntities;
};

using namespace ignition;
using namespace gazebo;
using namespace gui;
using namespace events;

/////////////////////////////////////////////////
GuiNewRemovedEntities::GuiNewRemovedEntities(
const std::set<Entity> &_newEntities,
const std::set<Entity> &_removedEntities)
: QEvent(kType), dataPtr(utils::MakeImpl<Implementation>())
{
this->dataPtr->newEntities = _newEntities;
this->dataPtr->removedEntities = _removedEntities;
}

/////////////////////////////////////////////////
const std::set<Entity> &GuiNewRemovedEntities::NewEntities() const
{
return this->dataPtr->newEntities;
}

/////////////////////////////////////////////////
const std::set<Entity> &GuiNewRemovedEntities::RemovedEntities() const
{
return this->dataPtr->removedEntities;
}

/////////////////////////////////////////////////
NewRemovedEntities::NewRemovedEntities(
const std::set<Entity> &_newEntities,
const std::set<Entity> &_removedEntities)
: QEvent(kType), dataPtr(utils::MakeImpl<Implementation>())
{
this->dataPtr->newEntities = _newEntities;
this->dataPtr->removedEntities = _removedEntities;
}

/////////////////////////////////////////////////
const std::set<Entity> &NewRemovedEntities::NewEntities() const
{
return this->dataPtr->newEntities;
}

/////////////////////////////////////////////////
const std::set<Entity> &NewRemovedEntities::RemovedEntities() const
{
return this->dataPtr->removedEntities;
}
67 changes: 67 additions & 0 deletions src/gui/GuiEvents_TEST.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#include <gtest/gtest.h>

#include "ignition/gazebo/test_config.hh"
#include "ignition/gazebo/gui/GuiEvents.hh"

using namespace ignition;
using namespace gazebo;
using namespace gui;

/////////////////////////////////////////////////
TEST(GuiEventsTest, GuiNewRemovedEntities)
{
events::GuiNewRemovedEntities event({1, 2, 3}, {4, 5});

EXPECT_LT(QEvent::User, event.type());

auto addedEntities = event.NewEntities();
EXPECT_EQ(3u, addedEntities.size());
EXPECT_NE(addedEntities.find(1), addedEntities.end());
EXPECT_NE(addedEntities.find(2), addedEntities.end());
EXPECT_NE(addedEntities.find(3), addedEntities.end());
EXPECT_EQ(addedEntities.find(100), addedEntities.end());

auto removedEntities = event.RemovedEntities();
EXPECT_EQ(2u, removedEntities.size());
EXPECT_NE(removedEntities.find(4), removedEntities.end());
EXPECT_NE(removedEntities.find(5), removedEntities.end());
EXPECT_EQ(removedEntities.find(6), removedEntities.end());
}

/////////////////////////////////////////////////
TEST(GuiEventsTest, NewRemovedEntities)
{
events::NewRemovedEntities event({1, 2, 3}, {4, 5});

EXPECT_LT(QEvent::User, event.type());

auto addedEntities = event.NewEntities();
EXPECT_EQ(3u, addedEntities.size());
EXPECT_NE(addedEntities.find(1), addedEntities.end());
EXPECT_NE(addedEntities.find(2), addedEntities.end());
EXPECT_NE(addedEntities.find(3), addedEntities.end());
EXPECT_EQ(addedEntities.find(100), addedEntities.end());

auto removedEntities = event.RemovedEntities();
EXPECT_EQ(2u, removedEntities.size());
EXPECT_NE(removedEntities.find(4), removedEntities.end());
EXPECT_NE(removedEntities.find(5), removedEntities.end());
EXPECT_EQ(removedEntities.find(6), removedEntities.end());
}
6 changes: 4 additions & 2 deletions src/gui/plugins/entity_tree/EntityTree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -556,13 +556,15 @@ bool EntityTree::eventFilter(QObject *_obj, QEvent *_event)
}
}
else if (_event->type() ==
ignition::gazebo::gui::events::AddedRemovedEntities::kType)
ignition::gazebo::gui::events::GuiNewRemovedEntities::kType)
{
std::lock_guard<std::mutex> lock(this->dataPtr->newRemovedEntityMutex);
auto addedRemovedEvent =
reinterpret_cast<gui::events::AddedRemovedEntities *>(_event);
reinterpret_cast<gui::events::GuiNewRemovedEntities *>(_event);
if (addedRemovedEvent)
{
// TODO(chapulina) Make these entities visually different from entities
// created from the server.
for (auto entity : addedRemovedEvent->NewEntities())
this->dataPtr->newEntities.insert(entity);

Expand Down
19 changes: 14 additions & 5 deletions src/gui/plugins/scene_manager/GzSceneManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

#include "GzSceneManager.hh"

#include <vector>
#include <set>

#include <ignition/common/Profiler.hh>
#include <ignition/gui/Application.hh>
Expand Down Expand Up @@ -85,16 +85,25 @@ void GzSceneManager::Update(const UpdateInfo &_info,
this->dataPtr->renderUtil.UpdateECM(_info, _ecm);
this->dataPtr->renderUtil.UpdateFromECM(_info, _ecm);

// Emit entities removed event
std::vector<Entity> removed;
// Emit entities created / removed event for gui::Plugins which don't have
// direct access to the ECM.
std::set<Entity> created;
_ecm.EachNew<components::Name>(
[&](const Entity &_entity, const components::Name *)->bool
{
created.insert(_entity);
return true;
});
std::set<Entity> removed;
_ecm.EachRemoved<components::Name>(
[&](const Entity &_entity, const components::Name *)->bool
{
removed.push_back(_entity);
removed.insert(_entity);
return true;
});

ignition::gazebo::gui::events::RemovedEntities removedEvent(removed);
ignition::gazebo::gui::events::NewRemovedEntities removedEvent(
created, removed);
ignition::gui::App()->sendEvent(
ignition::gui::App()->findChild<ignition::gui::MainWindow *>(),
&removedEvent);
Expand Down
8 changes: 4 additions & 4 deletions src/gui/plugins/select_entities/SelectEntities.cc
Original file line number Diff line number Diff line change
Expand Up @@ -574,13 +574,13 @@ bool SelectEntities::eventFilter(QObject *_obj, QEvent *_event)
}
}
else if (_event->type() ==
ignition::gazebo::gui::events::RemovedEntities::kType)
ignition::gazebo::gui::events::NewRemovedEntities::kType)
{
if (!this->dataPtr->wireBoxes.empty())
{
auto removedEvent =
reinterpret_cast<gui::events::RemovedEntities *>(_event);
for (auto &entity : removedEvent->Data())
auto event =
reinterpret_cast<gui::events::NewRemovedEntities *>(_event);
for (auto &entity : event->RemovedEntities())
{
auto wireBoxIt = this->dataPtr->wireBoxes.find(entity);
if (wireBoxIt != this->dataPtr->wireBoxes.end())
Expand Down

0 comments on commit ee90892

Please sign in to comment.