Browse Source

Allocate nested script execution contexts on demand.

Lasse Öörni 13 years ago
parent
commit
613e3e94f9
4 changed files with 13 additions and 38 deletions
  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.
 - 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.
 - 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.
 - 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_ = scriptEngine_->CreateContext();
     immediateContext_->SetExceptionCallback(asMETHOD(Script, ExceptionCallback), this, asCALL_THISCALL);
     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
     // Register the Array & String types
     RegisterArray(scriptEngine_);
     RegisterArray(scriptEngine_);
     RegisterString(scriptEngine_);
     RegisterString(scriptEngine_);
@@ -169,11 +162,9 @@ Script::~Script()
         immediateContext_->Release();
         immediateContext_->Release();
         immediateContext_ = 0;
         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();
     scriptFileContexts_.Clear();
     
     
     if (scriptEngine_)
     if (scriptEngine_)
@@ -436,9 +427,16 @@ asIObjectType* Script::GetObjectType(const char* declaration)
     return type;
     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)
 void Script::OutputAPIRow(const String& row, bool removeReference)

+ 1 - 4
Engine/Script/Script.h

@@ -42,9 +42,6 @@ enum ScriptLogMode
     LOGMODE_RETAINED
     LOGMODE_RETAINED
 };
 };
 
 
-/// Maximum function/method nesting level.
-static const unsigned MAX_SCRIPT_NESTING_LEVEL = 32;
-
 /// Scripting subsystem. Allows execution of AngelScript.
 /// Scripting subsystem. Allows execution of AngelScript.
 class Script : public Object
 class Script : public Object
 {
 {
@@ -100,7 +97,7 @@ private:
     /// Return current script nesting level.
     /// Return current script nesting level.
     unsigned GetScriptNestingLevel() { return scriptNestingLevel_; }
     unsigned GetScriptNestingLevel() { return scriptNestingLevel_; }
     /// Return a script function/method execution context for the current execution nesting level.
     /// 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.
     /// Output a sanitated row of script API.
     void OutputAPIRow(const String& row, bool removeReference = false);
     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_;
     Script* scriptSystem = script_;
     
     
     asIScriptContext* context = scriptSystem->GetScriptFileContext();
     asIScriptContext* context = scriptSystem->GetScriptFileContext();
-    if (!context)
-    {
-        LOGERROR("Maximum script execution nesting level exceeded");
-        return false;
-    }
-    
     if (context->Prepare(function) < 0)
     if (context->Prepare(function) < 0)
         return false;
         return false;
     
     
@@ -214,12 +208,6 @@ bool ScriptFile::Execute(asIScriptObject* object, asIScriptFunction* method, con
     Script* scriptSystem = script_;
     Script* scriptSystem = script_;
     
     
     asIScriptContext* context = scriptSystem->GetScriptFileContext();
     asIScriptContext* context = scriptSystem->GetScriptFileContext();
-    if (!context)
-    {
-        LOGERROR("Maximum script execution nesting level exceeded");
-        return false;
-    }
-    
     if (context->Prepare(method) < 0)
     if (context->Prepare(method) < 0)
         return false;
         return false;
     
     
@@ -243,12 +231,6 @@ asIScriptObject* ScriptFile::CreateObject(const String& className)
         return 0;
         return 0;
     
     
     asIScriptContext* context = script_->GetScriptFileContext();
     asIScriptContext* context = script_->GetScriptFileContext();
-    if (!context)
-    {
-        LOGERROR("Maximum script execution nesting level exceeded, can not create object");
-        return 0;
-    }
-    
     asIScriptEngine* engine = script_->GetScriptEngine();
     asIScriptEngine* engine = script_->GetScriptEngine();
     asIObjectType *type = engine->GetObjectTypeById(scriptModule_->GetTypeIdByDecl(className.CString()));
     asIObjectType *type = engine->GetObjectTypeById(scriptModule_->GetTypeIdByDecl(className.CString()));
     if (!type)
     if (!type)