Pārlūkot izejas kodu

Allocate nested script execution contexts on demand.

Lasse Öörni 13 gadi atpakaļ
vecāks
revīzija
613e3e94f9
4 mainītis faili ar 13 papildinājumiem un 38 dzēšanām
  1. 0 2
      Docs/Reference.dox
  2. 12 14
      Engine/Script/Script.cpp
  3. 1 4
      Engine/Script/Script.h
  4. 0 18
      Engine/Script/ScriptFile.cpp

+ 0 - 2
Docs/Reference.dox

@@ -347,8 +347,6 @@ There are some complexities of the scripting system one has to watch out for:
 
 - During the execution of the script object's constructor, the object is not yet associated with the ScriptInstance, and therefore subscribing to events, or trying to access the node or scene will fail. The use of the constructor is best reserved for initializing member variables only.
 
-- There is a maximum allowed nesting level (currently 32) for execution that moves between C++ & AngelScript. Nested execution typically occurs if you send an event to another ScriptInstance from a scripted event handler. If the nesting level is exceeded, an error will be logged and the script code that would have required the extra nesting level will not be executed.
-
 - When the resource request for a particular ScriptFile is initially made, the script file and the files it includes are compiled into an AngelScript script module. Each script module has its own class hierarchy that is not usable from other script modules, unless the classes are declared shared. See AngelScript documentation for more details.
 
 - If a ScriptFile resource is reloaded, all the script objects created from it will be destroyed, then recreated. They will lose any stored state as their constructors and Start() methods will be run again. This is rarely useful when running an actual game, but may be helpful during development.

+ 12 - 14
Engine/Script/Script.cpp

@@ -150,13 +150,6 @@ Script::Script(Context* context) :
     immediateContext_ = scriptEngine_->CreateContext();
     immediateContext_->SetExceptionCallback(asMETHOD(Script, ExceptionCallback), this, asCALL_THISCALL);
     
-    // Create the function/method contexts
-    for (unsigned i = 0 ; i < MAX_SCRIPT_NESTING_LEVEL; ++i)
-    {
-        scriptFileContexts_.Push(scriptEngine_->CreateContext());
-        scriptFileContexts_[i]->SetExceptionCallback(asMETHOD(Script, ExceptionCallback), this, asCALL_THISCALL);
-    }
-    
     // Register the Array & String types
     RegisterArray(scriptEngine_);
     RegisterString(scriptEngine_);
@@ -169,11 +162,9 @@ Script::~Script()
         immediateContext_->Release();
         immediateContext_ = 0;
     }
-    for (unsigned i = 0 ; i < MAX_SCRIPT_NESTING_LEVEL; ++i)
-    {
-        if (scriptFileContexts_[i])
-            scriptFileContexts_[i]->Release();
-    }
+    
+    for (unsigned i = 0 ; i < scriptFileContexts_.Size(); ++i)
+        scriptFileContexts_[i]->Release();
     scriptFileContexts_.Clear();
     
     if (scriptEngine_)
@@ -436,9 +427,16 @@ asIObjectType* Script::GetObjectType(const char* declaration)
     return type;
 }
 
-asIScriptContext* Script::GetScriptFileContext() const
+asIScriptContext* Script::GetScriptFileContext()
 {
-    return scriptNestingLevel_ < scriptFileContexts_.Size() ? scriptFileContexts_[scriptNestingLevel_] : 0;
+    while (scriptNestingLevel_ >= scriptFileContexts_.Size())
+    {
+        asIScriptContext* newContext = scriptEngine_->CreateContext();
+        newContext->SetExceptionCallback(asMETHOD(Script, ExceptionCallback), this, asCALL_THISCALL);
+        scriptFileContexts_.Push(newContext);
+    }
+    
+    return scriptFileContexts_[scriptNestingLevel_];
 }
 
 void Script::OutputAPIRow(const String& row, bool removeReference)

+ 1 - 4
Engine/Script/Script.h

@@ -42,9 +42,6 @@ enum ScriptLogMode
     LOGMODE_RETAINED
 };
 
-/// Maximum function/method nesting level.
-static const unsigned MAX_SCRIPT_NESTING_LEVEL = 32;
-
 /// Scripting subsystem. Allows execution of AngelScript.
 class Script : public Object
 {
@@ -100,7 +97,7 @@ private:
     /// Return current script nesting level.
     unsigned GetScriptNestingLevel() { return scriptNestingLevel_; }
     /// Return a script function/method execution context for the current execution nesting level.
-    asIScriptContext* GetScriptFileContext() const;
+    asIScriptContext* GetScriptFileContext();
     /// Output a sanitated row of script API.
     void OutputAPIRow(const String& row, bool removeReference = false);
     

+ 0 - 18
Engine/Script/ScriptFile.cpp

@@ -170,12 +170,6 @@ bool ScriptFile::Execute(asIScriptFunction* function, const VariantVector& param
     Script* scriptSystem = script_;
     
     asIScriptContext* context = scriptSystem->GetScriptFileContext();
-    if (!context)
-    {
-        LOGERROR("Maximum script execution nesting level exceeded");
-        return false;
-    }
-    
     if (context->Prepare(function) < 0)
         return false;
     
@@ -214,12 +208,6 @@ bool ScriptFile::Execute(asIScriptObject* object, asIScriptFunction* method, con
     Script* scriptSystem = script_;
     
     asIScriptContext* context = scriptSystem->GetScriptFileContext();
-    if (!context)
-    {
-        LOGERROR("Maximum script execution nesting level exceeded");
-        return false;
-    }
-    
     if (context->Prepare(method) < 0)
         return false;
     
@@ -243,12 +231,6 @@ asIScriptObject* ScriptFile::CreateObject(const String& className)
         return 0;
     
     asIScriptContext* context = script_->GetScriptFileContext();
-    if (!context)
-    {
-        LOGERROR("Maximum script execution nesting level exceeded, can not create object");
-        return 0;
-    }
-    
     asIScriptEngine* engine = script_->GetScriptEngine();
     asIObjectType *type = engine->GetObjectTypeById(scriptModule_->GetTypeIdByDecl(className.CString()));
     if (!type)