2
0
Эх сурвалжийг харах

Centralize allocation of event data variant maps to Context to avoid constant dynamic memory allocation.

Lasse Öörni 12 жил өмнө
parent
commit
76292ef63e
40 өөрчлөгдсөн 193 нэмэгдсэн , 165 устгасан
  1. 17 0
      Source/Engine/Core/Context.cpp
  2. 5 1
      Source/Engine/Core/Context.h
  3. 5 0
      Source/Engine/Core/Object.cpp
  4. 2 0
      Source/Engine/Core/Object.h
  5. 1 1
      Source/Engine/Core/Timer.cpp
  6. 1 1
      Source/Engine/Core/WorkQueue.cpp
  7. 1 1
      Source/Engine/Engine/Console.cpp
  8. 1 1
      Source/Engine/Engine/Engine.cpp
  9. 1 1
      Source/Engine/Graphics/AnimatedModel.cpp
  10. 1 1
      Source/Engine/Graphics/AnimationState.cpp
  11. 2 2
      Source/Engine/Graphics/Direct3D9/D3D9Graphics.cpp
  12. 1 1
      Source/Engine/Graphics/Octree.cpp
  13. 2 2
      Source/Engine/Graphics/OpenGL/OGLGraphics.cpp
  14. 2 2
      Source/Engine/Graphics/Renderer.cpp
  15. 1 1
      Source/Engine/Graphics/Terrain.cpp
  16. 2 2
      Source/Engine/IO/Log.cpp
  17. 19 23
      Source/Engine/Input/Input.cpp
  18. 2 2
      Source/Engine/Network/Connection.cpp
  19. 3 3
      Source/Engine/Network/Network.cpp
  20. 53 57
      Source/Engine/Physics/PhysicsWorld.cpp
  21. 7 0
      Source/Engine/Physics/PhysicsWorld.h
  22. 1 1
      Source/Engine/Scene/Component.cpp
  23. 7 7
      Source/Engine/Scene/Node.cpp
  24. 6 7
      Source/Engine/Scene/Scene.cpp
  25. 2 0
      Source/Engine/Scene/Scene.h
  26. 1 1
      Source/Engine/Scene/Serializable.cpp
  27. 3 3
      Source/Engine/UI/Button.cpp
  28. 1 1
      Source/Engine/UI/CheckBox.cpp
  29. 4 4
      Source/Engine/UI/DropDownList.cpp
  30. 4 4
      Source/Engine/UI/FileSelector.cpp
  31. 3 3
      Source/Engine/UI/LineEdit.cpp
  32. 7 7
      Source/Engine/UI/ListView.cpp
  33. 1 1
      Source/Engine/UI/Menu.cpp
  34. 1 1
      Source/Engine/UI/MessageBox.cpp
  35. 1 2
      Source/Engine/UI/ScrollBar.cpp
  36. 1 1
      Source/Engine/UI/ScrollView.cpp
  37. 2 2
      Source/Engine/UI/Slider.cpp
  38. 9 8
      Source/Engine/UI/UI.cpp
  39. 9 9
      Source/Engine/UI/UIElement.cpp
  40. 1 1
      Source/Engine/UI/Window.cpp

+ 17 - 0
Source/Engine/Core/Context.cpp

@@ -71,6 +71,11 @@ Context::~Context()
     
     subsystems_.Clear();
     factories_.Clear();
+    
+    // Delete allocated event data maps
+    for (PODVector<VariantMap*>::Iterator i = eventDataMaps_.Begin(); i != eventDataMaps_.End(); ++i)
+        delete *i;
+    eventDataMaps_.Clear();
 }
 
 SharedPtr<Object> Context::CreateObject(ShortStringHash objectType)
@@ -140,6 +145,18 @@ void Context::UpdateAttributeDefaultValue(ShortStringHash objectType, const char
         info->defaultValue_ = defaultValue;
 }
 
+VariantMap& Context::GetEventDataMap()
+{
+    unsigned nestingLevel = eventSenders_.Size();
+    while (eventDataMaps_.Size() < nestingLevel + 1)
+        eventDataMaps_.Push(new VariantMap());
+    
+    VariantMap& ret = *eventDataMaps_[nestingLevel];
+    ret.Clear();
+    return ret;
+}
+
+
 void Context::CopyBaseAttributes(ShortStringHash baseType, ShortStringHash derivedType)
 {
     const Vector<AttributeInfo>* baseAttributes = GetAttributes(baseType);

+ 5 - 1
Source/Engine/Core/Context.h

@@ -56,7 +56,9 @@ public:
     void RemoveAttribute(ShortStringHash objectType, const char* name);
     /// Update object attribute's default value.
     void UpdateAttributeDefaultValue(ShortStringHash objectType, const char* name, const Variant& defaultValue);
-
+    /// Return a preallocated map for event data. Used for optimization to avoid constant re-allocation of event data maps.
+    VariantMap& GetEventDataMap();
+    
     /// Copy base class attributes to derived class.
     void CopyBaseAttributes(ShortStringHash baseType, ShortStringHash derivedType);
     /// Template version of registering an object factory.
@@ -161,6 +163,8 @@ private:
     HashMap<Object*, HashMap<StringHash, HashSet<Object*> > > specificEventReceivers_;
     /// Event sender stack.
     PODVector<Object*> eventSenders_;
+    /// Event data stack.
+    PODVector<VariantMap*> eventDataMaps_;
     /// Active event handler. Not stored in a stack for performance reasons; is needed only in esoteric cases.
     EventHandler* eventHandler_;
     /// Object categories.

+ 5 - 0
Source/Engine/Core/Object.cpp

@@ -319,6 +319,11 @@ void Object::SendEvent(StringHash eventType, VariantMap& eventData)
     context->EndSendEvent();
 }
 
+VariantMap& Object::GetEventDataMap() const
+{
+    return context_->GetEventDataMap();
+}
+
 Object* Object::GetSubsystem(ShortStringHash type) const
 {
     return context_->GetSubsystem(type);

+ 2 - 0
Source/Engine/Core/Object.h

@@ -84,6 +84,8 @@ public:
     void SendEvent(StringHash eventType);
     /// Send event with parameters to all subscribers.
     void SendEvent(StringHash eventType, VariantMap& eventData);
+    /// Return a preallocated map for event data. Used for optimization to avoid constant re-allocation of event data maps.
+    VariantMap& GetEventDataMap() const;
     
     /// Return execution context.
     Context* GetContext() const { return context_; }

+ 1 - 1
Source/Engine/Core/Timer.cpp

@@ -85,7 +85,7 @@ void Time::BeginFrame(float timeStep)
         // Frame begin event
         using namespace BeginFrame;
         
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_FRAMENUMBER] = frameNumber_;
         eventData[P_TIMESTEP] = timeStep_;
         SendEvent(E_BEGINFRAME, eventData);

