فهرست منبع

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

Lasse Öörni 12 سال پیش
والد
کامیت
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);