Skip to content

Commit

Permalink
#5231: Move connect entities algorithm from EntityCreator interface t…
Browse files Browse the repository at this point in the history
…o namespace selection::algorithm.
  • Loading branch information
codereader committed May 17, 2020
1 parent 0eca409 commit 638e918
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 54 deletions.
9 changes: 3 additions & 6 deletions include/ientity.h
Expand Up @@ -317,7 +317,7 @@ class ITargetManager
};
typedef std::shared_ptr<ITargetManager> ITargetManagerPtr;

const std::string MODULE_ENTITYCREATOR("Doom3EntityCreator");
const char* const MODULE_ENTITYCREATOR("Doom3EntityCreator");

/**
* \brief
Expand All @@ -332,15 +332,12 @@ class EntityCreator :
/// Create an entity node with the given entity class.
virtual IEntityNodePtr createEntity(const IEntityClassPtr& eclass) = 0;

/// Connect the two given entity nodes using the "target" system.
virtual void connectEntities(const scene::INodePtr& source,
const scene::INodePtr& target) = 0;

// Constructs a new targetmanager instance (used by root nodes)
virtual ITargetManagerPtr createTargetManager() = 0;
};

inline EntityCreator& GlobalEntityCreator() {
inline EntityCreator& GlobalEntityCreator()
{
// Cache the reference locally
static EntityCreator& _entityCreator(
*std::static_pointer_cast<EntityCreator>(
Expand Down
43 changes: 0 additions & 43 deletions radiant/entity/EntityCreator.cpp
Expand Up @@ -102,49 +102,6 @@ IEntityNodePtr Doom3EntityCreator::createEntity(const IEntityClassPtr& eclass)
return node;
}

/* Connect two entities using a "target" key.
*/
void Doom3EntityCreator::connectEntities(const scene::INodePtr& source,
const scene::INodePtr& target)
{
// Obtain both entities
Entity* e1 = Node_getEntity(source);
Entity* e2 = Node_getEntity(target);

// Check entities are valid
if (e1 == NULL || e2 == NULL) {
rError() << "entityConnectSelected: both of the selected instances must be an entity\n";
return;
}

// Check entities are distinct
if (e1 == e2) {
rError() << "entityConnectSelected: the selected instances must not both be from the same entity\n";
return;
}

// Start the scoped undo session
UndoableCommand undo("entityConnectSelected");

// Find the first unused target key on the source entity
for (int i = 0; i < 1024; ++i) {

// Construct candidate key by appending number to "target"
std::string targetKey = fmt::format("target{0:d}", i);

// If the source entity does not have this key, add it and finish,
// otherwise continue looping
if (e1->getKeyValue(targetKey).empty())
{
e1->setKeyValue(targetKey, e2->getKeyValue("name"));
break;
}
}

// Redraw the scene
SceneChangeNotify();
}

ITargetManagerPtr Doom3EntityCreator::createTargetManager()
{
return std::make_shared<TargetManager>();
Expand Down
1 change: 0 additions & 1 deletion radiant/entity/EntityCreator.h
Expand Up @@ -14,7 +14,6 @@ class Doom3EntityCreator :

// EntityCreator implementation
IEntityNodePtr createEntity(const IEntityClassPtr& eclass) override;
void connectEntities(const scene::INodePtr& source, const scene::INodePtr& target) override;
ITargetManagerPtr createTargetManager() override;

// RegisterableModule implementation
Expand Down
43 changes: 39 additions & 4 deletions radiant/selection/algorithm/Entity.cpp
@@ -1,5 +1,6 @@
#include "Entity.h"

#include <limits>
#include "i18n.h"
#include "itransformable.h"
#include "selectionlib.h"
Expand Down Expand Up @@ -178,10 +179,44 @@ void connectSelectedEntities(const cmd::ArgumentList& args)
{
if (GlobalSelectionSystem().countSelected() == 2)
{
GlobalEntityCreator().connectEntities(
GlobalSelectionSystem().penultimateSelected(), // source
GlobalSelectionSystem().ultimateSelected() // target
);
// Obtain both entities
Entity* e1 = Node_getEntity(GlobalSelectionSystem().penultimateSelected()); // source
Entity* e2 = Node_getEntity(GlobalSelectionSystem().ultimateSelected()); // target

// Check entities are valid
if (e1 == nullptr || e2 == nullptr)
{
rError() << "connectSelectedEntities: both of the selected instances must be entities" << std::endl;
return;
}

// Check entities are distinct
if (e1 == e2)
{
rError() << "connectSelectedEntities: the selected entities must be different" << std::endl;
return;
}

// Start the scoped undo session
UndoableCommand undo("entityConnectSelected");

// Find the first unused target key on the source entity
for (unsigned int i = 0; i < std::numeric_limits<unsigned int>::max(); ++i)
{
// Construct candidate key by appending number to "target"
auto targetKey = fmt::format("target{0:d}", i);

// If the source entity does not have this key, add it and finish,
// otherwise continue looping
if (e1->getKeyValue(targetKey).empty())
{
e1->setKeyValue(targetKey, e2->getKeyValue("name"));
break;
}
}

// Redraw the scene
SceneChangeNotify();
}
else
{
Expand Down

0 comments on commit 638e918

Please sign in to comment.