+ 1 - 1
Source/Engine/Core/WorkQueue.cpp

@@ -255,7 +255,7 @@ void WorkQueue::PurgeCompleted()
 {
     using namespace WorkItemCompleted;
     
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     
     // Purge completed work items and send completion events.
     for (List<WorkItem>::Iterator i = workItems_.Begin(); i != workItems_.End();)

+ 1 - 1
Source/Engine/Engine/Console.cpp

@@ -203,7 +203,7 @@ void Console::HandleTextFinished(StringHash eventType, VariantMap& eventData)
         // Send the command as an event for script subsystem
         using namespace ConsoleCommand;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_COMMAND] = line;
         SendEvent(E_CONSOLECOMMAND, eventData);
 

+ 1 - 1
Source/Engine/Engine/Engine.cpp

@@ -520,7 +520,7 @@ void Engine::Update()
     // Logic update event
     using namespace Update;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_TIMESTEP] = timeStep_;
     SendEvent(E_UPDATE, eventData);
 

+ 1 - 1
Source/Engine/Graphics/AnimatedModel.cpp

@@ -708,7 +708,7 @@ void AnimatedModel::SetSkeleton(const Skeleton& skeleton, bool createBones)
 
         using namespace BoneHierarchyCreated;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_NODE] = (void*)node_;
         node_->SendEvent(E_BONEHIERARCHYCREATED, eventData);
     }

+ 1 - 1
Source/Engine/Graphics/AnimationState.cpp

@@ -287,7 +287,7 @@ void AnimationState::AddTime(float delta)
                 
                 Node* senderNode = model_ ? model_->GetNode() : node_;
                 
-                VariantMap eventData;
+                VariantMap& eventData = senderNode->GetEventDataMap();
                 eventData[P_NODE] = (void*)senderNode;
                 eventData[P_NAME] = animation_->GetAnimationName();
                 eventData[P_TIME] = i->time_;

+ 2 - 2
Source/Engine/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -459,7 +459,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
 
     using namespace ScreenMode;
     
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_WIDTH] = width_;
     eventData[P_HEIGHT] = height_;
     eventData[P_FULLSCREEN] = fullscreen_;
@@ -2025,7 +2025,7 @@ void Graphics::WindowResized()
     
     using namespace ScreenMode;
     
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_WIDTH] = width_;
     eventData[P_HEIGHT] = height_;
     eventData[P_FULLSCREEN] = fullscreen_;

+ 1 - 1
Source/Engine/Graphics/Octree.cpp

@@ -435,7 +435,7 @@ void Octree::Update(const FrameInfo& frame)
     {
         using namespace SceneDrawableUpdateFinished;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_SCENE] = (void*)scene;
         eventData[P_TIMESTEP] = frame.timeStep_;
         scene->SendEvent(E_SCENEDRAWABLEUPDATEFINISHED, eventData);

+ 2 - 2
Source/Engine/Graphics/OpenGL/OGLGraphics.cpp

@@ -489,7 +489,7 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless,
 
     using namespace ScreenMode;
     
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_WIDTH] = width_;
     eventData[P_HEIGHT] = height_;
     eventData[P_FULLSCREEN] = fullscreen_;
@@ -2073,7 +2073,7 @@ void Graphics::WindowResized()
     
     using namespace ScreenMode;
     
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_WIDTH] = width_;
     eventData[P_HEIGHT] = height_;
     eventData[P_FULLSCREEN] = fullscreen_;

+ 2 - 2
Source/Engine/Graphics/Renderer.cpp

@@ -630,7 +630,7 @@ void Renderer::Update(float timeStep)
         // Update view. This may queue further views
         using namespace BeginViewUpdate;
         
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_SURFACE] = (void*)renderTarget.Get();
         eventData[P_TEXTURE] = (void*)(renderTarget ? renderTarget->GetParentTexture() : 0);
         eventData[P_SCENE] = (void*)scene;
@@ -692,7 +692,7 @@ void Renderer::Render()
             
             RenderSurface* renderTarget = views_[i]->GetRenderTarget();
             
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_SURFACE] = (void*)renderTarget;
             eventData[P_TEXTURE] = (void*)(renderTarget ? renderTarget->GetParentTexture() : 0);
             eventData[P_SCENE] = (void*)views_[i]->GetScene();

+ 1 - 1
Source/Engine/Graphics/Terrain.cpp

@@ -716,7 +716,7 @@ void Terrain::CreateGeometry()
     {
         using namespace TerrainCreated;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_NODE] = (void*)node_;
         node_->SendEvent(E_TERRAINCREATED, eventData);
     }

+ 2 - 2
Source/Engine/IO/Log.cpp

@@ -166,7 +166,7 @@ void Log::Write(int level, const String& message)
 
     using namespace LogMessage;
 
-    VariantMap eventData;
+    VariantMap& eventData = logInstance->GetEventDataMap();
     eventData[P_MESSAGE] = formattedMessage;
     eventData[P_LEVEL] = level;
     logInstance->SendEvent(E_LOGMESSAGE, eventData);
@@ -207,7 +207,7 @@ void Log::WriteRaw(const String& message, bool error)
 
     using namespace LogMessage;
 
-    VariantMap eventData;
+    VariantMap& eventData = logInstance->GetEventDataMap();
     eventData[P_MESSAGE] = message;
     logInstance->SendEvent(E_LOGMESSAGE, eventData);
 

+ 19 - 23
Source/Engine/Input/Input.cpp

@@ -162,7 +162,7 @@ void Input::Update()
             {
                 using namespace MouseMove;
 
-                VariantMap eventData;
+                VariantMap& eventData = GetEventDataMap();
                 if (mouseVisible_)
                 {
                     eventData[P_X] = mousePosition.x_;
@@ -203,7 +203,7 @@ void Input::SetMouseVisible(bool enable)
 
         using namespace MouseVisibleChanged;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_VISIBLE] = mouseVisible_;
         SendEvent(E_MOUSEVISIBLECHANGED, eventData);
     }
@@ -504,8 +504,7 @@ void Input::ResetState()
 
         using namespace TouchEnd;
 
