# HG changeset patch # User truelight # Date 1173998923 0 # Node ID 346932a30fc9718134f91352baaa13da1a263670 # Parent 9e0a193b2bec56b5c510a521e05c3bbf5f7783b7 (svn r9235) [NoAI] -Codechange: renamed ai/squirrel.* to ai/ai_squirrel.* diff -r 9e0a193b2bec -r 346932a30fc9 config.lib --- a/config.lib Thu Mar 15 22:46:22 2007 +0000 +++ b/config.lib Thu Mar 15 22:48:43 2007 +0000 @@ -705,13 +705,13 @@ if [ "$os" = "CYGWIN" ] || [ "$os" = "MINGW" ]; then LDFLAGS="$LDFLAGS -Wl,--subsystem,windows" LIBS="$LIBS -lws2_32 -lwinmm -lgdi32 -ldxguid -lole32" - # GCC 4.0+ complains about that we break strict-aliasing. - # On most places we don't see how to fix it, and it doesn't - # break anything. So disable strict-aliasing to make the - # compiler all happy. - if [ $cc_version -ge 40 ]; then - CFLAGS="$CFLAGS -fno-strict-aliasing" - fi + fi + # GCC 4.0+ complains about that we break strict-aliasing. + # On most places we don't see how to fix it, and it doesn't + # break anything. So disable strict-aliasing to make the + # compiler all happy. + if [ $cc_version -ge 40 ]; then + CFLAGS="$CFLAGS -fno-strict-aliasing" fi if [ "$os" != "CYGWIN" ] && [ "$os" != "FREEBSD" ] && [ "$os" != "MINGW" ] && [ "$os" != "MORPHOS" ] && [ "$os" != "OSX" ] && [ "$os" != "WINCE" ] && [ "$os" != "PSP" ]; then diff -r 9e0a193b2bec -r 346932a30fc9 projects/openttd.vcproj --- a/projects/openttd.vcproj Thu Mar 15 22:46:22 2007 +0000 +++ b/projects/openttd.vcproj Thu Mar 15 22:48:43 2007 +0000 @@ -980,10 +980,10 @@ RelativePath=".\..\src\ai\ai.h"> + RelativePath=".\..\src\ai\ai_squirrel.cpp"> + RelativePath=".\..\src\ai\ai_squirrel.hpp"> - - + + - - - - + RelativePath=".\..\src\ai\api\ai_base.cpp"> - - + RelativePath=".\..\src\ai\api\ai_cargo.cpp"> + RelativePath=".\..\src\ai\api\ai_company.cpp"> + RelativePath=".\..\src\ai\api\ai_industry.cpp"> + RelativePath=".\..\src\ai\api\ai_map.cpp"> + + + + @@ -1571,40 +1571,36 @@ RelativePath=".\..\src\ai\api\ai_town.hpp" > - - + + - - - - - - + + + + diff -r 9e0a193b2bec -r 346932a30fc9 source.list --- a/source.list Thu Mar 15 22:46:22 2007 +0000 +++ b/source.list Thu Mar 15 22:48:43 2007 +0000 @@ -297,8 +297,8 @@ # AI Core ai/ai.cpp ai/ai.h -ai/squirrel.cpp -ai/squirrel.hpp +ai/ai_squirrel.cpp +ai/ai_squirrel.hpp # AI API ai/api/ai_base.hpp diff -r 9e0a193b2bec -r 346932a30fc9 src/ai/ai_squirrel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ai/ai_squirrel.cpp Thu Mar 15 22:48:43 2007 +0000 @@ -0,0 +1,216 @@ +/* $Id$ */ + +/** @file squirrel.cpp allows loading squirrel scripts to control an AI */ + +#include "../stdafx.h" +#include "../debug.h" +#include "../openttd.h" +#include "../string.h" +#include "../fios.h" +#include +#include + +#ifdef _UNICODE +/* Disable unicode for squirrel to allow compilation with MINGW + * and simplify coding for WIN32 (squirrel headers miss a lot of "string" functions) + */ +#undef _UNICODE +#endif +#include +#include "../squirrel.hpp" +#include "../squirrel_helper.hpp" +#include "../squirrel_class.hpp" +#include "api/ai_factory.hpp" +#include "api/ai_controller.hpp" +#include "ai_squirrel.hpp" + +/* Convert all AI related classes to Squirrel data */ +#define DEFINE_SQUIRREL_CLASS +#include "api/ai_base.hpp" +#include "api/ai_cargo.hpp" +#include "api/ai_controller.hpp" +#include "api/ai_company.hpp" +#include "api/ai_industry.hpp" +#include "api/ai_map.hpp" +#include "api/ai_town.hpp" + +static FSquirrel iFSquirrel; ///< Tell the AI-core that we have an AI with which we like to play. + +/** + * Our tiny wrapper between C++ and Squirrel. + */ +class AIFactorySquirrel: public AIFactoryBase { +public: + Squirrel *engine; + HSQOBJECT SQ_instance; + char *script_name; + + ~AIFactorySquirrel(); + + /* virtual */ const char *GetAuthor() { return this->engine->CallStringMethod (this->SQ_instance, "GetAuthor"); } + /* virtual */ const char *GetName() { return this->engine->CallStringMethod (this->SQ_instance, "GetName"); } + /* virtual */ const char *GetDescription() { return this->engine->CallStringMethod (this->SQ_instance, "GetDescription"); } + /* virtual */ int GetVersion() { return this->engine->CallIntegerMethod(this->SQ_instance, "GetVersion"); } + /* virtual */ const char *GetDate() { return this->engine->CallStringMethod (this->SQ_instance, "GetDate"); } + /* virtual */ AIController *CreateInstance(); + + /** + * Register Squirrel script to the Factory. + */ + void RegisterSquirrel() { this->RegisterFactory(this->GetName()); } + + /** + * Check if a method exists in the script. + */ + void CheckMethods(AIFactorySquirrel *fbase, SQInteger *res, const char *name); +}; + +AIFactorySquirrel::~AIFactorySquirrel() +{ + free(this->script_name); +} + +void AIFactorySquirrel::CheckMethods(AIFactorySquirrel *fbase, SQInteger *res, const char *name) +{ + if (!fbase->engine->MethodExists(fbase->SQ_instance, name)) { + char error[1024]; + snprintf(error, sizeof(error), "Missing method '%s' for FactoryClass", name); + fbase->engine->ThrowError(error); + *res = SQ_ERROR; + } +} + +SQInteger FSquirrel::FactoryConstructor(HSQUIRRELVM vm) +{ + AIFactorySquirrel *fbase = new AIFactorySquirrel(); + SQInteger res = 0; + + Squirrel::GetInstance(vm, &fbase->SQ_instance); + fbase->engine = ((FSquirrel *)Squirrel::GetGlobalPointer(vm))->engine; + + /* Check if all needed fields are there */ + fbase->CheckMethods(fbase, &res, "GetAuthor"); + fbase->CheckMethods(fbase, &res, "GetName"); + fbase->CheckMethods(fbase, &res, "GetDescription"); + fbase->CheckMethods(fbase, &res, "GetVersion"); + fbase->CheckMethods(fbase, &res, "GetDate"); + fbase->CheckMethods(fbase, &res, "CreateInstance"); + + /* Abort if one method was missing */ + if (res != 0) return res; + + fbase->RegisterSquirrel(); + fbase->script_name = strdup(((FSquirrel *)Squirrel::GetGlobalPointer(vm))->current_script); + + return 0; +} + +extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb); +extern bool FiosIsHiddenFile(const struct dirent *ent); + + +void FSquirrel::ScanDir(const char *dirname) +{ + struct stat sb; + struct dirent *dirent; + DIR *dir; + char d_name[256]; + char script_name[256]; + 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)); + + /* Found file must be directory, but not '.' or '..' */ + if (FiosIsValidFile("ai", dirent, &sb) && (sb.st_mode & S_IFDIR) && + (!FiosIsHiddenFile(dirent) || strncasecmp(d_name, PERSONAL_DIR, strlen(d_name)) == 0) && + strcmp(d_name, ".") != 0 && strcmp(d_name, "..") != 0) { + /* Create the full-length script-name */ + strcpy(script_name, dirname); + strcat(script_name, PATHSEP); + strcat(script_name, d_name); + strcat(script_name, PATHSEP); + strcat(script_name, "main.nut"); + /* If it exists, load it up */ + if (FileExists(script_name)) { + DEBUG(ai, 6, "[squirrel] Loading script '%s' for AI handling", script_name); + this->current_script = script_name; + this->engine->LoadScript(this->current_script); + } + } + } + closedir(dir); +} + +void FSquirrel::Initializer() +{ + this->engine = new Squirrel(); + + /* Create the AIFactory class, and bind the constructor */ + this->engine->AddClassBegin("AIFactory"); + this->engine->AddMethod("constructor", &FSquirrel::FactoryConstructor, 1, "x"); + this->engine->AddClassEnd(); + + /* Set a dummy AIController, so script can load */ + this->engine->AddClassBegin("AIController"); + this->engine->AddClassEnd(); + /* Mark this class as global pointer */ + this->engine->SetGlobalPointer(this); + + /* Scan the AI dir for scripts */ + this->ScanDir("ai"); +} + +FSquirrel::~FSquirrel() +{ + delete this->engine; +} + +AIController *AIFactorySquirrel::CreateInstance() +{ + const char *class_name = this->engine->CallStringMethod(this->SQ_instance, "CreateInstance"); + AIControllerSquirrel *controller = new AIControllerSquirrel(this->script_name, class_name); + + return controller; +} + +void AIControllerSquirrel::RegisterClasses() +{ + /* Ignore AIFactory if we are really starting an AI */ + this->engine->AddClassBegin("AIFactory"); + this->engine->AddClassEnd(); + + /* Register all classes */ + SQAIBaseRegister(this->engine); + SQAICargoRegister(this->engine); + SQAICompanyRegister(this->engine); + SQAIControllerRegister(this->engine); + SQAIIndustryRegister(this->engine); + SQAIMapRegister(this->engine); + SQAITownRegister(this->engine); + + this->engine->SetGlobalPointer(this->engine); +} + +AIControllerSquirrel::AIControllerSquirrel(const char *script, const char *class_name) +{ + this->engine = new Squirrel(); + this->RegisterClasses(); + this->engine->LoadScript(script); + /* Create the main-class */ + this->engine->CreateClassInstance(class_name, this, &this->SQ_instance); + this->engine->CallMethod(this->SQ_instance, "constructor"); +} + +AIControllerSquirrel::~AIControllerSquirrel() +{ + delete this->engine; +} + +/* virtual */ void AIControllerSquirrel::GameLoop() +{ + this->engine->CallMethod(this->SQ_instance, "GameLoop"); +} diff -r 9e0a193b2bec -r 346932a30fc9 src/ai/ai_squirrel.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ai/ai_squirrel.hpp Thu Mar 15 22:48:43 2007 +0000 @@ -0,0 +1,56 @@ +/* $Id$ */ + +/** @file squirrel.hpp declarations of the class for squirrel loader */ + +#ifndef AI_SQUIRREL_HPP +#define AI_SQUIRREL_HPP + +class AIControllerSquirrel: public AIController { +private: + Squirrel *engine; ///< The Squirrel engine + HSQOBJECT SQ_instance; ///< The internal instance of squirrel + + /** + * Registers all our classes, so it can be used from Squirrel. + */ + void RegisterClasses(); + +public: + AIControllerSquirrel(const char *script_dir, const char *class_name); + ~AIControllerSquirrel(); + + /* virtual */ void GameLoop(); + + uint GetTick() { return AIController::GetTick(); } +}; + +class FSquirrel: public AIFactory { +private: + Squirrel *engine; ///< The Squirrel engine + const char *current_script; ///< Temporary variable to know which script defines which class + + /** + * The constructor for when a script makes an instance of the Factory class. + */ + static SQInteger FactoryConstructor(HSQUIRRELVM vm); + + /** + * Scans a dir to see if there are dirs in it which have a file called 'main.nut'. + * If found it loads the script. + */ + void ScanDir(const char *dirname); + +public: + ~FSquirrel(); + + /* virtual */ const char *GetAuthor() { return "OpenTTD Dev Team"; } + /* virtual */ const char *GetName() { return "Squirrel"; } + /* virtual */ const char *GetDescription() { return "Squirrel Module for loading scripts"; } + /* virtual */ int GetVersion() { return 0; } + /* virtual */ const char *GetDate() { return ""; } + /* virtual */ AIController *CreateInstance() { return NULL; } + /* virtual */ bool AllowStartup() { return false; } + /* virtual */ void Initializer(); +}; + +#endif /* AI_SQUIRREL_HPP */ diff -r 9e0a193b2bec -r 346932a30fc9 src/ai/squirrel.cpp --- a/src/ai/squirrel.cpp Thu Mar 15 22:46:22 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,216 +0,0 @@ -/* $Id$ */ - -/** @file squirrel.cpp allows loading squirrel scripts to control an AI */ - -#include "../stdafx.h" -#include "../debug.h" -#include "../openttd.h" -#include "../string.h" -#include "../fios.h" -#include -#include - -#ifdef _UNICODE -/* Disable unicode for squirrel to allow compilation with MINGW - * and simplify coding for WIN32 (squirrel headers miss a lot of "string" functions) - */ -#undef _UNICODE -#endif -#include -#include "../squirrel.hpp" -#include "../squirrel_helper.hpp" -#include "../squirrel_class.hpp" -#include "api/ai_factory.hpp" -#include "api/ai_controller.hpp" -#include "squirrel.hpp" - -/* Convert all AI related classes to Squirrel data */ -#define DEFINE_SQUIRREL_CLASS -#include "api/ai_base.hpp" -#include "api/ai_cargo.hpp" -#include "api/ai_controller.hpp" -#include "api/ai_company.hpp" -#include "api/ai_industry.hpp" -#include "api/ai_map.hpp" -#include "api/ai_town.hpp" - -static FSquirrel iFSquirrel; ///< Tell the AI-core that we have an AI with which we like to play. - -/** - * Our tiny wrapper between C++ and Squirrel. - */ -class AIFactorySquirrel: public AIFactoryBase { -public: - Squirrel *engine; - HSQOBJECT SQ_instance; - char *script_name; - - ~AIFactorySquirrel(); - - /* virtual */ const char *GetAuthor() { return this->engine->CallStringMethod (this->SQ_instance, "GetAuthor"); } - /* virtual */ const char *GetName() { return this->engine->CallStringMethod (this->SQ_instance, "GetName"); } - /* virtual */ const char *GetDescription() { return this->engine->CallStringMethod (this->SQ_instance, "GetDescription"); } - /* virtual */ int GetVersion() { return this->engine->CallIntegerMethod(this->SQ_instance, "GetVersion"); } - /* virtual */ const char *GetDate() { return this->engine->CallStringMethod (this->SQ_instance, "GetDate"); } - /* virtual */ AIController *CreateInstance(); - - /** - * Register Squirrel script to the Factory. - */ - void RegisterSquirrel() { this->RegisterFactory(this->GetName()); } - - /** - * Check if a method exists in the script. - */ - void CheckMethods(AIFactorySquirrel *fbase, SQInteger *res, const char *name); -}; - -AIFactorySquirrel::~AIFactorySquirrel() -{ - free(this->script_name); -} - -void AIFactorySquirrel::CheckMethods(AIFactorySquirrel *fbase, SQInteger *res, const char *name) -{ - if (!fbase->engine->MethodExists(fbase->SQ_instance, name)) { - char error[1024]; - snprintf(error, sizeof(error), "Missing method '%s' for FactoryClass", name); - fbase->engine->ThrowError(error); - *res = SQ_ERROR; - } -} - -SQInteger FSquirrel::FactoryConstructor(HSQUIRRELVM vm) -{ - AIFactorySquirrel *fbase = new AIFactorySquirrel(); - SQInteger res = 0; - - Squirrel::GetInstance(vm, &fbase->SQ_instance); - fbase->engine = ((FSquirrel *)Squirrel::GetGlobalPointer(vm))->engine; - - /* Check if all needed fields are there */ - fbase->CheckMethods(fbase, &res, "GetAuthor"); - fbase->CheckMethods(fbase, &res, "GetName"); - fbase->CheckMethods(fbase, &res, "GetDescription"); - fbase->CheckMethods(fbase, &res, "GetVersion"); - fbase->CheckMethods(fbase, &res, "GetDate"); - fbase->CheckMethods(fbase, &res, "CreateInstance"); - - /* Abort if one method was missing */ - if (res != 0) return res; - - fbase->RegisterSquirrel(); - fbase->script_name = strdup(((FSquirrel *)Squirrel::GetGlobalPointer(vm))->current_script); - - return 0; -} - -extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb); -extern bool FiosIsHiddenFile(const struct dirent *ent); - - -void FSquirrel::ScanDir(const char *dirname) -{ - struct stat sb; - struct dirent *dirent; - DIR *dir; - char d_name[256]; - char script_name[256]; - 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)); - - /* Found file must be directory, but not '.' or '..' */ - if (FiosIsValidFile("ai", dirent, &sb) && (sb.st_mode & S_IFDIR) && - (!FiosIsHiddenFile(dirent) || strncasecmp(d_name, PERSONAL_DIR, strlen(d_name)) == 0) && - strcmp(d_name, ".") != 0 && strcmp(d_name, "..") != 0) { - /* Create the full-length script-name */ - strcpy(script_name, dirname); - strcat(script_name, PATHSEP); - strcat(script_name, d_name); - strcat(script_name, PATHSEP); - strcat(script_name, "main.nut"); - /* If it exists, load it up */ - if (FileExists(script_name)) { - DEBUG(ai, 6, "[squirrel] Loading script '%s' for AI handling", script_name); - this->current_script = script_name; - this->engine->LoadScript(this->current_script); - } - } - } - closedir(dir); -} - -void FSquirrel::Initializer() -{ - this->engine = new Squirrel(); - - /* Create the AIFactory class, and bind the constructor */ - this->engine->AddClassBegin("AIFactory"); - this->engine->AddMethod("constructor", &FSquirrel::FactoryConstructor, 1, "x"); - this->engine->AddClassEnd(); - - /* Set a dummy AIController, so script can load */ - this->engine->AddClassBegin("AIController"); - this->engine->AddClassEnd(); - /* Mark this class as global pointer */ - this->engine->SetGlobalPointer(this); - - /* Scan the AI dir for scripts */ - this->ScanDir("ai"); -} - -FSquirrel::~FSquirrel() -{ - delete this->engine; -} - -AIController *AIFactorySquirrel::CreateInstance() -{ - const char *class_name = this->engine->CallStringMethod(this->SQ_instance, "CreateInstance"); - AIControllerSquirrel *controller = new AIControllerSquirrel(this->script_name, class_name); - - return controller; -} - -void AIControllerSquirrel::RegisterClasses() -{ - /* Ignore AIFactory if we are really starting an AI */ - this->engine->AddClassBegin("AIFactory"); - this->engine->AddClassEnd(); - - /* Register all classes */ - SQAIBaseRegister(this->engine); - SQAICargoRegister(this->engine); - SQAICompanyRegister(this->engine); - SQAIControllerRegister(this->engine); - SQAIIndustryRegister(this->engine); - SQAIMapRegister(this->engine); - SQAITownRegister(this->engine); - - this->engine->SetGlobalPointer(this->engine); -} - -AIControllerSquirrel::AIControllerSquirrel(const char *script, const char *class_name) -{ - this->engine = new Squirrel(); - this->RegisterClasses(); - this->engine->LoadScript(script); - /* Create the main-class */ - this->engine->CreateClassInstance(class_name, this, &this->SQ_instance); - this->engine->CallMethod(this->SQ_instance, "constructor"); -} - -AIControllerSquirrel::~AIControllerSquirrel() -{ - delete this->engine; -} - -/* virtual */ void AIControllerSquirrel::GameLoop() -{ - this->engine->CallMethod(this->SQ_instance, "GameLoop"); -} diff -r 9e0a193b2bec -r 346932a30fc9 src/ai/squirrel.hpp --- a/src/ai/squirrel.hpp Thu Mar 15 22:46:22 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* $Id$ */ - -/** @file squirrel.hpp declarations of the class for squirrel loader */ - -#ifndef AI_SQUIRREL_HPP -#define AI_SQUIRREL_HPP - -class AIControllerSquirrel: public AIController { -private: - Squirrel *engine; ///< The Squirrel engine - HSQOBJECT SQ_instance; ///< The internal instance of squirrel - - /** - * Registers all our classes, so it can be used from Squirrel. - */ - void RegisterClasses(); - -public: - AIControllerSquirrel(const char *script_dir, const char *class_name); - ~AIControllerSquirrel(); - - /* virtual */ void GameLoop(); - - uint GetTick() { return AIController::GetTick(); } -}; - -class FSquirrel: public AIFactory { -private: - Squirrel *engine; ///< The Squirrel engine - const char *current_script; ///< Temporary variable to know which script defines which class - - /** - * The constructor for when a script makes an instance of the Factory class. - */ - static SQInteger FactoryConstructor(HSQUIRRELVM vm); - - /** - * Scans a dir to see if there are dirs in it which have a file called 'main.nut'. - * If found it loads the script. - */ - void ScanDir(const char *dirname); - -public: - ~FSquirrel(); - - /* virtual */ const char *GetAuthor() { return "OpenTTD Dev Team"; } - /* virtual */ const char *GetName() { return "Squirrel"; } - /* virtual */ const char *GetDescription() { return "Squirrel Module for loading scripts"; } - /* virtual */ int GetVersion() { return 0; } - /* virtual */ const char *GetDate() { return ""; } - /* virtual */ AIController *CreateInstance() { return NULL; } - /* virtual */ bool AllowStartup() { return false; } - /* virtual */ void Initializer(); -}; - -#endif /* AI_SQUIRREL_HPP */