--- a/src/ai/ai_squirrel.cpp Wed Jun 18 20:58:42 2008 +0000
+++ b/src/ai/ai_squirrel.cpp Thu Jun 19 11:55:14 2008 +0000
@@ -92,10 +92,17 @@
if (FioCheckFileExists(script_name, AI_DIR)) {
char load_script[MAX_PATH];
char dir_name[MAX_PATH];
+ char d_name_2[MAX_PATH];
+ /* In case the directory has a dot in it, ignore it, as that is the
+ * indicator for multiple versions of the same library */
+ ttd_strlcpy(d_name_2, d_name, sizeof(d_name_2));
+ char *e = strrchr(d_name_2, '.');
+ if (e != NULL) *e = '\0';
+
ttd_strlcpy(load_script, script_name, sizeof(load_script));
ttd_strlcpy(dir_name, library_depth, sizeof(dir_name));
ttd_strlcat(dir_name, ".", sizeof(dir_name));
- ttd_strlcat(dir_name, d_name, sizeof(dir_name));
+ ttd_strlcat(dir_name, d_name_2, sizeof(dir_name));
/* Remove the 'library.nut' part and replace it with 'main.nut' */
script_name[strlen(script_name) - 11] = '\0';
@@ -164,19 +171,22 @@
bool AISquirrel::ImportLibrary(const char *library, const char *class_name, int version, HSQUIRRELVM vm, AIController *controller)
{
- AILibraryList::iterator iter = this->library_list.find(library);
- /* Check if the library exists */
+ /* Internally we store libraries as 'library.version' */
+ char library_name[1024];
+ snprintf(library_name, sizeof(library_name), "%s.%d", library, version);
+
+ /* Check if the library + version exists */
+ AILibraryList::iterator iter = this->library_list.find(library_name);
if (iter == this->library_list.end()) {
char error[1024];
- snprintf(error, sizeof(error), "couldn't find library '%s'", library);
- sq_throwerror(vm, OTTD2FS(error));
- return false;
- }
- /* Check if the version matches */
- if ((*iter).second->GetVersion() != version) {
- char error[1024];
- snprintf(error, sizeof(error), "this AI is expected library '%s' to be version %d, but it is version %d", library, version, (*iter).second->GetVersion());
+ /* Now see if the version doesn't exist, or the library */
+ iter = this->library_list.find(library);
+ if (iter == this->library_list.end()) {
+ snprintf(error, sizeof(error), "couldn't find library '%s'", library);
+ } else {
+ snprintf(error, sizeof(error), "this AI is expecting library '%s' to be version %d, but the latest available is version %d", library, version, (*iter).second->GetVersion());
+ }
sq_throwerror(vm, OTTD2FS(error));
return false;
}
@@ -189,7 +199,7 @@
int next_number;
/* Check if we already have this library loaded.. if so, fill fake_class
* with the class-name it is nested in */
- if (!controller->LoadedLibrary(library, &next_number, &fake_class[0], sizeof(fake_class))) {
+ if (!controller->LoadedLibrary(library_name, &next_number, &fake_class[0], sizeof(fake_class))) {
/* Create a new fake internal name */
snprintf(fake_class, sizeof(fake_class), "_internalNA%d", next_number);
@@ -200,7 +210,7 @@
/* Load the library */
if (!Squirrel::LoadScript(vm, (*iter).second->GetScriptName(), false)) {
char error[1024];
- snprintf(error, sizeof(error), "there was a compile error when importing '%s'", library);
+ snprintf(error, sizeof(error), "there was a compile error when importing '%s' version %d", library, version);
sq_throwerror(vm, OTTD2FS(error));
return false;
}
@@ -208,7 +218,7 @@
sq_newslot(vm, -3, SQFalse);
sq_pop(vm, 1);
- controller->AddLoadedLibrary(library, fake_class);
+ controller->AddLoadedLibrary(library_name, fake_class);
}
/* Find the real class inside the fake class (like 'sets.Vector') */
@@ -221,7 +231,7 @@
sq_pushstring(vm, OTTD2FS((*iter).second->GetInstanceName()), -1);
if (SQ_FAILED(sq_get(vm, -2))) {
char error[1024];
- snprintf(error, sizeof(error), "unable to find class '%s' in the library '%s'", (*iter).second->GetInstanceName(), library);
+ snprintf(error, sizeof(error), "unable to find class '%s' in the library '%s' version %d", (*iter).second->GetInstanceName(), library, version);
sq_throwerror(vm, OTTD2FS(error));
return false;
}
@@ -248,13 +258,15 @@
void AISquirrel::RegisterLibrary(AILibrary *library)
{
- const char *ai_name = library->GetDirName();
+ const char *ai_name_without_version = library->GetDirName();
+ char ai_name[1024];
+ snprintf(ai_name, sizeof(ai_name), "%s.%d", library->GetDirName(), library->GetVersion());
/* Check if we register twice; than the first always wins */
if (this->library_list.find(ai_name) != this->library_list.end()) {
/* In case they are not the same dir, give a warning */
if (strcasecmp(library->GetScriptName(), this->library_list[ai_name]->GetScriptName()) != 0) {
- DEBUG(ai, 0, "Registering two Libraries with the same name");
+ DEBUG(ai, 0, "Registering two libraries with the same name");
DEBUG(ai, 0, " 1: %s", this->library_list[ai_name]->GetScriptName());
DEBUG(ai, 0, " 2: %s", library->GetScriptName());
DEBUG(ai, 0, "The first is taking precedence");
@@ -263,7 +275,14 @@
delete library;
return;
}
- this->library_list[ai_name] = library;
+
+ this->library_list[strdup(ai_name)] = library;
+ /* Insert the global name too, so we if the library is known at all */
+ if (this->library_list.find(ai_name_without_version) == this->library_list.end()) {
+ this->library_list[strdup(ai_name_without_version)] = library;
+ } else if (this->library_list[ai_name_without_version]->GetVersion() < library->GetVersion()) {
+ this->library_list[ai_name_without_version] = library;
+ }
}
void AISquirrel::RegisterAI(AIInfo *info)
@@ -283,7 +302,8 @@
delete info;
return;
}
- this->info_list[ai_name] = info;
+
+ this->info_list[strdup(ai_name)] = info;
}
void AISquirrel::UnregisterAI(AIInfo *info)