-        VariantMap eventData;
-
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_TOUCHID] = state.touchID_;
         eventData[P_X] = state.position_.x_;
         eventData[P_Y] = state.position_.y_;
@@ -526,7 +525,7 @@ void Input::SendInputFocusEvent()
 {
     using namespace InputFocus;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_FOCUS] = HasFocus();
     eventData[P_MINIMIZED] = IsMinimized();
     SendEvent(E_INPUTFOCUS, eventData);
@@ -563,7 +562,7 @@ void Input::SetMouseButton(int button, bool newState)
 
     using namespace MouseButtonDown;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_BUTTON] = button;
     eventData[P_BUTTONS] = mouseButtonDown_;
     eventData[P_QUALIFIERS] = GetQualifiers();
@@ -596,7 +595,7 @@ void Input::SetKey(int key, bool newState)
 
     using namespace KeyDown;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_KEY] = key;
     eventData[P_BUTTONS] = mouseButtonDown_;
     eventData[P_QUALIFIERS] = GetQualifiers();
@@ -620,7 +619,7 @@ void Input::SetMouseWheel(int delta)
 
         using namespace MouseWheel;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_WHEEL] = delta;
         eventData[P_BUTTONS] = mouseButtonDown_;
         eventData[P_QUALIFIERS] = GetQualifiers();
@@ -685,7 +684,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
 
             using namespace MouseMove;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             if (mouseVisible_)
             {
                 eventData[P_X] = evt.motion.x;
@@ -716,8 +715,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
 
             using namespace TouchBegin;
 
-            VariantMap eventData;
-
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_TOUCHID] = touchID;
             eventData[P_X] = state.position_.x_;
             eventData[P_Y] = state.position_.y_;
@@ -734,8 +732,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
 
             using namespace TouchEnd;
 
-            VariantMap eventData;
-
+            VariantMap& eventData = GetEventDataMap();
             // Do not trust the position in the finger up event. Instead use the last position stored in the
             // touch structure
             eventData[P_TOUCHID] = touchID;
@@ -760,8 +757,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
 
             using namespace TouchMove;
 
-            VariantMap eventData;
-
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_TOUCHID] = touchID;
             eventData[P_X] = state.position_.x_;
             eventData[P_Y] = state.position_.y_;
@@ -779,7 +775,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
             unsigned button = evt.jbutton.button;
             unsigned joystickIndex = joystickIDMap_[evt.jbutton.which];
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_JOYSTICK] = joystickIndex;
             eventData[P_BUTTON] = button;
 
@@ -798,7 +794,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
             unsigned button = evt.jbutton.button;
             unsigned joystickIndex = joystickIDMap_[evt.jbutton.which];
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_JOYSTICK] = joystickIndex;
             eventData[P_BUTTON] = button;
 
@@ -815,7 +811,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
 
             unsigned joystickIndex = joystickIDMap_[evt.jaxis.which];
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_JOYSTICK] = joystickIndex;
             eventData[P_AXIS] = evt.jaxis.axis;
             eventData[P_POSITION] = Clamp((float)evt.jaxis.value / 32767.0f, -1.0f, 1.0f);
@@ -835,7 +831,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
 
             unsigned joystickIndex = joystickIDMap_[evt.jaxis.which];
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_JOYSTICK] = joystickIndex;
             eventData[P_HAT] = evt.jhat.hat;
             eventData[P_POSITION] = evt.jhat.value;
@@ -856,7 +852,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
             unsigned button = evt.cbutton.button;
             unsigned joystickIndex = joystickIDMap_[evt.cbutton.which];
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_JOYSTICK] = joystickIndex;
             eventData[P_BUTTON] = button;
 
@@ -875,7 +871,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
             unsigned button = evt.cbutton.button;
             unsigned joystickIndex = joystickIDMap_[evt.cbutton.which];
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_JOYSTICK] = joystickIndex;
             eventData[P_BUTTON] = button;
 
@@ -892,7 +888,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
 
             unsigned joystickIndex = joystickIDMap_[evt.caxis.which];
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_JOYSTICK] = joystickIndex;
             eventData[P_AXIS] = evt.caxis.axis;
             eventData[P_POSITION] = Clamp((float)evt.caxis.value / 32767.0f, -1.0f, 1.0f);
@@ -944,7 +940,7 @@ void Input::HandleSDLEvent(void* sdlEvent)
         {
             using namespace DropFile;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_FILENAME] = GetInternalPath(String(evt.drop.file));
             SDL_free(evt.drop.file);
 

+ 2 - 2
Source/Engine/Network/Connection.cpp

@@ -932,7 +932,7 @@ void Connection::ProcessSceneLoaded(int msgID, MemoryBuffer& msg)
         
         using namespace ClientSceneLoaded;
         
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_CONNECTION] = (void*)this;
         SendEvent(E_CLIENTSCENELOADED, eventData);
     }
@@ -1359,7 +1359,7 @@ void Connection::OnSceneLoadFailed()
     
     using namespace NetworkSceneLoadFailed;
     
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_CONNECTION] = (void*)this;
     SendEvent(E_NETWORKSCENELOADFAILED, eventData);
 }

+ 3 - 3
Source/Engine/Network/Network.cpp

@@ -83,7 +83,7 @@ void Network::HandleMessage(kNet::MessageConnection *source, kNet::packet_id_t p
         // If message was not handled internally, forward as an event
         using namespace NetworkMessage;
         
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_CONNECTION] = (void*)connection;
         eventData[P_MESSAGEID] = (int)msgId;
         eventData[P_DATA].SetBuffer(msg.GetData(), msg.GetSize());
@@ -126,7 +126,7 @@ void Network::NewConnectionEstablished(kNet::MessageConnection* connection)
     
     using namespace ClientConnected;
     
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_CONNECTION] = (void*)newConnection;
     newConnection->SendEvent(E_CLIENTCONNECTED, eventData);
 }
@@ -144,7 +144,7 @@ void Network::ClientDisconnected(kNet::MessageConnection* connection)
         
         using namespace ClientDisconnected;
         
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_CONNECTION] = (void*)connection;
         connection->SendEvent(E_CLIENTDISCONNECTED, eventData);
         

+ 53 - 57
Source/Engine/Physics/PhysicsWorld.cpp

@@ -569,7 +569,7 @@ void PhysicsWorld::PreStep(float timeStep)
     // Send pre-step event
     using namespace PhysicsPreStep;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_WORLD] = (void*)this;
     eventData[P_TIMESTEP] = timeStep;
     SendEvent(E_PHYSICSPRESTEP, eventData);
