summaryrefslogtreecommitdiff
path: root/src/script
diff options
context:
space:
mode:
authortruebrain <truebrain@openttd.org>2011-12-19 21:00:32 +0000
committertruebrain <truebrain@openttd.org>2011-12-19 21:00:32 +0000
commit3a535690d4e9aaa896a062e7b5b5454b1b07ac47 (patch)
tree600859d25db8391542b9cc0da9e063c7bdc6f4fc /src/script
parent77b7366c2947a3f2545d5542021be1cc203a74e8 (diff)
downloadopenttd-3a535690d4e9aaa896a062e7b5b5454b1b07ac47.tar.xz
(svn r23623) -Add: allow bi-directional communication with the AdminPort and GameScript
Diffstat (limited to 'src/script')
-rw-r--r--src/script/api/ai/ai_event.hpp.sq1
-rw-r--r--src/script/api/game/game_admin.hpp.sq27
-rw-r--r--src/script/api/game/game_event.hpp.sq1
-rw-r--r--src/script/api/game/game_event_types.hpp.sq15
-rw-r--r--src/script/api/script_admin.cpp151
-rw-r--r--src/script/api/script_admin.hpp53
-rw-r--r--src/script/api/script_event.hpp1
-rw-r--r--src/script/api/script_event_types.cpp183
-rw-r--r--src/script/api/script_event_types.hpp56
-rw-r--r--src/script/api/squirrel_export.awk6
-rw-r--r--src/script/api/template/template_admin.hpp.sq21
-rw-r--r--src/script/api/template/template_event_types.hpp.sq9
-rw-r--r--src/script/script_instance.cpp10
-rw-r--r--src/script/script_instance.hpp2
-rw-r--r--src/script/squirrel_class.hpp10
-rw-r--r--src/script/squirrel_helper.hpp22
16 files changed, 561 insertions, 7 deletions
diff --git a/src/script/api/ai/ai_event.hpp.sq b/src/script/api/ai/ai_event.hpp.sq
index abcdc62d2..df515755d 100644
--- a/src/script/api/ai/ai_event.hpp.sq
+++ b/src/script/api/ai/ai_event.hpp.sq
@@ -45,6 +45,7 @@ void SQAIEvent_Register(Squirrel *engine)
SQAIEvent.DefSQConst(engine, ScriptEvent::ET_DISASTER_ZEPPELINER_CLEARED, "ET_DISASTER_ZEPPELINER_CLEARED");
SQAIEvent.DefSQConst(engine, ScriptEvent::ET_TOWN_FOUNDED, "ET_TOWN_FOUNDED");
SQAIEvent.DefSQConst(engine, ScriptEvent::ET_AIRCRAFT_DEST_TOO_FAR, "ET_AIRCRAFT_DEST_TOO_FAR");
+ SQAIEvent.DefSQConst(engine, ScriptEvent::ET_ADMIN_PORT, "ET_ADMIN_PORT");
SQAIEvent.DefSQMethod(engine, &ScriptEvent::GetEventType, "GetEventType", 1, "x");
diff --git a/src/script/api/game/game_admin.hpp.sq b/src/script/api/game/game_admin.hpp.sq
new file mode 100644
index 000000000..f8b994e80
--- /dev/null
+++ b/src/script/api/game/game_admin.hpp.sq
@@ -0,0 +1,27 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
+
+#include "../script_admin.hpp"
+#include "../template/template_admin.hpp.sq"
+
+
+template <> const char *GetClassName<ScriptAdmin, ST_GS>() { return "GSAdmin"; }
+
+void SQGSAdmin_Register(Squirrel *engine)
+{
+ DefSQClass<ScriptAdmin, ST_GS> SQGSAdmin("GSAdmin");
+ SQGSAdmin.PreRegister(engine);
+ SQGSAdmin.AddConstructor<void (ScriptAdmin::*)(), 1>(engine, "x");
+
+ SQGSAdmin.DefSQAdvancedStaticMethod(engine, &ScriptAdmin::Send, "Send");
+
+ SQGSAdmin.PostRegister(engine);
+}
diff --git a/src/script/api/game/game_event.hpp.sq b/src/script/api/game/game_event.hpp.sq
index 5f87970f6..5bc8e9896 100644
--- a/src/script/api/game/game_event.hpp.sq
+++ b/src/script/api/game/game_event.hpp.sq
@@ -45,6 +45,7 @@ void SQGSEvent_Register(Squirrel *engine)
SQGSEvent.DefSQConst(engine, ScriptEvent::ET_DISASTER_ZEPPELINER_CLEARED, "ET_DISASTER_ZEPPELINER_CLEARED");
SQGSEvent.DefSQConst(engine, ScriptEvent::ET_TOWN_FOUNDED, "ET_TOWN_FOUNDED");
SQGSEvent.DefSQConst(engine, ScriptEvent::ET_AIRCRAFT_DEST_TOO_FAR, "ET_AIRCRAFT_DEST_TOO_FAR");
+ SQGSEvent.DefSQConst(engine, ScriptEvent::ET_ADMIN_PORT, "ET_ADMIN_PORT");
SQGSEvent.DefSQMethod(engine, &ScriptEvent::GetEventType, "GetEventType", 1, "x");
diff --git a/src/script/api/game/game_event_types.hpp.sq b/src/script/api/game/game_event_types.hpp.sq
index a6e806ffd..6358dbeae 100644
--- a/src/script/api/game/game_event_types.hpp.sq
+++ b/src/script/api/game/game_event_types.hpp.sq
@@ -217,3 +217,18 @@ void SQGSEventTownFounded_Register(Squirrel *engine)
SQGSEventTownFounded.PostRegister(engine);
}
+
+
+template <> const char *GetClassName<ScriptEventAdminPort, ST_GS>() { return "GSEventAdminPort"; }
+
+void SQGSEventAdminPort_Register(Squirrel *engine)
+{
+ DefSQClass<ScriptEventAdminPort, ST_GS> SQGSEventAdminPort("GSEventAdminPort");
+ SQGSEventAdminPort.PreRegister(engine, "GSEvent");
+
+ SQGSEventAdminPort.DefSQStaticMethod(engine, &ScriptEventAdminPort::Convert, "Convert", 2, ".x");
+
+ SQGSEventAdminPort.DefSQAdvancedMethod(engine, &ScriptEventAdminPort::GetObject, "GetObject");
+
+ SQGSEventAdminPort.PostRegister(engine);
+}
diff --git a/src/script/api/script_admin.cpp b/src/script/api/script_admin.cpp
new file mode 100644
index 000000000..c3845b897
--- /dev/null
+++ b/src/script/api/script_admin.cpp
@@ -0,0 +1,151 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file script_admin.cpp Implementation of ScriptAdmin. */
+
+#include "../../stdafx.h"
+#include "script_admin.hpp"
+#include "script_log.hpp"
+#include "../../network/network_admin.h"
+#include "../script_instance.hpp"
+#include "../../game/game.hpp"
+
+/* static */ bool ScriptAdmin::MakeJSON(HSQUIRRELVM vm, SQInteger index, int max_depth, std::string &data)
+{
+ if (max_depth == 0) {
+ ScriptLog::Error("Send parameters can only be nested to 25 deep. No data sent."); // SQUIRREL_MAX_DEPTH = 25
+ return false;
+ }
+
+ switch (sq_gettype(vm, index)) {
+ case OT_INTEGER: {
+ SQInteger res;
+ sq_getinteger(vm, index, &res);
+
+ char buf[10];
+ snprintf(buf, sizeof(buf), "%d", (int32)res);
+ data = buf;
+ return true;
+ }
+
+ case OT_STRING: {
+ const SQChar *res;
+ sq_getstring(vm, index, &res);
+
+ /* @bug if a string longer than 512 characters is given to SQ2OTTD, the
+ * internal buffer overflows. */
+ const char *buf = SQ2OTTD(res);
+ size_t len = strlen(buf) + 1;
+ if (len >= 255) {
+ ScriptLog::Error("Maximum string length is 254 chars. No data sent.");
+ return false;
+ }
+
+ data = std::string("\"") + buf + "\"";
+ return true;
+ }
+
+ case OT_ARRAY: {
+ data = "[ ";
+
+ bool first = true;
+ sq_pushnull(vm);
+ while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
+ if (!first) data += ", ";
+ if (first) first = false;
+
+ std::string tmp;
+
+ bool res = MakeJSON(vm, -1, max_depth - 1, tmp);
+ sq_pop(vm, 2);
+ if (!res) {
+ sq_pop(vm, 1);
+ return false;
+ }
+ data += tmp;
+ }
+ sq_pop(vm, 1);
+ data += " ]";
+ return true;
+ }
+
+ case OT_TABLE: {
+ data = "{ ";
+
+ bool first = true;
+ sq_pushnull(vm);
+ while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
+ if (!first) data += ", ";
+ if (first) first = false;
+
+ std::string key;
+ std::string value;
+
+ /* Store the key + value */
+ bool res = MakeJSON(vm, -2, max_depth - 1, key) && MakeJSON(vm, -1, max_depth - 1, value);
+ sq_pop(vm, 2);
+ if (!res) {
+ sq_pop(vm, 1);
+ return false;
+ }
+ data += key + ": " + value;
+ }
+ sq_pop(vm, 1);
+ data += " }";
+ return true;
+ }
+
+ case OT_BOOL: {
+ SQBool res;
+ sq_getbool(vm, index, &res);
+
+ if (res) {
+ data = "true";
+ return true;
+ }
+
+ data = "false";
+ return true;
+ }
+
+ case OT_NULL: {
+ data = "null";
+ return true;
+ }
+
+ default:
+ ScriptLog::Error("You tried to send an unsupported type. No data sent.");
+ return false;
+ }
+}
+
+/* static */ SQInteger ScriptAdmin::Send(HSQUIRRELVM vm)
+{
+ if (sq_gettop(vm) - 1 != 1) return sq_throwerror(vm, _SC("wrong number of parameters"));
+
+ if (sq_gettype(vm, 2) != OT_TABLE) {
+ return sq_throwerror(vm, _SC("ScriptAdmin::Send requires a table as first parameter. No data sent."));
+ }
+
+ std::string json;
+ ScriptAdmin::MakeJSON(vm, -1, SQUIRREL_MAX_DEPTH, json);
+
+#ifdef ENABLE_NETWORK
+ if (json.length() > NETWORK_GAMESCRIPT_JSON_LENGTH) {
+ ScriptLog::Error("You are trying to send a table that is too large to the AdminPort. No data sent.");
+ sq_pushinteger(vm, 0);
+ return 1;
+ }
+
+ NetworkAdminGameScript(json.c_str());
+#endif /* ENABLE_NETWORK */
+
+ sq_pushinteger(vm, 1);
+ return 1;
+}
diff --git a/src/script/api/script_admin.hpp b/src/script/api/script_admin.hpp
new file mode 100644
index 000000000..9733e5b9e
--- /dev/null
+++ b/src/script/api/script_admin.hpp
@@ -0,0 +1,53 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file script_admin.hpp Everything to communicate with the AdminPort. */
+
+#ifndef SCRIPT_ADMIN_HPP
+#define SCRIPT_ADMIN_HPP
+
+#include <string>
+#include "script_object.hpp"
+
+/**
+ * Class that handles communication with the AdminPort.
+ * @api game
+ */
+class ScriptAdmin : public ScriptObject {
+public:
+#ifndef DOXYGEN_API
+ /**
+ * Internal representation of the Send function.
+ */
+ static SQInteger Send(HSQUIRRELVM vm);
+#else
+ /**
+ * Send information to the AdminPort. The information can be anything
+ * as long as it isn't a class or instance thereof.
+ * @param table The information to send, in a table. For example: { param = "param" }.
+ * @return True if and only if the data was successfully converted to JSON
+ * and send to the AdminPort.
+ * @note If the resulting JSON of your table is larger than 1450 bytes,
+ * nothing will be sent (and false will be returned).
+ */
+ static bool Send(table);
+#endif /* DOXYGEN_API */
+
+private:
+ /**
+ * Convert a Squirrel structure into a JSON string.
+ * @param vm The VM to operate on.
+ * @param index The index we are currently working for.
+ * @param max_depth The maximal depth to follow the squirrel struct.
+ * @param data The resulting json string.
+ */
+ static bool MakeJSON(HSQUIRRELVM vm, SQInteger index, int max_depth, std::string &data);
+};
+
+#endif /* SCRIPT_ADMIN_HPP */
diff --git a/src/script/api/script_event.hpp b/src/script/api/script_event.hpp
index ba8131eda..323ac189e 100644
--- a/src/script/api/script_event.hpp
+++ b/src/script/api/script_event.hpp
@@ -50,6 +50,7 @@ public:
ET_DISASTER_ZEPPELINER_CLEARED,
ET_TOWN_FOUNDED,
ET_AIRCRAFT_DEST_TOO_FAR,
+ ET_ADMIN_PORT,
};
/**
diff --git a/src/script/api/script_event_types.cpp b/src/script/api/script_event_types.cpp
index 387e678bd..8b3ef8c5f 100644
--- a/src/script/api/script_event_types.cpp
+++ b/src/script/api/script_event_types.cpp
@@ -12,6 +12,7 @@
#include "../../stdafx.h"
#include "script_event_types.hpp"
#include "script_vehicle.hpp"
+#include "script_log.hpp"
#include "../../command_type.h"
#include "../../strings_func.h"
#include "../../settings_type.h"
@@ -119,3 +120,185 @@ bool ScriptEventCompanyAskMerger::AcceptMerger()
{
return ScriptObject::DoCommand(0, this->owner, 0, CMD_BUY_COMPANY);
}
+
+#define SKIP_EMPTY(p) while (*(p) == ' ' || *(p) == '\n' || *(p) == '\r') (p)++;
+#define RETURN_ERROR(stack) { ScriptLog::Error("Received invalid JSON data from AdminPort."); if (stack != 0) sq_pop(vm, stack); return NULL; }
+
+SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm)
+{
+ char *p = this->json;
+
+ if (this->ReadTable(vm, p) == NULL) {
+ sq_pushnull(vm);
+ return 1;
+ }
+
+ return 1;
+}
+
+char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, char *p)
+{
+ char *value = p;
+
+ bool escape = false;
+ for (;;) {
+ if (*p == '\\') {
+ escape = true;
+ p++;
+ continue;
+ }
+ if (*p == '"' && escape) {
+ escape = false;
+ p++;
+ continue;
+ }
+ escape = false;
+
+ if (*p == '"') break;
+ if (*p == '\0') RETURN_ERROR(0);
+
+ p++;
+ }
+
+ *p = '\0';
+ sq_pushstring(vm, OTTD2SQ(value), -1);
+ *p++ = '"';
+
+ return p;
+}
+
+char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, char *p)
+{
+ sq_newtable(vm);
+
+ SKIP_EMPTY(p);
+ if (*p++ != '{') RETURN_ERROR(1);
+
+ for (;;) {
+ SKIP_EMPTY(p);
+ if (*p++ != '"') RETURN_ERROR(1);
+
+ p = ReadString(vm, p);
+ if (p == NULL) {
+ sq_pop(vm, 1);
+ return NULL;
+ }
+
+ SKIP_EMPTY(p);
+ if (*p++ != ':') RETURN_ERROR(2);
+
+ p = this->ReadValue(vm, p);
+ if (p == NULL) {
+ sq_pop(vm, 2);
+ return NULL;
+ }
+
+ sq_rawset(vm, -3);
+ /* The key (-2) and value (-1) are popped from the stack by squirrel. */
+
+ SKIP_EMPTY(p);
+ if (*p == ',') {
+ p++;
+ continue;
+ }
+ break;
+ }
+
+ SKIP_EMPTY(p);
+ if (*p++ != '}') RETURN_ERROR(1);
+
+ return p;
+}
+
+char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p)
+{
+ SKIP_EMPTY(p);
+
+ if (strncmp(p, "false", 5) == 0) {
+ sq_pushinteger(vm, 0);
+ return p + 5;
+ }
+ if (strncmp(p, "true", 4) == 0) {
+ sq_pushinteger(vm, 1);
+ return p + 4;
+ }
+ if (strncmp(p, "null", 4) == 0) {
+ sq_pushnull(vm);
+ return p + 4;
+ }
+
+ switch (*p) {
+ case '"': {
+ /* String */
+ p = ReadString(vm, ++p);
+ if (p == NULL) return NULL;
+
+ break;
+ }
+
+ case '{': {
+ /* Table */
+ p = this->ReadTable(vm, p);
+ if (p == NULL) return NULL;
+
+ break;
+ }
+
+ case '[': {
+ /* Array */
+ sq_newarray(vm, 0);
+
+ while (*p++ != ']') {
+ p = this->ReadValue(vm, p);
+ if (p == NULL) {
+ sq_pop(vm, 1);
+ return NULL;
+ }
+ sq_arrayappend(vm, -2);
+
+ SKIP_EMPTY(p);
+ if (*p == ',') continue;
+ if (*p == ']') break;
+ RETURN_ERROR(1);
+ }
+
+ p++;
+
+ break;
+ }
+
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9': case '0':
+ case '-': {
+ /* Integer */
+
+ const char *value = p++;
+ for (;;) {
+ switch (*p++) {
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9': case '0':
+ continue;
+
+ default:
+ break;
+ }
+
+ p--;
+ break;
+ }
+
+ int res = atoi(value);
+ sq_pushinteger(vm, (SQInteger)res);
+
+ break;
+ }
+
+ default:
+ RETURN_ERROR(0);
+ }
+
+ return p;
+}
+
+#undef SKIP_EMPTY
+#undef RETURN_ERROR
diff --git a/src/script/api/script_event_types.hpp b/src/script/api/script_event_types.hpp
index cffa4a797..d6552aad1 100644
--- a/src/script/api/script_event_types.hpp
+++ b/src/script/api/script_event_types.hpp
@@ -829,4 +829,60 @@ private:
VehicleID vehicle_id; ///< The vehicle aircraft whose destination is too far away.
};
+/**
+ * Event Admin Port, indicating the admin port is sending you information.
+ * @api game
+ */
+class ScriptEventAdminPort : public ScriptEvent {
+public:
+ /**
+ * @param json The JSON string which got sent.
+ */
+ ScriptEventAdminPort(const char *json) :
+ ScriptEvent(ET_ADMIN_PORT),
+ json(strdup(json))
+ {}
+
+ ~ScriptEventAdminPort()
+ {
+ free(this->json);
+ }
+
+ /**
+ * Convert an ScriptEvent to the real instance.
+ * @param instance The instance to convert.
+ * @return The converted instance.
+ */
+ static ScriptEventAdminPort *Convert(ScriptEvent *instance) { return (ScriptEventAdminPort *)instance; }
+
+ /**
+ * Get the information that was sent to you back as Squirrel object.
+ */
+ SQInteger GetObject(HSQUIRRELVM vm);
+
+private:
+ char *json; ///< The JSON string.
+
+ /**
+ * Read a table from a JSON string.
+ * @param vm The VM used.
+ * @param p The (part of the) JSON string reading.
+ */
+ char *ReadTable(HSQUIRRELVM vm, char *p);
+
+ /**
+ * Read a value from a JSON string.
+ * @param vm The VM used.
+ * @param p The (part of the) JSON string reading.
+ */
+ char *ReadValue(HSQUIRRELVM vm, char *p);
+
+ /**
+ * Read a string from a JSON string.
+ * @param vm The VM used.
+ * @param p The (part of the) JSON string reading.
+ */
+ char *ReadString(HSQUIRRELVM vm, char *p);
+};
+
#endif /* SCRIPT_EVENT_TYPES_HPP */
diff --git a/src/script/api/squirrel_export.awk b/src/script/api/squirrel_export.awk
index b0b169576..ed190deaf 100644
--- a/src/script/api/squirrel_export.awk
+++ b/src/script/api/squirrel_export.awk
@@ -385,7 +385,11 @@ BEGIN {
if (mlen <= length(static_methods[i, 0])) mlen = length(static_methods[i, 0])
}
for (i = 1; i <= static_method_size; i++) {
- print " SQ" api_cls ".DefSQStaticMethod(engine, &" cls "::" static_methods[i, 0] ", " substr(spaces, 1, mlen - length(static_methods[i, 0])) "\"" static_methods[i, 0] "\", " substr(spaces, 1, mlen - length(static_methods[i, 0])) "" static_methods[i, 1] ", \"" static_methods[i, 2] "\");"
+ if (static_methods[i, 2] == "v") {
+ print " SQ" api_cls ".DefSQAdvancedStaticMethod(engine, &" cls "::" static_methods[i, 0] ", " substr(spaces, 1, mlen - length(static_methods[i, 0]) - 8) "\"" static_methods[i, 0] "\");"
+ } else {
+ print " SQ" api_cls ".DefSQStaticMethod(engine, &" cls "::" static_methods[i, 0] ", " substr(spaces, 1, mlen - length(static_methods[i, 0])) "\"" static_methods[i, 0] "\", " substr(spaces, 1, mlen - length(static_methods[i, 0])) "" static_methods[i, 1] ", \"" static_methods[i, 2] "\");"
+ }
delete static_methods[i]
}
if (static_method_size != 0) print ""
diff --git a/src/script/api/template/template_admin.hpp.sq b/src/script/api/template/template_admin.hpp.sq
new file mode 100644
index 000000000..2256d674b
--- /dev/null
+++ b/src/script/api/template/template_admin.hpp.sq
@@ -0,0 +1,21 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
+
+#include "../script_admin.hpp"
+
+namespace SQConvert {
+ /* Allow ScriptAdmin to be used as Squirrel parameter */
+ template <> inline ScriptAdmin *GetParam(ForceType<ScriptAdmin *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptAdmin *)instance; }
+ template <> inline ScriptAdmin &GetParam(ForceType<ScriptAdmin &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptAdmin *)instance; }
+ template <> inline const ScriptAdmin *GetParam(ForceType<const ScriptAdmin *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptAdmin *)instance; }
+ template <> inline const ScriptAdmin &GetParam(ForceType<const ScriptAdmin &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptAdmin *)instance; }
+ template <> inline int Return<ScriptAdmin *>(HSQUIRRELVM vm, ScriptAdmin *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Admin", res, NULL, DefSQDestructorCallback<ScriptAdmin>, true); return 1; }
+} // namespace SQConvert
diff --git a/src/script/api/template/template_event_types.hpp.sq b/src/script/api/template/template_event_types.hpp.sq
index cd642c3aa..b5dc02605 100644
--- a/src/script/api/template/template_event_types.hpp.sq
+++ b/src/script/api/template/template_event_types.hpp.sq
@@ -212,3 +212,12 @@ namespace SQConvert {
template <> inline const ScriptEventAircraftDestTooFar &GetParam(ForceType<const ScriptEventAircraftDestTooFar &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAircraftDestTooFar *)instance; }
template <> inline int Return<ScriptEventAircraftDestTooFar *>(HSQUIRRELVM vm, ScriptEventAircraftDestTooFar *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventAircraftDestTooFar", res, NULL, DefSQDestructorCallback<ScriptEventAircraftDestTooFar>, true); return 1; }
} // namespace SQConvert
+
+namespace SQConvert {
+ /* Allow ScriptEventAdminPort to be used as Squirrel parameter */
+ template <> inline ScriptEventAdminPort *GetParam(ForceType<ScriptEventAdminPort *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventAdminPort *)instance; }
+ template <> inline ScriptEventAdminPort &GetParam(ForceType<ScriptEventAdminPort &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAdminPort *)instance; }
+ template <> inline const ScriptEventAdminPort *GetParam(ForceType<const ScriptEventAdminPort *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventAdminPort *)instance; }
+ template <> inline const ScriptEventAdminPort &GetParam(ForceType<const ScriptEventAdminPort &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAdminPort *)instance; }
+ template <> inline int Return<ScriptEventAdminPort *>(HSQUIRRELVM vm, ScriptEventAdminPort *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventAdminPort", res, NULL, DefSQDestructorCallback<ScriptEventAdminPort>, true); return 1; }
+} // namespace SQConvert
diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp
index 4fabdf2fb..7a6b4fe70 100644
--- a/src/script/script_instance.cpp
+++ b/src/script/script_instance.cpp
@@ -297,12 +297,10 @@ static const SaveLoad _script_byte[] = {
SLE_END()
};
-static const uint SCRIPTSAVE_MAX_DEPTH = 25; ///< The maximum recursive depth for items stored in the savegame.
-
/* static */ bool ScriptInstance::SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test)
{
if (max_depth == 0) {
- ScriptLog::Error("Savedata can only be nested to 25 deep. No data saved.");
+ ScriptLog::Error("Savedata can only be nested to 25 deep. No data saved."); // SQUIRREL_MAX_DEPTH = 25
return false;
}
@@ -439,7 +437,7 @@ void ScriptInstance::Save()
_script_sl_byte = 1;
SlObject(NULL, _script_byte);
/* Save the data that was just loaded. */
- SaveObject(vm, -1, SCRIPTSAVE_MAX_DEPTH, false);
+ SaveObject(vm, -1, SQUIRREL_MAX_DEPTH, false);
} else if (!this->is_started) {
SaveEmpty();
return;
@@ -478,10 +476,10 @@ void ScriptInstance::Save()
return;
}
sq_pushobject(vm, savedata);
- if (SaveObject(vm, -1, SCRIPTSAVE_MAX_DEPTH, true)) {
+ if (SaveObject(vm, -1, SQUIRREL_MAX_DEPTH, true)) {
_script_sl_byte = 1;
SlObject(NULL, _script_byte);
- SaveObject(vm, -1, SCRIPTSAVE_MAX_DEPTH, false);
+ SaveObject(vm, -1, SQUIRREL_MAX_DEPTH, false);
this->is_save_data_on_stack = true;
} else {
SaveEmpty();
diff --git a/src/script/script_instance.hpp b/src/script/script_instance.hpp
index e7a23ccd9..d24a40827 100644
--- a/src/script/script_instance.hpp
+++ b/src/script/script_instance.hpp
@@ -17,6 +17,8 @@
#include "../command_type.h"
+static const uint SQUIRREL_MAX_DEPTH = 25; ///< The maximum recursive depth for items stored in the savegame.
+
/** Runtime information about a script like a pointer to the squirrel vm and the current state. */
class ScriptInstance {
public:
diff --git a/src/script/squirrel_class.hpp b/src/script/squirrel_class.hpp
index 73117b60a..55efcdf13 100644
--- a/src/script/squirrel_class.hpp
+++ b/src/script/squirrel_class.hpp
@@ -72,6 +72,16 @@ public:
}
/**
+ * This defines a static method inside a class for Squirrel, which has access to the 'engine' (experts only!).
+ */
+ template <typename Func>
+ void DefSQAdvancedStaticMethod(Squirrel *engine, Func function_proc, const char *function_name)
+ {
+ using namespace SQConvert;
+ engine->AddMethod(function_name, DefSQAdvancedStaticCallback<CL, Func>, 0, NULL, &function_proc, sizeof(function_proc));
+ }
+
+ /**
* This defines a static method inside a class for Squirrel with defined params.
* @note If you define nparam, make sure that he first param is always 'x',
* which is the 'this' inside the function. This is hidden from the rest
diff --git a/src/script/squirrel_helper.hpp b/src/script/squirrel_helper.hpp
index cdc4b8b8f..a72199dce 100644
--- a/src/script/squirrel_helper.hpp
+++ b/src/script/squirrel_helper.hpp
@@ -831,6 +831,28 @@ namespace SQConvert {
}
}
+
+ /**
+ * A general template for all static advanced method callbacks from Squirrel.
+ * In here the function_proc is recovered, and the SQCall is called that
+ * can handle this exact amount of params.
+ */
+ template <typename Tcls, typename Tmethod>
+ inline SQInteger DefSQAdvancedStaticCallback(HSQUIRRELVM vm)
+ {
+ /* Find the amount of params we got */
+ int nparam = sq_gettop(vm);
+ SQUserPointer ptr = NULL;
+
+ /* Get the real function pointer */
+ sq_getuserdata(vm, nparam, &ptr, 0);
+ /* Remove the userdata from the stack */
+ sq_pop(vm, 1);
+
+ /* Call the function, which its only param is always the VM */
+ return (SQInteger)(*(*(Tmethod *)ptr))(vm);
+ }
+
/**
* A general template for the destructor of SQ instances. This is needed
* here as it has to be in the same scope as DefSQConstructorCallback.