From ce4744e1d6637d0dec3766c5a827b43859396e58 Mon Sep 17 00:00:00 2001 From: yexo Date: Sun, 15 Mar 2009 22:41:57 +0000 Subject: (svn r15736) -Codechange: Split AIScanner/AIFileInfo to the more generic classes ScriptScanner/ScriptFileInfo. --- projects/openttd_vs80.vcproj | 16 ++++++ projects/openttd_vs90.vcproj | 16 ++++++ source.list | 4 ++ src/ai/ai_info.cpp | 77 +++++------------------------ src/ai/ai_info.hpp | 79 ++++-------------------------- src/ai/ai_scanner.cpp | 110 ++---------------------------------------- src/ai/ai_scanner.hpp | 24 +-------- src/script/script_info.cpp | 72 +++++++++++++++++++++++++++ src/script/script_info.hpp | 88 +++++++++++++++++++++++++++++++++ src/script/script_scanner.cpp | 105 ++++++++++++++++++++++++++++++++++++++++ src/script/script_scanner.hpp | 43 +++++++++++++++++ src/settings.cpp | 1 + 12 files changed, 371 insertions(+), 264 deletions(-) create mode 100644 src/script/script_info.cpp create mode 100644 src/script/script_info.hpp create mode 100644 src/script/script_scanner.cpp create mode 100644 src/script/script_scanner.hpp diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj index ff547623b..386311ede 100644 --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -2267,6 +2267,22 @@ + + + + + + + + diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj index ee5c4a1e4..980b6f67f 100644 --- a/projects/openttd_vs90.vcproj +++ b/projects/openttd_vs90.vcproj @@ -2264,6 +2264,22 @@ + + + + + + + + diff --git a/source.list b/source.list index 662202469..c9c8b0d46 100644 --- a/source.list +++ b/source.list @@ -518,6 +518,10 @@ table/unmovable_land.h table/water_land.h # Script +script/script_info.cpp +script/script_info.hpp +script/script_scanner.cpp +script/script_scanner.hpp script/squirrel.cpp script/squirrel.hpp script/squirrel_class.hpp 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(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 #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 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 { @@ -125,6 +59,11 @@ public: static SQInteger Constructor(HSQUIRRELVM vm); static SQInteger DummyConstructor(HSQUIRRELVM vm); + /** + * Get the settings of the AI. + */ + bool GetSettings(); + /** * Get the config list for this AI. */ 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 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 -class AIScanner { +class AIScanner : public ScriptScanner { public: AIScanner(); ~AIScanner(); @@ -55,16 +56,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. */ @@ -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 */ diff --git a/src/script/script_info.cpp b/src/script/script_info.cpp new file mode 100644 index 000000000..12df08ce5 --- /dev/null +++ b/src/script/script_info.cpp @@ -0,0 +1,72 @@ +/* $Id$ */ + +/** @file script_info.cpp Implementation of ScriptFileInfo. */ + +#include "../stdafx.h" + +#include +#include "squirrel.hpp" +#include "squirrel_helper.hpp" + +#include "script_info.hpp" +#include "script_scanner.hpp" + +ScriptFileInfo::~ScriptFileInfo() +{ + 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); +} + +bool ScriptFileInfo::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 ScriptFileInfo::Constructor(HSQUIRRELVM vm, ScriptFileInfo *info) +{ + /* Set some basic info from the parent */ + info->SQ_instance = MallocT(1); + Squirrel::GetInstance(vm, info->SQ_instance, 2); + /* Make sure the instance stays alive over time */ + sq_addref(vm, info->SQ_instance); + ScriptScanner *scanner = (ScriptScanner *)Squirrel::GetGlobalPointer(vm); + info->engine = scanner->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; + } + + info->main_script = strdup(scanner->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; +} diff --git a/src/script/script_info.hpp b/src/script/script_info.hpp new file mode 100644 index 000000000..d34fd4cef --- /dev/null +++ b/src/script/script_info.hpp @@ -0,0 +1,88 @@ +/* $Id$ */ + +/** @file script_info.hpp ScriptInfo keeps track of all information of a script, like Author, Description, ... */ + +#ifndef SCRIPT_INFO +#define SCRIPT_INFO + +#include "../misc/countedptr.hpp" + +class ScriptFileInfo : public SimpleCountedObject { +public: + ScriptFileInfo() : + SQ_instance(NULL), + main_script(NULL), + author(NULL), + name(NULL), + short_name(NULL), + description(NULL), + date(NULL), + instance_name(NULL) + {} + ~ScriptFileInfo(); + + /** + * Get the Author of the script. + */ + const char *GetAuthor() const { return this->author; } + + /** + * Get the Name of the script. + */ + const char *GetName() const { return this->name; } + + /** + * Get the 4 character long short name of the script. + */ + const char *GetShortName() const { return this->short_name; } + + /** + * Get the description of the script. + */ + const char *GetDescription() const { return this->description; } + + /** + * Get the version of the script. + */ + int GetVersion() const { return this->version; } + + /** + * Get the last-modified date of the script. + */ + const char *GetDate() const { return this->date; } + + /** + * Get the name of the instance of the script 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, ScriptFileInfo *info); + +protected: + class Squirrel *engine; + HSQOBJECT *SQ_instance; +private: + char *main_script; + const char *author; + const char *name; + const char *short_name; + const char *description; + const char *date; + const char *instance_name; + int version; +}; + +#endif /* SCRIPT_INFO */ diff --git a/src/script/script_scanner.cpp b/src/script/script_scanner.cpp new file mode 100644 index 000000000..7b993889e --- /dev/null +++ b/src/script/script_scanner.cpp @@ -0,0 +1,105 @@ +/* $Id$ */ + +/** @file script_scanner.cpp Allows scanning for scripts. */ + +#include "../stdafx.h" +#include "../string_func.h" +#include "../fileio_func.h" +#include + +#include +#include "../script/squirrel.hpp" +#include "script_info.hpp" +#include "script_scanner.hpp" + +void ScriptScanner::ScanDir(const char *dirname, const char *info_file_name) +{ + 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)); + + char info_script[MAX_PATH]; + ttd_strlcpy(info_script, temp_script, sizeof(info_script)); + ttd_strlcpy(main_script, temp_script, sizeof(main_script)); + + /* Every script should contain an 'info.nut' and 'main.nut' file; else it is not a valid script */ + ttd_strlcat(info_script, info_file_name, sizeof(info_script)); + ttd_strlcat(main_script, "main.nut", sizeof(main_script)); + if (!FioCheckFileExists(info_script, NO_DIRECTORY) || !FioCheckFileExists(main_script, NO_DIRECTORY)) continue; + + /* We don't care if one of the other scripts failed to load. */ + this->engine->ResetCrashed(); + this->engine->LoadScript(info_script); + } + closedir(dir); +} + +void ScriptScanner::ScanScriptDir(const char *info_file_name, Subdirectory search_dir) +{ + char buf[MAX_PATH]; + Searchpath sp; + + extern void ScanForTarFiles(); + ScanForTarFiles(); + + FOR_ALL_SEARCHPATHS(sp) { + FioAppendDirectory(buf, MAX_PATH, sp, search_dir); + if (FileExists(buf)) this->ScanDir(buf, info_file_name); + } +} + +ScriptScanner::ScriptScanner() +{ + this->engine = new Squirrel(); + this->main_script[0] = '\0'; + + /* Mark this class as global pointer */ + this->engine->SetGlobalPointer(this); +} + +ScriptScanner::~ScriptScanner() +{ + delete this->engine; +} diff --git a/src/script/script_scanner.hpp b/src/script/script_scanner.hpp new file mode 100644 index 000000000..922e37202 --- /dev/null +++ b/src/script/script_scanner.hpp @@ -0,0 +1,43 @@ +/* $Id$ */ + +/** @file script_scanner.hpp Declarations of the class for the script scanner. */ + +#ifndef SCRIPT_SCANNER_HPP +#define SCRIPT_SCANNER_HPP + +#include "../fileio_type.h" + +class ScriptScanner { +public: + ScriptScanner(); + ~ScriptScanner(); + + /** + * 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 for scripts. + * @param info_flie_name The name of the 'info.nut' file. + * @param search_dir The subdirecotry to search for scripts. + */ + void ScanScriptDir(const char *info_file_name, Subdirectory search_dir); + +private: + /** + * Scan a dir for scripts. + */ + void ScanDir(const char *dirname, const char *info_file_name); + +protected: + class Squirrel *engine; + char main_script[1024]; +}; + +#endif /* SCRIPT_SCANNER_HPP */ diff --git a/src/settings.cpp b/src/settings.cpp index 3f1396f5d..2711ea330 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -57,6 +57,7 @@ #include "station_func.h" #include "settings_func.h" #include "ini_type.h" +#include "ai/ai.hpp" #include "ai/ai_config.hpp" #include "newgrf.h" #include "engine_base.h" -- cgit v1.2.3-70-g09d2