@@ -595,7 +595,7 @@ void PhysicsWorld::PostStep(float timeStep)
     // Send post-step event
     using namespace PhysicsPreStep;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_WORLD] = (void*)this;
     eventData[P_TIMESTEP] = timeStep;
     SendEvent(E_PHYSICSPOSTSTEP, eventData);
@@ -606,15 +606,14 @@ void PhysicsWorld::SendCollisionEvents()
     PROFILE(SendCollisionEvents);
 
     currentCollisions_.Clear();
+    physicsCollisionData_.Clear();
+    nodeCollisionData_.Clear();
+    
     int numManifolds = collisionDispatcher_->getNumManifolds();
 
     if (numManifolds)
     {
-        VariantMap physicsCollisionData;
-        VariantMap nodeCollisionData;
-        VectorBuffer contacts;
-
-        physicsCollisionData[PhysicsCollision::P_WORLD] = (void*)this;
+        physicsCollisionData_[PhysicsCollision::P_WORLD] = (void*)this;
 
         for (int i = 0; i < numManifolds; ++i)
         {
@@ -675,88 +674,85 @@ void PhysicsWorld::SendCollisionEvents()
             bool phantom = bodyA->IsPhantom() || bodyB->IsPhantom();
             bool newCollision = !previousCollisions_.Contains(i->first_);
 
-            physicsCollisionData[PhysicsCollision::P_NODEA] = (void*)nodeA;
-            physicsCollisionData[PhysicsCollision::P_NODEB] = (void*)nodeB;
-            physicsCollisionData[PhysicsCollision::P_BODYA] = (void*)bodyA;
-            physicsCollisionData[PhysicsCollision::P_BODYB] = (void*)bodyB;
-            physicsCollisionData[PhysicsCollision::P_PHANTOM] = phantom;
+            physicsCollisionData_[PhysicsCollision::P_NODEA] = (void*)nodeA;
+            physicsCollisionData_[PhysicsCollision::P_NODEB] = (void*)nodeB;
+            physicsCollisionData_[PhysicsCollision::P_BODYA] = (void*)bodyA;
+            physicsCollisionData_[PhysicsCollision::P_BODYB] = (void*)bodyB;
+            physicsCollisionData_[PhysicsCollision::P_PHANTOM] = phantom;
 
-            contacts.Clear();
+            contacts_.Clear();
 
             for (int j = 0; j < numContacts; ++j)
             {
                 btManifoldPoint& point = contactManifold->getContactPoint(j);
-                contacts.WriteVector3(ToVector3(point.m_positionWorldOnB));
-                contacts.WriteVector3(ToVector3(point.m_normalWorldOnB));
-                contacts.WriteFloat(point.m_distance1);
-                contacts.WriteFloat(point.m_appliedImpulse);
+                contacts_.WriteVector3(ToVector3(point.m_positionWorldOnB));
+                contacts_.WriteVector3(ToVector3(point.m_normalWorldOnB));
+                contacts_.WriteFloat(point.m_distance1);
+                contacts_.WriteFloat(point.m_appliedImpulse);
             }
 
-            physicsCollisionData[PhysicsCollision::P_CONTACTS] = contacts.GetBuffer();
+            physicsCollisionData_[PhysicsCollision::P_CONTACTS] = contacts_.GetBuffer();
 
             // Send separate collision start event if collision is new
             if (newCollision)
             {
-                SendEvent(E_PHYSICSCOLLISIONSTART, physicsCollisionData);
+                SendEvent(E_PHYSICSCOLLISIONSTART, physicsCollisionData_);
                 // Skip rest of processing if either of the nodes or bodies is removed as a response to the event
                 if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_)
                     continue;
             }
 
             // Then send the ongoing collision event
-            SendEvent(E_PHYSICSCOLLISION, physicsCollisionData);
+            SendEvent(E_PHYSICSCOLLISION, physicsCollisionData_);
             if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_)
                 continue;
 
-            nodeCollisionData[NodeCollision::P_BODY] = (void*)bodyA;
-            nodeCollisionData[NodeCollision::P_OTHERNODE] = (void*)nodeB;
-            nodeCollisionData[NodeCollision::P_OTHERBODY] = (void*)bodyB;
-            nodeCollisionData[NodeCollision::P_PHANTOM] = phantom;
-            nodeCollisionData[NodeCollision::P_CONTACTS] = contacts.GetBuffer();
+            nodeCollisionData_[NodeCollision::P_BODY] = (void*)bodyA;
+            nodeCollisionData_[NodeCollision::P_OTHERNODE] = (void*)nodeB;
+            nodeCollisionData_[NodeCollision::P_OTHERBODY] = (void*)bodyB;
+            nodeCollisionData_[NodeCollision::P_PHANTOM] = phantom;
+            nodeCollisionData_[NodeCollision::P_CONTACTS] = contacts_.GetBuffer();
 
             if (newCollision)
             {
-                nodeA->SendEvent(E_NODECOLLISIONSTART, nodeCollisionData);
+                nodeA->SendEvent(E_NODECOLLISIONSTART, nodeCollisionData_);
                 if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_)
                     continue;
             }
 
-            nodeA->SendEvent(E_NODECOLLISION, nodeCollisionData);
+            nodeA->SendEvent(E_NODECOLLISION, nodeCollisionData_);
             if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_)
                 continue;
 
-            contacts.Clear();
+            contacts_.Clear();
             for (int j = 0; j < numContacts; ++j)
             {
                 btManifoldPoint& point = contactManifold->getContactPoint(j);
-                contacts.WriteVector3(ToVector3(point.m_positionWorldOnB));
-                contacts.WriteVector3(-ToVector3(point.m_normalWorldOnB));
-                contacts.WriteFloat(point.m_distance1);
-                contacts.WriteFloat(point.m_appliedImpulse);
+                contacts_.WriteVector3(ToVector3(point.m_positionWorldOnB));
+                contacts_.WriteVector3(-ToVector3(point.m_normalWorldOnB));
+                contacts_.WriteFloat(point.m_distance1);
+                contacts_.WriteFloat(point.m_appliedImpulse);
             }
 
