فهرست منبع

Check that script classes implement the empty "ScriptObject" interface.

Lasse Öörni 15 سال پیش
والد
کامیت
5d53f2240a
3فایلهای تغییر یافته به همراه32 افزوده شده و 1 حذف شده
  1. 26 0
      Engine/Script/ScriptFile.cpp
  2. 5 1
      Engine/Script/ScriptFile.h
  3. 1 0
      Examples/ScriptTest/Game.cpp

+ 26 - 0
Engine/Script/ScriptFile.cpp

@@ -75,6 +75,7 @@ void ScriptFile::load(Deserializer& source, ResourceCache* cache)
     // Discard the previous module if there was one
     mCompiled = false;
     mAllIncludeFiles.clear();
+    mInterfaceFound.clear();
     setMemoryUse(0);
     removeAllEventHandlers();
     
@@ -252,6 +253,31 @@ asIScriptObject* ScriptFile::createObject(const std::string& className, asIScrip
     if (!type)
         return 0;
     
+    // Ensure that the type implements the "ScriptObject" interface, so it can be returned also to script properly
+    bool found = false;
+    std::map<asIObjectType*, bool>::const_iterator i = mInterfaceFound.find(type);
+    if (i == mInterfaceFound.end())
+    {
+        unsigned numInterfaces = type->GetInterfaceCount();
+        for (unsigned j = 0; j < numInterfaces; ++j)
+        {
+            asIObjectType* interfaceType = type->GetInterface(j);
+            if (!strcmp(interfaceType->GetName(), "ScriptObject"))
+            {
+                found = true;
+                break;
+            }
+        }
+        mInterfaceFound[type] = found;
+    }
+    else
+        found = i->second;
+    if (!found)
+    {
+        LOGERROR("Script class " + className + " does not implement the ScriptObject interface");
+        return 0;
+    }
+    
     // Get the factory function id from the object type
     std::string factoryName = className + "@ " + className + "()";
     int factoryId = type->GetFactoryIdByDecl(factoryName.c_str());

+ 5 - 1
Engine/Script/ScriptFile.h

@@ -34,12 +34,14 @@
 
 class ScriptEngine;
 class Variant;
+class asIObjectType;
 class asIScriptContext;
 class asIScriptEngine;
 class asIScriptFunction;
 class asIScriptModule;
 class asIScriptObject;
 
+
 //! A script file resource
 class ScriptFile : public Resource, public ScriptEventListener
 {
@@ -100,9 +102,11 @@ private:
     bool mCompiled;
     //! Encountered include files during script file loading
     std::set<std::string> mAllIncludeFiles;
+    //! Search cache for checking whether script classes implement "ScriptObject" interface
+    std::map<asIObjectType*, bool> mInterfaceFound;
 };
 
-//! Get last script file that is executing or has executed script code
+//! Get last script file that is executing or has executed script functions
 ScriptFile* getLastScriptFile();
 
 #endif // SCRIPT_SCRIPTFILE_H

+ 1 - 0
Examples/ScriptTest/Game.cpp

@@ -63,6 +63,7 @@ Game::Game(const std::vector<std::string>& arguments) :
 
 Game::~Game()
 {
+    // The scripts hold references to engine subsystems, not releasing them shows up as numerous memory leaks
     mCache->releaseResources(ShortStringHash("ScriptFile"), true);
 }