Adjust load and cleanup sequence for scripts, enabling scripts in library objects

This commit is contained in:
Marianne Gagnon 2015-06-09 20:24:17 -04:00
parent cb510840ae
commit 32edaa25fe
4 changed files with 40 additions and 36 deletions

View File

@ -163,6 +163,9 @@ void World::init()
throw std::runtime_error(msg.str());
}
std::string script_path = World::getWorld()->getTrack()->getTrackFile("scripting.as");
m_script_engine->loadScript(script_path, true);
// Create the physics
m_physics = new Physics();
@ -207,6 +210,8 @@ void World::init()
m_weather = new Weather(m_track->getWeatherLightning(),
m_track->getWeatherSound());
}
m_script_engine->compileLoadedScripts();
} // init
//-----------------------------------------------------------------------------

View File

@ -85,14 +85,14 @@ namespace Scripting
* \param string scriptname = name of script to get
* \return The corresponding script
*/
std::string getScript(std::string fileName)
std::string getScript(std::string script_path)
{
std::string script_path = World::getWorld()->getTrack()->getTrackFile(fileName);
//std::string script_path = World::getWorld()->getTrack()->getTrackFile(fileName);
FILE *f = fopen(script_path.c_str(), "rb");
if (f == NULL)
{
Log::debug("Scripting", "File does not exist : {0}.as", fileName.c_str());
Log::debug("Scripting", "File does not exist : {0}", script_path.c_str());
return "";
}
@ -205,29 +205,7 @@ namespace Scripting
// TODO: allow splitting in multiple files
std::string script_filename = "scripting.as";
auto cached_script = m_loaded_files.find(script_filename);
auto cached_function = m_functions_cache.find(function_name);
if (cached_script == m_loaded_files.end())
{
// Compile the script code
Log::info("Scripting", "Checking for script file '%s'", script_filename.c_str());
r = compileScript(m_engine, script_filename);
if (r < 0)
{
Log::info("Scripting", "Script '%s' is not available", script_filename.c_str());
m_loaded_files[script_filename] = false;
m_functions_cache[function_name] = NULL; // remember that this script is unavailable
return;
}
m_loaded_files[script_filename] = true;
}
else if (cached_script->second == false)
{
return; // script file unavailable
}
if (cached_function == m_functions_cache.end())
{
// Find the function for the function we want to execute.
@ -239,7 +217,7 @@ namespace Scripting
if (func == NULL)
{
Log::debug("Scripting", "Scripting function was not found : %s", function_name.c_str());
m_loaded_files[function_name] = NULL; // remember that this script is unavailable
m_functions_cache[function_name] = NULL; // remember that this function is unavailable
return;
}
@ -337,7 +315,7 @@ namespace Scripting
curr.second->Release();
}
m_functions_cache.clear();
m_loaded_files.clear();
m_engine->DiscardModule(MODULE_ID_MAIN_SCRIPT_FILE);
}
//-----------------------------------------------------------------------------
@ -369,15 +347,15 @@ namespace Scripting
//-----------------------------------------------------------------------------
int ScriptEngine::compileScript(asIScriptEngine *engine, std::string scriptName)
bool ScriptEngine::loadScript(std::string script_path, bool clear_previous)
{
int r;
std::string script = getScript(scriptName);
std::string script = getScript(script_path);
if (script.size() == 0)
{
// No such file
return -1;
return false;
}
// Add the script sections that will be compiled into executable code.
@ -385,14 +363,25 @@ namespace Scripting
// we can call AddScriptSection() several times for the same module and
// the script engine will treat them all as if they were one. The script
// section name, will allow us to localize any errors in the script code.
asIScriptModule *mod = engine->GetModule(MODULE_ID_MAIN_SCRIPT_FILE, asGM_ALWAYS_CREATE);
asIScriptModule *mod = m_engine->GetModule(MODULE_ID_MAIN_SCRIPT_FILE,
clear_previous ? asGM_ALWAYS_CREATE : asGM_ONLY_IF_EXISTS);
r = mod->AddScriptSection("script", &script[0], script.size());
if (r < 0)
{
Log::error("Scripting", "AddScriptSection() failed");
return -1;
return false;
}
return true;
}
//-----------------------------------------------------------------------------
bool ScriptEngine::compileLoadedScripts()
{
int r;
asIScriptModule *mod = m_engine->GetModule(MODULE_ID_MAIN_SCRIPT_FILE, asGM_ONLY_IF_EXISTS);
// Compile the script. If there are any compiler messages they will
// be written to the message stream that we set right after creating the
// script engine. If there are no errors, and no warnings, nothing will
@ -401,7 +390,7 @@ namespace Scripting
if (r < 0)
{
Log::error("Scripting", "Build() failed");
return -1;
return false;
}
// The engine doesn't keep a copy of the script sections after Build() has
@ -414,6 +403,6 @@ namespace Scripting
// scope, so function names, and global variables will not conflict with
// each other.
return 0;
return true;
}
}

View File

@ -43,13 +43,14 @@ namespace Scripting
void evalScript(std::string script_fragment);
void cleanupCache();
bool loadScript(std::string script_path, bool clear_previous);
bool compileLoadedScripts();
private:
asIScriptEngine *m_engine;
std::map<std::string, bool> m_loaded_files;
std::map<std::string, asIScriptFunction*> m_functions_cache;
void configureEngine(asIScriptEngine *engine);
int compileScript(asIScriptEngine *engine,std::string scriptName);
}; // class ScriptEngine
}

View File

@ -183,18 +183,27 @@ TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
if (world != NULL)
track = world->getTrack();
std::string local_lib_node_path;
std::string local_script_file_path;
if (track != NULL)
{
local_lib_node_path = track->getTrackFile("library/" + name + "/node.xml");
local_script_file_path = track->getTrackFile("library/" + name + "/scripting.as");
}
std::string lib_node_path = lib_path + "node.xml";
std::string lib_script_file_path = lib_path + "scripting.as";
if (local_lib_node_path.size() > 0 && file_manager->fileExists(local_lib_node_path))
{
lib_path = track->getTrackFile("library/" + name);
libroot = file_manager->createXMLTree(local_lib_node_path);
if (track != NULL)
World::getWorld()->getScriptEngine()->loadScript(lib_script_file_path, false);
}
else if (file_manager->fileExists(lib_node_path))
{
libroot = file_manager->createXMLTree(lib_node_path);
if (track != NULL)
World::getWorld()->getScriptEngine()->loadScript(lib_script_file_path, false);
}
else
{