-            nodeCollisionData[NodeCollision::P_BODY] = (void*)bodyB;
-            nodeCollisionData[NodeCollision::P_OTHERNODE] = (void*)nodeA;
-            nodeCollisionData[NodeCollision::P_OTHERBODY] = (void*)bodyA;
-            nodeCollisionData[NodeCollision::P_CONTACTS] = contacts.GetBuffer();
+            nodeCollisionData_[NodeCollision::P_BODY] = (void*)bodyB;
+            nodeCollisionData_[NodeCollision::P_OTHERNODE] = (void*)nodeA;
+            nodeCollisionData_[NodeCollision::P_OTHERBODY] = (void*)bodyA;
+            nodeCollisionData_[NodeCollision::P_CONTACTS] = contacts_.GetBuffer();
 
             if (newCollision)
             {
-                nodeB->SendEvent(E_NODECOLLISIONSTART, nodeCollisionData);
+                nodeB->SendEvent(E_NODECOLLISIONSTART, nodeCollisionData_);
                 if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_)
                     continue;
             }
 
-            nodeB->SendEvent(E_NODECOLLISION, nodeCollisionData);
+            nodeB->SendEvent(E_NODECOLLISION, nodeCollisionData_);
         }
     }
 
     // Send collision end events as applicable
     {
-        VariantMap physicsCollisionData;
-        VariantMap nodeCollisionData;
-
-        physicsCollisionData[PhysicsCollisionEnd::P_WORLD] = (void*)this;
+        physicsCollisionData_[PhysicsCollisionEnd::P_WORLD] = (void*)this;
 
         for (HashMap<Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> >, btPersistentManifold*>::Iterator i = previousCollisions_.Begin(); i != previousCollisions_.End(); ++i)
         {
@@ -783,31 +779,31 @@ void PhysicsWorld::SendCollisionEvents()
                 WeakPtr<Node> nodeWeakA(nodeA);
                 WeakPtr<Node> nodeWeakB(nodeB);
 
-                physicsCollisionData[PhysicsCollisionEnd::P_BODYA] = (void*)bodyA;
-                physicsCollisionData[PhysicsCollisionEnd::P_BODYB] = (void*)bodyB;
-                physicsCollisionData[PhysicsCollisionEnd::P_NODEA] = (void*)nodeA;
-                physicsCollisionData[PhysicsCollisionEnd::P_NODEB] = (void*)nodeB;
-                physicsCollisionData[PhysicsCollisionEnd::P_PHANTOM] = phantom;
+                physicsCollisionData_[PhysicsCollisionEnd::P_BODYA] = (void*)bodyA;
+                physicsCollisionData_[PhysicsCollisionEnd::P_BODYB] = (void*)bodyB;
+                physicsCollisionData_[PhysicsCollisionEnd::P_NODEA] = (void*)nodeA;
+                physicsCollisionData_[PhysicsCollisionEnd::P_NODEB] = (void*)nodeB;
+                physicsCollisionData_[PhysicsCollisionEnd::P_PHANTOM] = phantom;
 
-                SendEvent(E_PHYSICSCOLLISIONEND, physicsCollisionData);
+                SendEvent(E_PHYSICSCOLLISIONEND, physicsCollisionData_);
                 // Skip rest of processing if either of the nodes or bodies is removed as a response to the event
                 if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_)
                     continue;
 
-                nodeCollisionData[NodeCollisionEnd::P_BODY] = (void*)bodyA;
-                nodeCollisionData[NodeCollisionEnd::P_OTHERNODE] = (void*)nodeB;
-                nodeCollisionData[NodeCollisionEnd::P_OTHERBODY] = (void*)bodyB;
-                nodeCollisionData[NodeCollisionEnd::P_PHANTOM] = phantom;
+                nodeCollisionData_[NodeCollisionEnd::P_BODY] = (void*)bodyA;
+                nodeCollisionData_[NodeCollisionEnd::P_OTHERNODE] = (void*)nodeB;
+                nodeCollisionData_[NodeCollisionEnd::P_OTHERBODY] = (void*)bodyB;
+                nodeCollisionData_[NodeCollisionEnd::P_PHANTOM] = phantom;
 
-                nodeA->SendEvent(E_NODECOLLISIONEND, nodeCollisionData);
+                nodeA->SendEvent(E_NODECOLLISIONEND, nodeCollisionData_);
                 if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_)
                     continue;
 
-                nodeCollisionData[NodeCollisionEnd::P_BODY] = (void*)bodyB;
-                nodeCollisionData[NodeCollisionEnd::P_OTHERNODE] = (void*)nodeA;
-                nodeCollisionData[NodeCollisionEnd::P_OTHERBODY] = (void*)bodyA;
+                nodeCollisionData_[NodeCollisionEnd::P_BODY] = (void*)bodyB;
+                nodeCollisionData_[NodeCollisionEnd::P_OTHERNODE] = (void*)nodeA;
+                nodeCollisionData_[NodeCollisionEnd::P_OTHERBODY] = (void*)bodyA;
 
-                nodeB->SendEvent(E_NODECOLLISIONEND, nodeCollisionData);
+                nodeB->SendEvent(E_NODECOLLISIONEND, nodeCollisionData_);
             }
         }
     }

+ 7 - 0
Source/Engine/Physics/PhysicsWorld.h

@@ -27,6 +27,7 @@
 #include "HashSet.h"
 #include "Sphere.h"
 #include "Vector3.h"
+#include "VectorBuffer.h"
 
 #include <LinearMath/btIDebugDraw.h>
 
@@ -250,6 +251,12 @@ private:
     HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> > triMeshCache_;
     /// Cache for convex geometry data by model and LOD level.
     HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> > convexCache_;
+    /// Preallocated event data map for physics collision events.
+    VariantMap physicsCollisionData_;
+    /// Preallocated event data map for node collision events.
+    VariantMap nodeCollisionData_;
+    /// Preallocated buffer for physics collision contact data.
+    VectorBuffer contacts_;
     /// Simulation steps per second.
     unsigned fps_;
     /// Time accumulator for non-interpolated mode.

+ 1 - 1
Source/Engine/Scene/Component.cpp

@@ -89,7 +89,7 @@ void Component::SetEnabled(bool enable)
         {
             using namespace ComponentEnabledChanged;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_SCENE] = (void*)scene;
             eventData[P_NODE] = (void*)node_;
             eventData[P_COMPONENT] = (void*)this;

+ 7 - 7
Source/Engine/Scene/Node.cpp

@@ -243,7 +243,7 @@ void Node::SetName(const String& name)
         {
             using namespace NodeNameChanged;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_SCENE] = (void*)scene_;
             eventData[P_NODE] = (void*)this;
 
