diff options
author | yexo <yexo@openttd.org> | 2009-03-15 22:41:57 +0000 |
---|---|---|
committer | yexo <yexo@openttd.org> | 2009-03-15 22:41:57 +0000 |
commit | ce4744e1d6637d0dec3766c5a827b43859396e58 (patch) | |
tree | 9f32a6c0a0ae74a9f2ba9bdd8534a3dbfff3e054 /src/ai | |
parent | dda23960960133b5edd01a286aa5d43864886117 (diff) | |
download | openttd-ce4744e1d6637d0dec3766c5a827b43859396e58.tar.xz |
(svn r15736) -Codechange: Split AIScanner/AIFileInfo to the more generic classes ScriptScanner/ScriptFileInfo.
Diffstat (limited to 'src/ai')
-rw-r--r-- | src/ai/ai_info.cpp | 77 | ||||
-rw-r--r-- | src/ai/ai_info.hpp | 79 | ||||
-rw-r--r-- | src/ai/ai_scanner.cpp | 110 | ||||
-rw-r--r-- | src/ai/ai_scanner.hpp | 24 |
4 files changed, 26 insertions, 264 deletions
diff --git a/src/ai/ai_info.cpp b/src/ai/ai_info.cpp index 4d9cfa9a2..cb5d9b645 100644 --- a/src/ai/ai_info.cpp +++ b/src/ai/ai_info.cpp @@ -28,75 +28,15 @@ AIConfigItem _start_date_config = { NULL }; -AIFileInfo::~AIFileInfo() -{ - free((void *)this->author); - free((void *)this->name); - free((void *)this->short_name); - free((void *)this->description); - free((void *)this->date); - free((void *)this->instance_name); - free(this->main_script); - free(this->SQ_instance); -} - AILibrary::~AILibrary() { free((void *)this->category); } -bool AIFileInfo::GetSettings() +/* static */ SQInteger AIFileInfo::Constructor(HSQUIRRELVM vm, AIFileInfo *info) { - return this->engine->CallMethod(*this->SQ_instance, "GetSettings", NULL, -1); -} - -bool AIFileInfo::CheckMethod(const char *name) const -{ - if (!this->engine->MethodExists(*this->SQ_instance, name)) { - char error[1024]; - snprintf(error, sizeof(error), "your info.nut/library.nut doesn't have the method '%s'", name); - this->engine->ThrowError(error); - return false; - } - return true; -} - -/* static */ SQInteger AIFileInfo::Constructor(HSQUIRRELVM vm, AIFileInfo *info, bool library) -{ - /* Set some basic info from the parent */ - info->SQ_instance = MallocT<SQObject>(1); - Squirrel::GetInstance(vm, info->SQ_instance, 2); - /* Make sure the instance stays alive over time */ - sq_addref(vm, info->SQ_instance); + ScriptFileInfo::Constructor(vm, info); info->base = ((AIScanner *)Squirrel::GetGlobalPointer(vm)); - info->engine = info->base->GetEngine(); - - static const char * const required_functions[] = { - "GetAuthor", - "GetName", - "GetShortName", - "GetDescription", - "GetVersion", - "GetDate", - "CreateInstance", - }; - for (size_t i = 0; i < lengthof(required_functions); i++) { - if (!info->CheckMethod(required_functions[i])) return SQ_ERROR; - } - if (library) { - if (!info->CheckMethod("GetCategory")) return SQ_ERROR; - } - - info->main_script = strdup(info->base->GetMainScript()); - - /* Cache the data the info file gives us. */ - if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetAuthor", &info->author)) return SQ_ERROR; - if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetName", &info->name)) return SQ_ERROR; - if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetShortName", &info->short_name)) return SQ_ERROR; - if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetDescription", &info->description)) return SQ_ERROR; - if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetDate", &info->date)) return SQ_ERROR; - if (!info->engine->CallIntegerMethod(*info->SQ_instance, "GetVersion", &info->version)) return SQ_ERROR; - if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "CreateInstance", &info->instance_name)) return SQ_ERROR; return 0; } @@ -108,7 +48,7 @@ bool AIFileInfo::CheckMethod(const char *name) const if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == NULL) return sq_throwerror(vm, _SC("Pass an instance of a child class of AIInfo to RegisterAI")); AIInfo *info = (AIInfo *)instance; - SQInteger res = AIFileInfo::Constructor(vm, info, false); + SQInteger res = AIFileInfo::Constructor(vm, info); if (res != 0) return res; AIConfigItem config = _start_date_config; @@ -140,7 +80,7 @@ bool AIFileInfo::CheckMethod(const char *name) const sq_getinstanceup(vm, 2, &instance, 0); AIInfo *info = (AIInfo *)instance; - SQInteger res = AIFileInfo::Constructor(vm, info, false); + SQInteger res = AIFileInfo::Constructor(vm, info); if (res != 0) return res; /* Remove the link to the real instance, else it might get deleted by RegisterAI() */ @@ -150,6 +90,11 @@ bool AIFileInfo::CheckMethod(const char *name) const return 0; } +bool AIInfo::GetSettings() +{ + return this->engine->CallMethod(*this->SQ_instance, "GetSettings", NULL, -1); +} + AIInfo::~AIInfo() { /* Free all allocated strings */ @@ -360,14 +305,14 @@ int AIInfo::GetSettingDefaultValue(const char *name) const /* Create a new AIFileInfo */ AILibrary *library = new AILibrary(); - SQInteger res = AIFileInfo::Constructor(vm, library, true); + SQInteger res = AIFileInfo::Constructor(vm, library); if (res != 0) { delete library; return res; } /* Cache the category */ - if (!library->engine->CallStringMethodStrdup(*library->SQ_instance, "GetCategory", &library->category)) { + if (!library->CheckMethod("GetCategory") || !library->engine->CallStringMethodStrdup(*library->SQ_instance, "GetCategory", &library->category)) { delete library; return SQ_ERROR; } diff --git a/src/ai/ai_info.hpp b/src/ai/ai_info.hpp index ef8505e2d..1d86bc9ff 100644 --- a/src/ai/ai_info.hpp +++ b/src/ai/ai_info.hpp @@ -7,7 +7,7 @@ #include <list> #include "../core/smallmap_type.hpp" -#include "api/ai_object.hpp" +#include "../script/script_info.hpp" enum AIConfigFlags { AICONFIG_NONE = 0x0, @@ -36,81 +36,15 @@ extern AIConfigItem _start_date_config; typedef std::list<AIConfigItem> AIConfigItemList; -class AIFileInfo : public AIObject { +class AIFileInfo : public ScriptFileInfo { public: - friend class AIInfo; - friend class AILibrary; - - AIFileInfo() : SQ_instance(NULL), main_script(NULL), author(NULL), name(NULL), short_name(NULL), description(NULL), date(NULL), instance_name(NULL) {}; - ~AIFileInfo(); - - /** - * Get the Author of the AI. - */ - const char *GetAuthor() const { return this->author; } - - /** - * Get the Name of the AI. - */ - const char *GetName() const { return this->name; } - - /** - * Get the 4 character long short name of the AI. - */ - const char *GetShortName() const { return this->short_name; } - - /** - * Get the description of the AI. - */ - const char *GetDescription() const { return this->description; } - - /** - * Get the version of the AI. - */ - int GetVersion() const { return this->version; } - - /** - * Get the settings of the AI. - */ - bool GetSettings(); - - /** - * Get the date of the AI. - */ - const char *GetDate() const { return this->date; } - - /** - * Get the name of the instance of the AI to create. - */ - const char *GetInstanceName() const { return this->instance_name; } - - /** - * Get the filename of the main.nut script. - */ - const char *GetMainScript() const { return this->main_script; } - - /** - * Check if a given method exists. - */ - bool CheckMethod(const char *name) const; - /** * Process the creation of a FileInfo object. */ - static SQInteger Constructor(HSQUIRRELVM vm, AIFileInfo *info, bool library); + static SQInteger Constructor(HSQUIRRELVM vm, AIFileInfo *info); -private: - class Squirrel *engine; - HSQOBJECT *SQ_instance; - char *main_script; +protected: class AIScanner *base; - const char *author; - const char *name; - const char *short_name; - const char *description; - const char *date; - const char *instance_name; - int version; }; class AIInfo : public AIFileInfo { @@ -126,6 +60,11 @@ public: static SQInteger DummyConstructor(HSQUIRRELVM vm); /** + * Get the settings of the AI. + */ + bool GetSettings(); + + /** * Get the config list for this AI. */ const AIConfigItemList *GetConfigList() const; diff --git a/src/ai/ai_scanner.cpp b/src/ai/ai_scanner.cpp index a35055133..af452f086 100644 --- a/src/ai/ai_scanner.cpp +++ b/src/ai/ai_scanner.cpp @@ -20,114 +20,16 @@ #include "ai_scanner.hpp" #include "api/ai_controller.hpp" -void AIScanner::ScanDir(const char *dirname, bool library_scan) -{ - extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb); - extern bool FiosIsHiddenFile(const struct dirent *ent); - - char d_name[MAX_PATH]; - char temp_script[1024]; - struct stat sb; - struct dirent *dirent; - DIR *dir; - - dir = ttd_opendir(dirname); - /* Dir not found, so do nothing */ - if (dir == NULL) return; - - /* Walk all dirs trying to find a dir in which 'main.nut' exists */ - while ((dirent = readdir(dir)) != NULL) { - ttd_strlcpy(d_name, FS2OTTD(dirent->d_name), sizeof(d_name)); - - /* Valid file, not '.' or '..', not hidden */ - if (!FiosIsValidFile(dirname, dirent, &sb)) continue; - if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue; - if (FiosIsHiddenFile(dirent) && strncasecmp(d_name, PERSONAL_DIR, strlen(d_name)) != 0) continue; - - /* Create the full length dirname */ - ttd_strlcpy(temp_script, dirname, sizeof(temp_script)); - ttd_strlcat(temp_script, d_name, sizeof(temp_script)); - - if (S_ISREG(sb.st_mode)) { - /* Only .tar files are allowed */ - char *ext = strrchr(d_name, '.'); - if (ext == NULL || strcasecmp(ext, ".tar") != 0) continue; - - /* We always expect a directory in the TAR */ - const char *first_dir = FioTarFirstDir(temp_script); - if (first_dir == NULL) continue; - - ttd_strlcat(temp_script, PATHSEP, sizeof(temp_script)); - ttd_strlcat(temp_script, first_dir, sizeof(temp_script)); - FioTarAddLink(temp_script, first_dir); - } else if (!S_ISDIR(sb.st_mode)) { - /* Skip any other type of file */ - continue; - } - - /* Add an additional / where needed */ - if (temp_script[strlen(temp_script) - 1] != PATHSEPCHAR) ttd_strlcat(temp_script, PATHSEP, sizeof(temp_script)); - - if (!library_scan) { - char info_script[MAX_PATH]; - ttd_strlcpy(info_script, temp_script, sizeof(info_script)); - ttd_strlcpy(main_script, temp_script, sizeof(main_script)); - - /* Every AI should contain an 'info.nut' and 'main.nut' file; else it is not a valid AI */ - ttd_strlcat(info_script, "info.nut", sizeof(info_script)); - ttd_strlcat(main_script, "main.nut", sizeof(main_script)); - if (!FioCheckFileExists(info_script, AI_DIR) || !FioCheckFileExists(main_script, AI_DIR)) continue; - - DEBUG(ai, 6, "Loading AI at location '%s'", main_script); - /* We don't care if one of the other scripts failed to load. */ - this->engine->ResetCrashed(); - this->engine->LoadScript(info_script); - } else { - char library_script[MAX_PATH]; - ttd_strlcpy(library_script, temp_script, sizeof(library_script)); - ttd_strlcpy(main_script, temp_script, sizeof(main_script)); - - /* Every library should contain an 'library.nut' and 'main.nut' file; else it is not a valid library */ - ttd_strlcat(library_script, "library.nut", sizeof(library_script)); - ttd_strlcat(main_script, "main.nut", sizeof(main_script)); - if (!FioCheckFileExists(library_script, AI_LIBRARY_DIR) || !FioCheckFileExists(main_script, AI_LIBRARY_DIR)) continue; - - DEBUG(ai, 6, "Loading AI Library at location '%s'", main_script); - /* We don't care if one of the other scripst failed to load. */ - this->engine->ResetCrashed(); - this->engine->LoadScript(library_script); - } - } - closedir(dir); -} - -void AIScanner::ScanAIDir() -{ - char buf[MAX_PATH]; - Searchpath sp; - - extern void ScanForTarFiles(); - ScanForTarFiles(); - - FOR_ALL_SEARCHPATHS(sp) { - FioAppendDirectory(buf, MAX_PATH, sp, AI_DIR); - if (FileExists(buf)) this->ScanDir(buf, false); - FioAppendDirectory(buf, MAX_PATH, sp, AI_LIBRARY_DIR); - if (FileExists(buf)) this->ScanDir(buf, true); - } -} - void AIScanner::RescanAIDir() { - this->ScanAIDir(); + this->ScanScriptDir("info.nut", AI_DIR); + this->ScanScriptDir("library.nut", AI_LIBRARY_DIR); } AIScanner::AIScanner() : + ScriptScanner(), info_dummy(NULL) { - this->engine = new Squirrel(); - this->main_script[0] = '\0'; - /* Create the AIInfo class, and add the RegisterAI function */ DefSQClass <AIInfo> SQAIInfo("AIInfo"); SQAIInfo.PreRegister(engine); @@ -145,11 +47,8 @@ AIScanner::AIScanner() : this->engine->AddClassEnd(); this->engine->AddMethod("RegisterLibrary", &AILibrary::Constructor, 2, "tx"); - /* Mark this class as global pointer */ - this->engine->SetGlobalPointer(this); - /* Scan the AI dir for scripts */ - this->ScanAIDir(); + this->RescanAIDir(); /* Create the dummy AI */ this->engine->ResetCrashed(); @@ -176,7 +75,6 @@ AIScanner::~AIScanner() } delete this->info_dummy; - delete this->engine; } bool AIScanner::ImportLibrary(const char *library, const char *class_name, int version, HSQUIRRELVM vm, AIController *controller) diff --git a/src/ai/ai_scanner.hpp b/src/ai/ai_scanner.hpp index dbbadb1e8..d2e98c319 100644 --- a/src/ai/ai_scanner.hpp +++ b/src/ai/ai_scanner.hpp @@ -5,10 +5,11 @@ #ifndef AI_SCANNER_HPP #define AI_SCANNER_HPP +#include "../script/script_scanner.hpp" #include "../core/string_compare_type.hpp" #include <map> -class AIScanner { +class AIScanner : public ScriptScanner { public: AIScanner(); ~AIScanner(); @@ -56,16 +57,6 @@ public: const AIInfoList *GetUniqueAIInfoList() { return &this->info_single_list; } /** - * Get the engine of the main squirrel handler (it indexes all available scripts). - */ - class Squirrel *GetEngine() { return this->engine; } - - /** - * Get the current main script the ScanDir is currently tracking. - */ - const char *GetMainScript() { return this->main_script; } - - /** * Rescan the AI dir for scripts. */ void RescanAIDir(); @@ -81,21 +72,10 @@ private: */ void ScanAIDir(); - /** - * Scan a dir for AIs. - * For non-library-scan, if an AI is found, AIInfo is created, and the AI - * is registered to the central system. - * For library-scan, if a library is found, AILibrary is created, and the - * library is registered to the central system. - */ - void ScanDir(const char *dirname, bool library_dir); - AIInfo *info_dummy; AIInfoList info_list; AIInfoList info_single_list; AILibraryList library_list; - class Squirrel *engine; - char main_script[1024]; }; #endif /* AI_SCANNER_HPP */ |