Browse Source

Fixed possibility of mistaken procedural event handling if attempted from a script object that does not belong to a ScriptInstance.

Lasse Öörni 13 years ago
parent
commit
d9f9505ae4
2 changed files with 36 additions and 22 deletions
  1. 1 1
      Docs/Reference.dox
  2. 35 21
      Engine/Script/ScriptInstance.cpp

+ 1 - 1
Docs/Reference.dox

@@ -283,7 +283,7 @@ The update methods above correspond to the variable timestep scene update and po
 
 
 The Start() and Stop() methods do not have direct counterparts in C++ components. Start() is called just after the script object has been created. Stop() is called just before the script object is destroyed. This happens when the ScriptInstance is destroyed, or if the script class is changed.
 The Start() and Stop() methods do not have direct counterparts in C++ components. Start() is called just after the script object has been created. Stop() is called just before the script object is destroyed. This happens when the ScriptInstance is destroyed, or if the script class is changed.
 
 
-Subscribing to \ref Events "events" in script behaves differently depending on whether \ref Object::SubscribeToEvent "SubscribeToEvent()" is called from a script object's method, or from a procedural script function. If called from an object method, the ScriptInstance becomes the event receiver on the C++ side, and forwards the events to the script object. If called from a function, the ScriptFile will be the event receiver.
+Subscribing to \ref Events "events" in script behaves differently depending on whether \ref Object::SubscribeToEvent "SubscribeToEvent()" is called from a script object's method, or from a procedural script function. If called from an object method, the ScriptInstance becomes the event receiver on the C++ side, and forwards the events to the script object. If called from a function, the ScriptFile will be the event receiver. Note that object-based event handling only works when the script object in question is attached to a ScriptInstance component, as it needs a C++ side proxy. If you simply create a new free-standing object in script, it will not be able to subscribe to events.
 
 
 The script object's active/inactive state can be controlled through the \ref ScriptInstance::SetActive "SetActive()" function. When inactive, the scripted update methods or event handlers will not be called. This can be used to reduce CPU load in a large or densely populated scene.
 The script object's active/inactive state can be controlled through the \ref ScriptInstance::SetActive "SetActive()" function. When inactive, the scripted update methods or event handlers will not be called. This can be used to reduce CPU load in a large or densely populated scene.
 
 

+ 35 - 21
Engine/Script/ScriptInstance.cpp

@@ -490,6 +490,17 @@ void ScriptInstance::HandleScriptEvent(StringHash eventType, VariantMap& eventDa
     scriptFile_->Execute(scriptObject_, method, parameters);
     scriptFile_->Execute(scriptObject_, method, parameters);
 }
 }
 
 
+void ScriptInstance::HandleScriptFileReload(StringHash eventType, VariantMap& eventData)
+{
+    ReleaseObject();
+}
+
+void ScriptInstance::HandleScriptFileReloadFinished(StringHash eventType, VariantMap& eventData)
+{
+    if (!className_.Empty())
+        CreateObject();
+}
+
 Context* GetScriptContext()
 Context* GetScriptContext()
 {
 {
     return static_cast<Script*>(asGetActiveContext()->GetEngine()->GetUserData())->GetContext();
     return static_cast<Script*>(asGetActiveContext()->GetEngine()->GetUserData())->GetContext();
@@ -526,30 +537,33 @@ Scene* GetScriptContextScene()
 
 
 ScriptEventListener* GetScriptContextEventListener()
 ScriptEventListener* GetScriptContextEventListener()
 {
 {
-    // First try to get the script instance. If not found, get the script file for procedural event handling
-    ScriptInstance* instance = GetScriptContextInstance();
-    if (instance)
-        return instance;
-    ScriptFile* file = GetScriptContextFile();
-    return file;
+    // If context this pointer is non-null, try to get the script instance. Else get the script file for procedural
+    // event handling.
+    asIScriptContext* context = asGetActiveContext();
+    if (context)
+    {
+        if (context->GetThisPointer())
+            return GetScriptContextInstance();
+        else
+            return GetScriptContextFile();
+    }
+    else
+        return 0;
 }
 }
 
 
 Object* GetScriptContextEventListenerObject()
 Object* GetScriptContextEventListenerObject()
 {
 {
-    ScriptInstance* instance = GetScriptContextInstance();
-    if (instance)
-        return instance;
-    ScriptFile* file = GetScriptContextFile();
-    return file;
-}
-
-void ScriptInstance::HandleScriptFileReload(StringHash eventType, VariantMap& eventData)
-{
-    ReleaseObject();
+    // If context this pointer is non-null, try to get the script instance. Else get the script file for procedural
+    // event handling.
+    asIScriptContext* context = asGetActiveContext();
+    if (context)
+    {
+        if (context->GetThisPointer())
+            return GetScriptContextInstance();
+        else
+            return GetScriptContextFile();
+    }
+    else
+        return 0;
 }
 }
 
 
-void ScriptInstance::HandleScriptFileReloadFinished(StringHash eventType, VariantMap& eventData)
-{
-    if (!className_.Empty())
-        CreateObject();
-}