@@ -457,7 +457,7 @@ void Node::SetEnabled(bool enable, bool recursive)
         {
             using namespace NodeEnabledChanged;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_SCENE] = (void*)scene_;
             eventData[P_NODE] = (void*)this;
 
@@ -473,7 +473,7 @@ void Node::SetEnabled(bool enable, bool recursive)
             {
                 using namespace ComponentEnabledChanged;
 
-                VariantMap eventData;
+                VariantMap& eventData = GetEventDataMap();
                 eventData[P_SCENE] = (void*)scene_;
                 eventData[P_NODE] = (void*)this;
                 eventData[P_COMPONENT] = (void*)(*i);
@@ -557,7 +557,7 @@ void Node::AddChild(Node* node)
     {
         using namespace NodeAdded;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_SCENE] = (void*)scene_;
         eventData[P_PARENT] = (void*)this;
         eventData[P_NODE] = (void*)node;
@@ -1316,7 +1316,7 @@ void Node::AddComponent(Component* component, unsigned id, CreateMode mode)
     {
         using namespace ComponentAdded;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_SCENE] = (void*)scene_;
         eventData[P_NODE] = (void*)this;
         eventData[P_COMPONENT] = (void*)component;
@@ -1397,7 +1397,7 @@ void Node::RemoveChild(Vector<SharedPtr<Node> >::Iterator i)
     {
         using namespace NodeRemoved;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_SCENE] = (void*)scene_;
         eventData[P_PARENT] = (void*)this;
         eventData[P_NODE] = (void*)(*i).Get();
@@ -1502,7 +1502,7 @@ void Node::RemoveComponent(Vector<SharedPtr<Component> >::Iterator i)
     {
         using namespace ComponentRemoved;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_SCENE] = (void*)scene_;
         eventData[P_NODE] = (void*)this;
         eventData[P_COMPONENT] = (void*)(*i).Get();

+ 6 - 7
Source/Engine/Scene/Scene.cpp

@@ -528,7 +528,7 @@ void Scene::Update(float timeStep)
 
     using namespace SceneUpdate;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_SCENE] = (void*)this;
     eventData[P_TIMESTEP] = timeStep;
 
@@ -547,10 +547,9 @@ void Scene::Update(float timeStep)
 
         using namespace UpdateSmoothing;
 
-        VariantMap eventData;
-        eventData[P_CONSTANT] = constant;
-        eventData[P_SQUAREDSNAPTHRESHOLD] = squaredSnapThreshold;
-        SendEvent(E_UPDATESMOOTHING, eventData);
+        smoothingData_[P_CONSTANT] = constant;
+        smoothingData_[P_SQUAREDSNAPTHRESHOLD] = squaredSnapThreshold;
+        SendEvent(E_UPDATESMOOTHING, smoothingData_);
     }
 
     // Post-update variable timestep logic
@@ -910,7 +909,7 @@ void Scene::UpdateAsyncLoading()
 
     using namespace AsyncLoadProgress;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_SCENE] = (void*)this;
     eventData[P_PROGRESS] = (float)asyncProgress_.loadedNodes_ / (float)asyncProgress_.totalNodes_;
     eventData[P_LOADEDNODES]  = asyncProgress_.loadedNodes_;
@@ -927,7 +926,7 @@ void Scene::FinishAsyncLoading()
 
     using namespace AsyncLoadFinished;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_SCENE] = (void*)this;
     SendEvent(E_ASYNCLOADFINISHED, eventData);
 }

+ 2 - 0
Source/Engine/Scene/Scene.h

@@ -220,6 +220,8 @@ private:
     PODVector<Component*> delayedDirtyComponents_;
     /// Mutex for the delayed dirty notification queue.
     Mutex sceneMutex_;
+    /// Preallocated event data map for smoothing update events.
+    VariantMap smoothingData_;
     /// Next free non-local node ID.
     unsigned replicatedNodeID_;
     /// Next free non-local component ID.

+ 1 - 1
Source/Engine/Scene/Serializable.cpp

@@ -509,7 +509,7 @@ void Serializable::SetTemporary(bool enable)
         
         using namespace TemporaryChanged;
         
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_SERIALIZABLE] = (void*)this;
         
         SendEvent(E_TEMPORARYCHANGED, eventData);

+ 3 - 3
Source/Engine/UI/Button.cpp

@@ -79,7 +79,7 @@ void Button::Update(float timeStep)
 
             using namespace Pressed;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_ELEMENT] = (void*)this;
             SendEvent(E_PRESSED, eventData);
         }
@@ -107,7 +107,7 @@ void Button::OnClickBegin(const IntVector2& position, const IntVector2& screenPo
 
         using namespace Pressed;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_ELEMENT] = (void*)this;
         SendEvent(E_PRESSED, eventData);
     }
@@ -121,7 +121,7 @@ void Button::OnClickEnd(const IntVector2& position, const IntVector2& screenPosi
 
         using namespace Released;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_ELEMENT] = (void*)this;
         SendEvent(E_RELEASED, eventData);
     }

+ 1 - 1
Source/Engine/UI/CheckBox.cpp

@@ -91,7 +91,7 @@ void CheckBox::SetChecked(bool enable)
 
         using namespace Toggled;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_STATE] = checked_;
         SendEvent(E_TOGGLED, eventData);

+ 4 - 4
Source/Engine/UI/DropDownList.cpp

@@ -140,10 +140,10 @@ void DropDownList::OnHidePopup()
     // When the popup is hidden, propagate the selection
     using namespace ItemSelected;
 
-    VariantMap newEventData;
-    newEventData[P_ELEMENT] = (void*)this;
-    newEventData[P_SELECTION] = GetSelection();
-    SendEvent(E_ITEMSELECTED, newEventData);
+    VariantMap& eventData = GetEventDataMap();
+    eventData[P_ELEMENT] = (void*)this;
+    eventData[P_SELECTION] = GetSelection();
+    SendEvent(E_ITEMSELECTED, eventData);
 }
 
 void DropDownList::OnSetEditable()

+ 4 - 4
Source/Engine/UI/FileSelector.cpp

@@ -378,7 +378,7 @@ bool FileSelector::EnterFile()
         {
             using namespace FileSelected;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_FILENAME] = path_ + fileEntries_[index].name_;
             eventData[P_FILTER] = GetFilter();
             eventData[P_OK] = true;
