Skip to content

Commit

Permalink
Entity::getKeyValuePairs() is no longer a virtual method
Browse files Browse the repository at this point in the history
This utility method is now implemented on Entity itself as a wrapper around the
virtual forEachKeyValue() method.
  • Loading branch information
Matthew Mott committed Jan 30, 2021
1 parent 82fa3af commit 29dc4e5
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 32 deletions.
28 changes: 20 additions & 8 deletions include/ientity.h
Expand Up @@ -7,6 +7,8 @@
#include "inameobserver.h"
#include <functional>

#include "string/predicate.h"

class IEntityClass;
typedef std::shared_ptr<IEntityClass> IEntityClassPtr;
typedef std::shared_ptr<const IEntityClass> IEntityClassConstPtr;
Expand Down Expand Up @@ -169,12 +171,12 @@ class Entity
virtual bool isInherited(const std::string& key) const = 0;

/**
* Return the list of Key/Value pairs matching the given prefix, case ignored.
* \brief Return the list of keyvalues matching the given prefix.
*
* This method performs a search for all spawnargs whose key
* matches the given prefix, with a suffix consisting of zero or more
* arbitrary characters. For example, if "target" were specified as the
* prefix, the list would include "target", "target0", "target127" etc.
* This method performs a search for all spawnargs whose key matches the
* given prefix, with a suffix consisting of zero or more arbitrary
* characters. For example, if "target" were specified as the prefix, the
* list would include "target", "target0", "target127" etc.
*
* This operation may not have high performance, due to the need to scan
* for matching names, therefore should not be used in performance-critical
Expand All @@ -184,10 +186,20 @@ class Entity
* The prefix to search for, interpreted case-insensitively.
*
* @return
* A list of KeyValue pairs matching the provided prefix. This
* list will be empty if there were no matches.
* A list of KeyValue pairs matching the provided prefix. This list will be
* empty if there were no matches.
*/
virtual KeyValuePairs getKeyValuePairs(const std::string& prefix) const = 0;
KeyValuePairs getKeyValuePairs(const std::string& prefix) const
{
KeyValuePairs list;

forEachKeyValue([&](const std::string& k, const std::string& v) {
if (string::istarts_with(k, prefix))
list.push_back(std::make_pair(k, v));
});

return list;
}

/** greebo: Returns true if the entity is a model. For Doom3, this is
* usually true when the classname == "func_static" and
Expand Down
18 changes: 0 additions & 18 deletions radiantcore/entity/SpawnArgs.cpp
Expand Up @@ -204,24 +204,6 @@ void SpawnArgs::forEachAttachment(AttachmentFunc func) const
_attachments.forEachAttachment(func);
}

Entity::KeyValuePairs SpawnArgs::getKeyValuePairs(const std::string& prefix) const
{
KeyValuePairs list;

for (KeyValues::const_iterator i = _keyValues.begin(); i != _keyValues.end(); ++i)
{
// If the prefix matches, add to list
if (string::istarts_with(i->first, prefix))
{
list.push_back(
std::pair<std::string, std::string>(i->first, i->second->get())
);
}
}

return list;
}

EntityKeyValuePtr SpawnArgs::getEntityKeyValue(const std::string& key)
{
KeyValues::const_iterator found = find(key);
Expand Down
3 changes: 0 additions & 3 deletions radiantcore/entity/SpawnArgs.h
Expand Up @@ -67,9 +67,6 @@ class SpawnArgs: public Entity
bool isInherited(const std::string& key) const override;
void forEachAttachment(AttachmentFunc func) const override;

// Get all KeyValues matching the given prefix.
KeyValuePairs getKeyValuePairs(const std::string& prefix) const override;

bool isWorldspawn() const override;
bool isContainer() const override;
void setIsContainer(bool isContainer);
Expand Down
38 changes: 35 additions & 3 deletions test/Entity.cpp
Expand Up @@ -162,12 +162,44 @@ TEST_F(EntityTest, EnumerateInheritedSpawnargs)
EXPECT_EQ(keyValues["noshadows"], "0");
}

TEST_F(EntityTest, GetKeyValuePairs)
{
auto torch = createByClassName("atdm:torch_brazier");
auto& spawnArgs = torch->getEntity();

using Pair = Entity::KeyValuePairs::value_type;

// Retrieve single spawnargs as single-element lists of pairs
auto classNamePairs = spawnArgs.getKeyValuePairs("classname");
EXPECT_EQ(classNamePairs.size(), 1);
EXPECT_EQ(classNamePairs[0], Pair("classname", "atdm:torch_brazier"));

auto namePairs = spawnArgs.getKeyValuePairs("name");
EXPECT_EQ(namePairs.size(), 1);
EXPECT_EQ(namePairs[0], Pair("name", "atdm_torch_brazier_1"));

// Add some spawnargs with a common prefix
const StringMap SR_KEYS{
{"sr_type_1", "blah"},
{"sr_type_2", "bleh"},
{"sR_tYpE_a", "123"},
{"SR_type_1a", "0 123 -120"},
};
for (const auto& pair: SR_KEYS)
spawnArgs.setKeyValue(pair.first, pair.second);

// Confirm all added prefix keys are found regardless of case
auto srPairs = spawnArgs.getKeyValuePairs("sr_type");
EXPECT_EQ(srPairs.size(), SR_KEYS.size());
for (const auto& pair: srPairs)
EXPECT_EQ(SR_KEYS.at(pair.first), pair.second);
}

TEST_F(EntityTest, CreateAttachedLightEntity)
{
// Create the torch entity which has an attached light
auto torchCls = GlobalEntityClassManager().findClass("atdm:torch_brazier");
auto torch = GlobalEntityModule().createEntity(torchCls);
EXPECT_TRUE(torch);
auto torch = createByClassName("atdm:torch_brazier");
ASSERT_TRUE(torch);

// Check that the attachment spawnargs are present
const Entity& spawnArgs = torch->getEntity();
Expand Down

0 comments on commit 29dc4e5

Please sign in to comment.