Codechange: [Script] rework how compat-scripts work and are loaded (#13504)
- compat_NNN.nut files now only defines what is needed to downgrade from API NNN + 1 to NNN. - Automatically load all required compatibility files based on the API version of the script, starting with the latest.
This commit is contained in:
@@ -116,9 +116,10 @@ void ScriptInstance::RegisterAPI()
|
||||
squirrel_register_std(this->engine);
|
||||
}
|
||||
|
||||
bool ScriptInstance::LoadCompatibilityScripts(const std::string &api_version, Subdirectory dir)
|
||||
bool ScriptInstance::LoadCompatibilityScript(std::string_view api_version, Subdirectory dir)
|
||||
{
|
||||
std::string script_name = fmt::format("compat_{}.nut", api_version);
|
||||
|
||||
for (Searchpath sp : _valid_searchpaths) {
|
||||
std::string buf = FioGetDirectory(sp, dir);
|
||||
buf += script_name;
|
||||
@@ -126,12 +127,30 @@ bool ScriptInstance::LoadCompatibilityScripts(const std::string &api_version, Su
|
||||
|
||||
if (this->engine->LoadScript(buf)) return true;
|
||||
|
||||
ScriptLog::Error("Failed to load API compatibility script");
|
||||
ScriptLog::Error(fmt::format("Failed to load API compatibility script for {}", api_version));
|
||||
Debug(script, 0, "Error compiling / running API compatibility script: {}", buf);
|
||||
return false;
|
||||
}
|
||||
|
||||
ScriptLog::Warning("API compatibility script not found");
|
||||
ScriptLog::Warning(fmt::format("API compatibility script for {} not found", api_version));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScriptInstance::LoadCompatibilityScripts(Subdirectory dir, std::span<const std::string_view> api_versions)
|
||||
{
|
||||
/* Don't try to load compatibility scripts for the current version. */
|
||||
if (this->versionAPI == std::rbegin(api_versions)->data()) return true;
|
||||
|
||||
ScriptLog::Info(fmt::format("Downgrading API to be compatible with version {}", this->versionAPI));
|
||||
|
||||
/* Downgrade the API till we are the same version as the script. The last
|
||||
* entry in the list is always the current version, so skip that one. */
|
||||
for (auto it = std::rbegin(api_versions) + 1; it != std::rend(api_versions); ++it) {
|
||||
if (!this->LoadCompatibilityScript(*it, dir)) return false;
|
||||
|
||||
if (*it == this->versionAPI) break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -261,11 +261,11 @@ protected:
|
||||
|
||||
/**
|
||||
* Load squirrel scripts to emulate an older API.
|
||||
* @param api_version: API version to load scripts for
|
||||
* @param dir Subdirectory to find the scripts in
|
||||
* @return true iff script loading should proceed
|
||||
* @param dir Subdirectory to find the scripts in.
|
||||
* @param api_versions List of available versions of the script type.
|
||||
* @return true iff script loading should proceed.
|
||||
*/
|
||||
bool LoadCompatibilityScripts(const std::string &api_version, Subdirectory dir);
|
||||
bool LoadCompatibilityScripts(Subdirectory dir, std::span<const std::string_view> api_versions);
|
||||
|
||||
/**
|
||||
* Tell the script it died.
|
||||
@@ -302,6 +302,14 @@ private:
|
||||
*/
|
||||
bool CallLoad();
|
||||
|
||||
/**
|
||||
* Load squirrel script for a specific version to emulate an older API.
|
||||
* @param api_version: API version to load scripts for.
|
||||
* @param dir Subdirectory to find the scripts in.
|
||||
* @return true iff script loading should proceed.
|
||||
*/
|
||||
bool LoadCompatibilityScript(std::string_view api_version, Subdirectory dir);
|
||||
|
||||
/**
|
||||
* Save one object (int / string / array / table) to the savegame.
|
||||
* @param vm The virtual machine to get all the data from.
|
||||
|
||||
Reference in New Issue
Block a user