Skip to content

Commit

Permalink
#5613: Entity KeyValue objects now hold a reference to the owning Spa…
Browse files Browse the repository at this point in the history
…wnArgs instance. This is a preparation to notify the owner on Undo/Redo when just a single key value is being reverted to a previous state - right now the SpawnArgs owner doesn't get notified.
  • Loading branch information
codereader committed Oct 17, 2021
1 parent 0429c9c commit f060e71
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 22 deletions.
12 changes: 7 additions & 5 deletions radiantcore/entity/KeyValue.cpp
Expand Up @@ -6,15 +6,17 @@
namespace entity
{

KeyValue::KeyValue(const std::string& value, const std::string& empty) :
_value(value),
_emptyValue(empty),
_undo(_value, std::bind(&KeyValue::importState, this, std::placeholders::_1), "KeyValue")
KeyValue::KeyValue(SpawnArgs& owner, const std::string& value, const std::string& empty) :
_owner(owner),
_value(value),
_emptyValue(empty),
_undo(_value, std::bind(&KeyValue::importState, this, std::placeholders::_1), "KeyValue")
{
notify();
}

KeyValue::~KeyValue() {
KeyValue::~KeyValue()
{
assert(_observers.empty());
}

Expand Down
6 changes: 5 additions & 1 deletion radiantcore/entity/KeyValue.h
Expand Up @@ -10,6 +10,8 @@
namespace entity
{

class SpawnArgs;

/// \brief A key/value pair of strings.
///
/// - Notifies observers when value changes - value changes to "" on destruction.
Expand All @@ -19,6 +21,8 @@ class KeyValue :
public sigc::trackable
{
private:
SpawnArgs& _owner;

typedef std::vector<KeyObserver*> KeyObservers;
KeyObservers _observers;

Expand All @@ -29,7 +33,7 @@ class KeyValue :
sigc::connection _redoHandler;

public:
KeyValue(const std::string& value, const std::string& empty);
KeyValue(SpawnArgs& owner, const std::string& value, const std::string& empty);

~KeyValue();

Expand Down
26 changes: 10 additions & 16 deletions radiantcore/entity/SpawnArgs.cpp
Expand Up @@ -285,44 +285,38 @@ void SpawnArgs::notifyErase(const std::string& key, KeyValue& value)
void SpawnArgs::insert(const std::string& key, const KeyValuePtr& keyValue)
{
// Insert the new key at the end of the list
KeyValues::iterator i = _keyValues.insert(
_keyValues.end(),
KeyValuePair(key, keyValue)
);
auto& pair = _keyValues.emplace_back(key, keyValue);

// Dereference the iterator to get a KeyValue& reference and notify the observers
notifyInsert(key, *i->second);
notifyInsert(key, *pair.second);

if (_instanced)
{
i->second->connectUndoSystem(_undo.getUndoChangeTracker());
pair.second->connectUndoSystem(_undo.getUndoChangeTracker());
}
}

void SpawnArgs::insert(const std::string& key, const std::string& value)
{
// Try to lookup the key in the map
KeyValues::iterator i = find(key);
auto i = find(key);

if (i != _keyValues.end())
if (i != _keyValues.end())
{
// Key has been found
i->second->assign(value);
// Key has been found
i->second->assign(value);

// Notify observers of key change, using the found key as argument
// as the case of the incoming "key" might be different
// as the case of the incoming "key" might be different
notifyChange(i->first, value);
}
}
else
{
// No key with that name found, create a new one
_undo.save();

// Allocate a new KeyValue object and insert it into the map
insert(
key,
KeyValuePtr(new KeyValue(value, _eclass->getAttribute(key).getValue()))
);
insert(key, std::make_shared<KeyValue>(*this, value, _eclass->getAttribute(key).getValue()));
}
}

Expand Down

0 comments on commit f060e71

Please sign in to comment.