@@ -459,7 +459,7 @@ void FileSelector::HandleOKPressed(StringHash eventType, VariantMap& eventData)
         {
             using namespace FileSelected;
 
-            VariantMap newEventData;
+            VariantMap& newEventData = GetEventDataMap();
             newEventData[P_FILENAME] = path_ + GetFileName();
             newEventData[P_FILTER] = GetFilter();
             newEventData[P_OK] = true;
@@ -470,7 +470,7 @@ void FileSelector::HandleOKPressed(StringHash eventType, VariantMap& eventData)
     {
         using namespace FileSelected;
 
-        VariantMap newEventData;
+        VariantMap& newEventData = GetEventDataMap();
         newEventData[P_FILENAME] = path_;
         newEventData[P_FILTER] = GetFilter();
         newEventData[P_OK] = true;
@@ -488,7 +488,7 @@ void FileSelector::HandleCancelPressed(StringHash eventType, VariantMap& eventDa
 
     using namespace FileSelected;
 
-    VariantMap newEventData;
+    VariantMap& newEventData = GetEventDataMap();
     newEventData[P_FILENAME] = String::EMPTY;
     newEventData[P_FILTER] = GetFilter();
     newEventData[P_OK] = false;

+ 3 - 3
Source/Engine/UI/LineEdit.cpp

@@ -342,7 +342,7 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
         {
             using namespace UnhandledKey;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_KEY] = key;
             eventData[P_BUTTONS] = buttons;
@@ -392,7 +392,7 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
             
             using namespace TextFinished;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_TEXT] = line_;
             SendEvent(E_TEXTFINISHED, eventData);
@@ -562,7 +562,7 @@ void LineEdit::UpdateText()
 
     using namespace TextChanged;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_ELEMENT] = (void*)this;
     eventData[P_TEXT] = line_;
     SendEvent(E_TEXTCHANGED, eventData);

+ 7 - 7
Source/Engine/UI/ListView.cpp

@@ -289,7 +289,7 @@ void ListView::OnKey(int key, int buttons, int qualifiers)
 
     using namespace UnhandledKey;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_ELEMENT] = (void*)this;
     eventData[P_KEY] = key;
     eventData[P_BUTTONS] = buttons;
@@ -490,7 +490,7 @@ void ListView::SetSelections(const PODVector<unsigned>& indices)
 
             using namespace ItemSelected;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_SELECTION] = index;
             SendEvent(E_ITEMDESELECTED, eventData);
@@ -522,7 +522,7 @@ void ListView::SetSelections(const PODVector<unsigned>& indices)
 
                 using namespace ItemSelected;
 
-                VariantMap eventData;
+                VariantMap& eventData = GetEventDataMap();
                 eventData[P_ELEMENT] = (void*)this;
                 eventData[P_SELECTION] = *i;
                 SendEvent(E_ITEMSELECTED, eventData);
@@ -562,7 +562,7 @@ void ListView::AddSelection(unsigned index)
 
             using namespace ItemSelected;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_SELECTION] = index;
             SendEvent(E_ITEMSELECTED, eventData);
@@ -588,7 +588,7 @@ void ListView::RemoveSelection(unsigned index)
     {
         using namespace ItemSelected;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_SELECTION] = index;
         SendEvent(E_ITEMDESELECTED, eventData);
@@ -1025,7 +1025,7 @@ void ListView::HandleUIMouseClick(StringHash eventType, VariantMap& eventData)
     }
     
     // Propagate the click as an event. Also include right-clicks
-    VariantMap clickEventData;
+    VariantMap& clickEventData = GetEventDataMap();
     clickEventData[ItemClicked::P_ELEMENT] = (void*)this;
     clickEventData[ItemClicked::P_ITEM] = (void*)element;
     clickEventData[ItemClicked::P_SELECTION] = i;
