浏览代码

Detect main thread when sending events or using profiler blocks; make these no-ops when called from outside the main thread.

Lasse Öörni 11 年之前
父节点
当前提交
346da1e1f9
共有 3 个文件被更改,包括 16 次插入3 次删除
  1. 3 3
      Docs/Reference.dox
  2. 5 0
      Source/Engine/Core/Object.cpp
  3. 8 0
      Source/Engine/Core/Profiler.h

+ 3 - 3
Docs/Reference.dox

@@ -1973,15 +1973,15 @@ Multithreading is so far not exposed to scripts, and is currently used only in a
 
 
 When making your own work functions, observe that the following things are (at least currently) unsafe and will result in undefined behavior and crashes, if done outside the main thread:
 When making your own work functions, observe that the following things are (at least currently) unsafe and will result in undefined behavior and crashes, if done outside the main thread:
 
 
-- Sending events
-- Using profiler blocks
 - Modifying scene or UI content
 - Modifying scene or UI content
 - Modifying GPU resources
 - Modifying GPU resources
 - Requesting resources from ResourceCache
 - Requesting resources from ResourceCache
 - Executing script functions
 - Executing script functions
 
 
+Sending events and using the Profiler are treated as no-ops when called from outside the main thread.
+
 \page AttributeAnimation %Attribute animation
 \page AttributeAnimation %Attribute animation
-Attribute animation is a new system for Urho3D, With it user can apply animation to object’s attribute. All object derived from Animatable can use attribute animation, currently these classes include Node, Component and UIElement.
+Attribute animation is a new system for Urho3D, With it user can apply animation to object's attribute. All object derived from Animatable can use attribute animation, currently these classes include Node, Component and UIElement.
 
 
 These are two way to use use attribute animation. First user can create attribute animation with code, and then apply it to object’s attribute. Here is a simple code for light color animation:
 These are two way to use use attribute animation. First user can create attribute animation with code, and then apply it to object’s attribute. Here is a simple code for light color animation:
 \code
 \code

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

@@ -22,6 +22,7 @@
 
 
 #include "Precompiled.h"
 #include "Precompiled.h"
 #include "Context.h"
 #include "Context.h"
+#include "Thread.h"
 
 
 #include "DebugNew.h"
 #include "DebugNew.h"
 
 
@@ -222,6 +223,10 @@ void Object::SendEvent(StringHash eventType)
 
 
 void Object::SendEvent(StringHash eventType, VariantMap& eventData)
 void Object::SendEvent(StringHash eventType, VariantMap& eventData)
 {
 {
+    // Attempting to send events from other threads is treated as a no-op
+    if (!Thread::IsMainThread())
+        return;
+    
     // Make a weak pointer to self to check for destruction during event handling
     // Make a weak pointer to self to check for destruction during event handling
     WeakPtr<Object> self(this);
     WeakPtr<Object> self(this);
     Context* context = context_;
     Context* context = context_;

+ 8 - 0
Source/Engine/Core/Profiler.h

@@ -23,6 +23,7 @@
 #pragma once
 #pragma once
 
 
 #include "Str.h"
 #include "Str.h"
+#include "Thread.h"
 #include "Timer.h"
 #include "Timer.h"
 
 
 namespace Urho3D
 namespace Urho3D
@@ -180,6 +181,10 @@ public:
     /// Begin timing a profiling block.
     /// Begin timing a profiling block.
     void BeginBlock(const char* name)
     void BeginBlock(const char* name)
     {
     {
+        // Profiler supports only the main thread currently
+        if (!Thread::IsMainThread())
+            return;
+        
         current_ = current_->GetChild(name);
         current_ = current_->GetChild(name);
         current_->Begin();
         current_->Begin();
     }
     }
@@ -187,6 +192,9 @@ public:
     /// End timing the current profiling block.
     /// End timing the current profiling block.
     void EndBlock()
     void EndBlock()
     {
     {
+        if (!Thread::IsMainThread())
+            return;
+        
         if (current_ != root_)
         if (current_ != root_)
         {
         {
             current_->End();
             current_->End();