00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "../../stdafx.h"
00013 #include "../../string_func.h"
00014 #include "../../script/squirrel.hpp"
00015 #include "../../rev.h"
00016
00017 #include "script_controller.hpp"
00018 #include "../script_fatalerror.hpp"
00019 #include "../script_info.hpp"
00020 #include "../script_instance.hpp"
00021 #include "../script_suspend.hpp"
00022 #include "script_log.hpp"
00023
00024 void ScriptController::SetCommandDelay(int ticks)
00025 {
00026 if (ticks <= 0) return;
00027 ScriptObject::SetDoCommandDelay(ticks);
00028 }
00029
00030 void ScriptController::Sleep(int ticks)
00031 {
00032 if (!ScriptObject::CanSuspend()) {
00033 throw Script_FatalError("You are not allowed to call Sleep in your constructor, Save(), Load(), and any valuator.");
00034 }
00035
00036 if (ticks <= 0) {
00037 ScriptLog::Warning("Sleep() value should be > 0. Assuming value 1.");
00038 ticks = 1;
00039 }
00040
00041 throw Script_Suspend(ticks, NULL);
00042 }
00043
00044 void ScriptController::Print(bool error_msg, const char *message)
00045 {
00046 ScriptLog::Log(error_msg ? ScriptLog::LOG_SQ_ERROR : ScriptLog::LOG_SQ_INFO, message);
00047 }
00048
00049 ScriptController::ScriptController() :
00050 ticks(0),
00051 loaded_library_count(0)
00052 {
00053 }
00054
00055 ScriptController::~ScriptController()
00056 {
00057 for (LoadedLibraryList::iterator iter = this->loaded_library.begin(); iter != this->loaded_library.end(); iter++) {
00058 free((*iter).second);
00059 free((*iter).first);
00060 }
00061
00062 this->loaded_library.clear();
00063 }
00064
00065 uint ScriptController::GetTick()
00066 {
00067 return ScriptObject::GetActiveInstance()->GetController()->ticks;
00068 }
00069
00070 int ScriptController::GetOpsTillSuspend()
00071 {
00072 return ScriptObject::GetActiveInstance()->GetOpsTillSuspend();
00073 }
00074
00075 int ScriptController::GetSetting(const char *name)
00076 {
00077 return ScriptObject::GetActiveInstance()->GetSetting(name);
00078 }
00079
00080 uint ScriptController::GetVersion()
00081 {
00082 return _openttd_newgrf_version;
00083 }
00084
00085 HSQOBJECT ScriptController::Import(const char *library, const char *class_name, int version)
00086 {
00087 ScriptController *controller = ScriptObject::GetActiveInstance()->GetController();
00088 Squirrel *engine = ScriptObject::GetActiveInstance()->engine;
00089 HSQUIRRELVM vm = engine->GetVM();
00090
00091
00092 char library_name[1024];
00093 snprintf(library_name, sizeof(library_name), "%s.%d", library, version);
00094 strtolower(library_name);
00095
00096 ScriptInfo *lib = ScriptObject::GetActiveInstance()->FindLibrary(library, version);
00097 if (lib == NULL) {
00098 char error[1024];
00099 snprintf(error, sizeof(error), "couldn't find library '%s' with version %d", library, version);
00100 throw sq_throwerror(vm, OTTD2SQ(error));
00101 }
00102
00103
00104 HSQOBJECT parent;
00105 sq_getstackobj(vm, 1, &parent);
00106
00107 char fake_class[1024];
00108
00109 LoadedLibraryList::iterator iter = controller->loaded_library.find(library_name);
00110 if (iter != controller->loaded_library.end()) {
00111 ttd_strlcpy(fake_class, (*iter).second, sizeof(fake_class));
00112 } else {
00113 int next_number = ++controller->loaded_library_count;
00114
00115
00116 snprintf(fake_class, sizeof(fake_class), "_internalNA%d", next_number);
00117
00118
00119 sq_pushroottable(vm);
00120 sq_pushstring(vm, OTTD2SQ(fake_class), -1);
00121 sq_newclass(vm, SQFalse);
00122
00123 if (!engine->LoadScript(vm, lib->GetMainScript(), false)) {
00124 char error[1024];
00125 snprintf(error, sizeof(error), "there was a compile error when importing '%s' version %d", library, version);
00126 throw sq_throwerror(vm, OTTD2SQ(error));
00127 }
00128
00129 sq_newslot(vm, -3, SQFalse);
00130 sq_pop(vm, 1);
00131
00132 controller->loaded_library[strdup(library_name)] = strdup(fake_class);
00133 }
00134
00135
00136 sq_pushroottable(vm);
00137 sq_pushstring(vm, OTTD2SQ(fake_class), -1);
00138 if (SQ_FAILED(sq_get(vm, -2))) {
00139 throw sq_throwerror(vm, _SC("internal error assigning library class"));
00140 }
00141 sq_pushstring(vm, OTTD2SQ(lib->GetInstanceName()), -1);
00142 if (SQ_FAILED(sq_get(vm, -2))) {
00143 char error[1024];
00144 snprintf(error, sizeof(error), "unable to find class '%s' in the library '%s' version %d", lib->GetInstanceName(), library, version);
00145 throw sq_throwerror(vm, OTTD2SQ(error));
00146 }
00147 HSQOBJECT obj;
00148 sq_getstackobj(vm, -1, &obj);
00149 sq_pop(vm, 3);
00150
00151 if (StrEmpty(class_name)) return obj;
00152
00153
00154 sq_pushobject(vm, parent);
00155 sq_pushstring(vm, OTTD2SQ(class_name), -1);
00156 sq_pushobject(vm, obj);
00157 sq_newclass(vm, SQTrue);
00158 sq_newslot(vm, -3, SQFalse);
00159 sq_pop(vm, 1);
00160
00161 return obj;
00162 }