diff --git a/src/modes/world.cpp b/src/modes/world.cpp index d7d71b0f4..5310bdf80 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -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 //----------------------------------------------------------------------------- diff --git a/src/scriptengine/script_engine.cpp b/src/scriptengine/script_engine.cpp index 7c03d35f4..3b1d387e4 100644 --- a/src/scriptengine/script_engine.cpp +++ b/src/scriptengine/script_engine.cpp @@ -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; } } diff --git a/src/scriptengine/script_engine.hpp b/src/scriptengine/script_engine.hpp index 961d16ecb..1d6aa956d 100644 --- a/src/scriptengine/script_engine.hpp +++ b/src/scriptengine/script_engine.hpp @@ -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 m_loaded_files; std::map m_functions_cache; void configureEngine(asIScriptEngine *engine); - int compileScript(asIScriptEngine *engine,std::string scriptName); }; // class ScriptEngine } diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index d5faeb0b7..6f97b2636 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -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 {