Basic editor copy and paste. Doesn't actually copy the entity until you paste it.

This commit is contained in:
2016-02-25 17:51:28 +01:00
parent da1c7b3093
commit 9e6c67596d
10 changed files with 71 additions and 6 deletions
+2
View File
@@ -29,6 +29,7 @@ struct EntityWrapper
EntityWrapper Parent();
EntityWrapper FirstChildByName(const std::string& name);
EntityWrapper FirstParentWithComponent(const std::string& componentType);
EntityWrapper Clone(EntityWrapper parent = EntityWrapper::Invalid);
bool IsChildOf(EntityWrapper potentialParent);
bool Valid() const;
@@ -39,6 +40,7 @@ struct EntityWrapper
private:
EntityWrapper firstChildByNameRecursive(const std::string& name, EntityID parent);
EntityWrapper cloneRecursive(EntityWrapper entity, EntityWrapper parent);
};
namespace std
+1 -1
View File
@@ -40,7 +40,7 @@ public:
// Change the parent of an entity
void SetParent(EntityID entity, EntityID parent);
// Get children of an entity
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> GetChildren(EntityID entity);
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> GetDirectChildren(EntityID entity);
// Get all component pools
const std::unordered_map<std::string, ComponentPool*>& GetComponentPools() const { return m_ComponentPools; }
// Get the entity children map
+8
View File
@@ -73,6 +73,12 @@ public:
// Called when the user means to rename an entity.
typedef std::function<void(EntityWrapper, const std::string&)> OnEntityChangeName_t;
void SetEntityChangeNameCallback(OnEntityChangeName_t f) { m_OnEntityChangeName = f; }
// Called when the user pastes an entity previously "copied"
// @param EntityWrapper The entity to copy
// @param EntityWrapper The entity to parent the new copy to
// @return The new copy of the entity
typedef std::function<EntityWrapper(EntityWrapper, EntityWrapper)> OnEntityPaste_t;
void SetEntityPasteCallback(OnEntityPaste_t f) { m_OnEntityPaste = f; }
// Called when the user means to attach a new component to an entity.
typedef std::function<void(EntityWrapper, const std::string&)> OnComponentAttach_t;
void SetComponentAttachCallback(OnComponentAttach_t f) { m_OnComponentAttach = f; }
@@ -111,6 +117,7 @@ private:
std::string m_DroppedFile = "";
bool m_Paused = false;
bool m_MouseLocked = false;
EntityWrapper m_CopyTarget = EntityWrapper::Invalid;
// Callbacks
OnEntitySelectedCallback_t m_OnEntitySelected = nullptr;
@@ -124,6 +131,7 @@ private:
OnComponentDelete_t m_OnComponentDelete = nullptr;
OnWidgetMode_t m_OnWidgetMode = nullptr;
OnWidgetSpace_t m_OnWidgetSpace = nullptr;
OnEntityPaste_t m_OnEntityPaste = nullptr;
// Events
EventRelay<EditorGUI, Events::KeyDown> m_EKeyDown;
+1
View File
@@ -56,6 +56,7 @@ private:
void OnEntityDelete(EntityWrapper entity);
void OnEntityChangeParent(EntityWrapper entity, EntityWrapper parent);
void OnEntityChangeName(EntityWrapper entity, const std::string& name);
EntityWrapper OnEntityPaste(EntityWrapper entityToCopy, EntityWrapper parent);
void OnComponentAttach(EntityWrapper entity, const std::string& componentType);
void OnComponentDelete(EntityWrapper entity, const std::string& componentType);
void OnWidgetSpace(EditorGUI::WidgetSpace widgetSpace);
+36 -1
View File
@@ -51,6 +51,17 @@ EntityWrapper EntityWrapper::FirstParentWithComponent(const std::string& compone
return EntityWrapper::Invalid;
}
EntityWrapper EntityWrapper::Clone(EntityWrapper parent /*= Invalid*/)
{
if (!Valid()) {
return EntityWrapper::Invalid;
}
EntityWrapper clone = cloneRecursive(*this, EntityWrapper::Invalid);
this->World->SetParent(clone.ID, parent.ID);
return clone;
}
bool EntityWrapper::IsChildOf(EntityWrapper potentialParent)
{
EntityWrapper entity = *this;
@@ -111,7 +122,7 @@ EntityWrapper EntityWrapper::firstChildByNameRecursive(const std::string& name,
return EntityWrapper::Invalid;
}
auto itPair = this->World->GetChildren(parent);
auto itPair = this->World->GetDirectChildren(parent);
if (itPair.first == itPair.second) {
return EntityWrapper::Invalid;
}
@@ -131,3 +142,27 @@ EntityWrapper EntityWrapper::firstChildByNameRecursive(const std::string& name,
return EntityWrapper::Invalid;
}
EntityWrapper EntityWrapper::cloneRecursive(EntityWrapper entity, EntityWrapper parent)
{
EntityWrapper clone = EntityWrapper(entity.World, entity.World->CreateEntity(parent.ID));
entity.World->SetName(clone.ID, entity.Name());
// Clone components
for (auto& kv : entity.World->GetComponentPools()) {
if (kv.second->KnowsEntity(entity.ID)) {
ComponentWrapper c1 = kv.second->GetByEntity(entity.ID);
ComponentWrapper c2 = entity.World->AttachComponent(clone.ID, kv.first);
c1.Copy(c2);
}
}
// Clone children
auto children = entity.World->GetDirectChildren(entity.ID);
for (auto it = children.first; it != children.second; ++it) {
EntityWrapper child(entity.World, it->second);
cloneRecursive(child, clone);
}
return clone;
}
+1 -1
View File
@@ -127,7 +127,7 @@ void World::SetParent(EntityID entity, EntityID parent)
m_EntityChildren.insert(std::make_pair(parent, entity));
}
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> World::GetChildren(EntityID entity)
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> World::GetDirectChildren(EntityID entity)
{
return m_EntityChildren.equal_range(entity);
}
+13
View File
@@ -598,6 +598,19 @@ bool EditorGUI::OnKeyDown(const Events::KeyDown& e)
entityImport(m_World);
}
if (e.ModCtrl && e.KeyCode == GLFW_KEY_C) {
m_CopyTarget = m_CurrentSelection;
}
if (e.ModCtrl && e.KeyCode == GLFW_KEY_V) {
if (m_OnEntityPaste != nullptr) {
EntityWrapper copy = m_OnEntityPaste(m_CopyTarget, m_CurrentSelection);
if (copy != EntityWrapper::Invalid) {
SelectEntity(copy);
}
}
}
if (e.KeyCode == GLFW_KEY_DELETE) {
if (m_CurrentSelection.Valid()) {
entityDelete(m_CurrentSelection);
+6
View File
@@ -28,6 +28,7 @@ EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame
m_EditorGUI->SetEntityDeleteCallback(std::bind(&EditorSystem::OnEntityDelete, this, std::placeholders::_1));
m_EditorGUI->SetEntityChangeParentCallback(std::bind(&EditorSystem::OnEntityChangeParent, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetEntityChangeNameCallback(std::bind(&EditorSystem::OnEntityChangeName, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetEntityPasteCallback(std::bind(&EditorSystem::OnEntityPaste, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetComponentAttachCallback(std::bind(&EditorSystem::OnComponentAttach, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetComponentDeleteCallback(std::bind(&EditorSystem::OnComponentDelete, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetWidgetModeCallback(std::bind(&EditorSystem::setWidgetMode, this, std::placeholders::_1));
@@ -160,6 +161,11 @@ void EditorSystem::OnEntityChangeName(EntityWrapper entity, const std::string& n
}
}
EntityWrapper EditorSystem::OnEntityPaste(EntityWrapper entityToCopy, EntityWrapper parent)
{
return entityToCopy.Clone(parent);
}
void EditorSystem::OnComponentAttach(EntityWrapper entity, const std::string& componentType)
{
if (entity.Valid()) {
+2 -2
View File
@@ -183,7 +183,7 @@ void Server::addInputCommandsToPacket(Packet& packet)
void Server::addPlayersToPacket(Packet & packet, EntityID entityID)
{
auto itPair = m_World->GetChildren(entityID);
auto itPair = m_World->GetDirectChildren(entityID);
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
// Loop through every child
for (auto it = itPair.first; it != itPair.second; it++) {
@@ -233,7 +233,7 @@ void Server::addPlayersToPacket(Packet & packet, EntityID entityID)
void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
{
auto itPair = m_World->GetChildren(entityID);
auto itPair = m_World->GetDirectChildren(entityID);
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
// Loop through every child
for (auto it = itPair.first; it != itPair.second; it++) {
+1 -1
View File
@@ -36,7 +36,7 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent /
}
// Find any SpawnPoints existing as children of spawner
auto children = spawner.World->GetChildren(spawner.ID);
auto children = spawner.World->GetDirectChildren(spawner.ID);
std::vector<EntityWrapper> spawnPoints;
for (auto kv = children.first; kv != children.second; ++kv) {
const EntityID& child = kv->second;