@@ -1047,7 +1047,7 @@ void ListView::HandleUIMouseDoubleClick(StringHash eventType, VariantMap& eventD
     if (i >= GetNumItems())
         return;
 
-    VariantMap clickEventData;
+    VariantMap& clickEventData = GetEventDataMap();
     clickEventData[ItemDoubleClicked::P_ELEMENT] = (void*)this;
     clickEventData[ItemDoubleClicked::P_ITEM] = (void*)element;
     clickEventData[ItemDoubleClicked::P_SELECTION] = i;

+ 1 - 1
Source/Engine/UI/Menu.cpp

@@ -375,7 +375,7 @@ void Menu::HandlePressedReleased(StringHash eventType, VariantMap& eventData)
     {
         using namespace MenuSelected;
 
-        VariantMap newEventData;
+        VariantMap& newEventData = GetEventDataMap();
         newEventData[P_ELEMENT] = (void*)this;
         SendEvent(E_MENUSELECTED, newEventData);
     }

+ 1 - 1
Source/Engine/UI/MessageBox.cpp

@@ -136,7 +136,7 @@ void MessageBox::HandleMessageAcknowledged(StringHash eventType, VariantMap& eve
 {
     using namespace MessageACK;
 
-    VariantMap newEventData;
+    VariantMap& newEventData = GetEventDataMap();
     newEventData[P_OK] = eventData[Released::P_ELEMENT] == okButton_;
     SendEvent(E_MESSAGEACK, newEventData);
 

+ 1 - 2
Source/Engine/UI/ScrollBar.cpp

@@ -286,8 +286,7 @@ void ScrollBar::HandleForwardButtonPressed(StringHash eventType, VariantMap& eve
 void ScrollBar::HandleSliderChanged(StringHash eventType, VariantMap& eventData)
 {
     // Send the event forward
-    VariantMap newEventData;
-
+    VariantMap& newEventData = GetEventDataMap();
     newEventData[ScrollBarChanged::P_ELEMENT] = (void*)this;
     newEventData[ScrollBarChanged::P_VALUE] = slider_->GetValue();
     SendEvent(E_SCROLLBARCHANGED, newEventData);

+ 1 - 1
Source/Engine/UI/ScrollView.cpp

@@ -407,7 +407,7 @@ void ScrollView::UpdateView(const IntVector2& position)
     {
         using namespace ViewChanged;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_X] = viewPosition_.x_;
         eventData[P_Y] = viewPosition_.y_;

+ 2 - 2
Source/Engine/UI/Slider.cpp

@@ -182,7 +182,7 @@ void Slider::SetValue(float value)
 
         using namespace SliderChanged;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_VALUE] = value_;
         SendEvent(E_SLIDERCHANGED, eventData);
@@ -256,7 +256,7 @@ void Slider::Page(const IntVector2& position, bool pressed)
 
     using namespace SliderPaged;
     
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_ELEMENT] = (void*)this;
     eventData[P_OFFSET] = offset;
 

+ 9 - 8
Source/Engine/UI/UI.cpp

@@ -157,8 +157,7 @@ void UI::SetFocusElement(UIElement* element, bool byKey)
 {
     using namespace FocusChanged;
 
-    VariantMap eventData;
-    eventData[P_CLICKEDELEMENT] = (void*)element;
+    UIElement* originalElement = element;
 
     if (element)
     {
@@ -188,7 +187,7 @@ void UI::SetFocusElement(UIElement* element, bool byKey)
         UIElement* oldFocusElement = focusElement_;
         focusElement_.Reset();
 
-        VariantMap focusEventData;
+        VariantMap& focusEventData = GetEventDataMap();
         focusEventData[Defocused::P_ELEMENT] = oldFocusElement;
         oldFocusElement->SendEvent(E_DEFOCUSED, focusEventData);
     }
@@ -198,12 +197,14 @@ void UI::SetFocusElement(UIElement* element, bool byKey)
     {
         focusElement_ = element;
 
-        VariantMap focusEventData;
+        VariantMap& focusEventData = GetEventDataMap();
         focusEventData[Focused::P_ELEMENT] = element;
         focusEventData[Focused::P_BYKEY] = byKey;
         element->SendEvent(E_FOCUSED, focusEventData);
     }
 
+    VariantMap& eventData = GetEventDataMap();
+    eventData[P_CLICKEDELEMENT] = (void*)originalElement;
     eventData[P_ELEMENT] = (void*)element;
     SendEvent(E_FOCUSCHANGED, eventData);
 }
@@ -920,7 +921,7 @@ void UI::ProcessHover(const IntVector2& cursorPos, int buttons, int qualifiers,
         {
             using namespace DragDropTest;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_SOURCE] = (void*)dragElement_.Get();
             eventData[P_TARGET] = (void*)element.Get();
             eventData[P_ACCEPT] = accept;
@@ -1026,7 +1027,7 @@ void UI::ProcessClickEnd(const IntVector2& cursorPos, int button, int buttons, i
                         {
                             using namespace DragDropFinish;
 
-                            VariantMap eventData;
+                            VariantMap& eventData = GetEventDataMap();
                             eventData[P_SOURCE] = (void*)dragElement_.Get();
                             eventData[P_TARGET] = (void*)element.Get();
                             eventData[P_ACCEPT] = accept;
@@ -1086,7 +1087,7 @@ void UI::SendDragEvent(StringHash eventType, UIElement* element, const IntVector
 
     using namespace DragBegin;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_ELEMENT] = (void*)element;
     eventData[P_X] = screenPos.x_;
     eventData[P_Y] = screenPos.y_;
@@ -1098,7 +1099,7 @@ void UI::SendDragEvent(StringHash eventType, UIElement* element, const IntVector
 
 void UI::SendClickEvent(StringHash eventType, UIElement* element, const IntVector2& pos, int button, int buttons, int qualifiers)
 {
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[UIMouseClick::P_ELEMENT] = (void*)element;
     eventData[UIMouseClick::P_X] = pos.x_;
     eventData[UIMouseClick::P_Y] = pos.y_;

+ 9 - 9
Source/Engine/UI/UIElement.cpp

@@ -530,7 +530,7 @@ void UIElement::SetName(const String& name)
 
     using namespace NameChanged;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_ELEMENT] = (void*)this;
 
     SendEvent(E_NAMECHANGED, eventData);
@@ -546,7 +546,7 @@ void UIElement::SetPosition(const IntVector2& position)
 
         using namespace Positioned;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_X] = position_.x_;
         eventData[P_Y] = position_.y_;
@@ -583,7 +583,7 @@ void UIElement::SetSize(const IntVector2& size)
 
             using namespace Resized;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_ELEMENT] = (void*)this;
             eventData[P_WIDTH] = size_.x_;
             eventData[P_HEIGHT] = size_.y_;
@@ -833,7 +833,7 @@ void UIElement::SetVisible(bool enable)
 
         using namespace VisibleChanged;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_VISIBLE] = visible_;
         SendEvent(E_VISIBLECHANGED, eventData);
@@ -1032,7 +1032,7 @@ void UIElement::UpdateLayout()
 
     using namespace LayoutUpdated;
 
-    VariantMap eventData;
+    VariantMap& eventData = GetEventDataMap();
     eventData[P_ELEMENT] = (void*)this;
     SendEvent(E_LAYOUTUPDATED, eventData);
 
@@ -1166,7 +1166,7 @@ void UIElement::InsertChild(unsigned index, UIElement* element)
     {
         using namespace ElementAdded;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_ROOT] = (void*)root;
         eventData[P_PARENT] = (void*)this;
         eventData[P_ELEMENT] = (void*)element;
@@ -1187,7 +1187,7 @@ void UIElement::RemoveChild(UIElement* element, unsigned index)
             {
                 using namespace ElementRemoved;
 
-                VariantMap eventData;
+                VariantMap& eventData = GetEventDataMap();
                 eventData[P_ROOT] = (void*)GetRoot();
                 eventData[P_PARENT] = (void*)this;
                 eventData[P_ELEMENT] = (void*)element;
@@ -1214,7 +1214,7 @@ void UIElement::RemoveChildAtIndex(unsigned index)
     {
         using namespace ElementRemoved;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_ROOT] = (void*)GetRoot();
         eventData[P_PARENT] = (void*)this;
         eventData[P_ELEMENT] = (void*)children_[index];
@@ -1239,7 +1239,7 @@ void UIElement::RemoveAllChildren()
         {
             using namespace ElementRemoved;
 
-            VariantMap eventData;
+            VariantMap& eventData = GetEventDataMap();
             eventData[P_ROOT] = (void*)root;
             eventData[P_PARENT] = (void*)this;
             eventData[P_ELEMENT] = (void*)(*i).Get();

+ 1 - 1
Source/Engine/UI/Window.cpp

@@ -256,7 +256,7 @@ void Window::SetModal(bool modal)
 
         using namespace ModalChanged;
 
-        VariantMap eventData;
+        VariantMap& eventData = GetEventDataMap();
         eventData[P_ELEMENT] = (void*)this;
         eventData[P_MODAL] = modal;
         SendEvent(E_MODALCHANGED, eventData);