Files
@ r28572:dd3e6f760743
Branch filter:
Location: cpp/openttd-patchpack/source/src/script/squirrel.hpp - annotation
r28572:dd3e6f760743
9.4 KiB
text/x-c++hdr
Update: nlohmann/json to 3.11.3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r12768:980ae0491352 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r15934:789c54d0000d r15934:789c54d0000d r18496:a8bd60b0514d r27106:2d95beb51290 r27106:2d95beb51290 r27106:2d95beb51290 r18496:a8bd60b0514d r18496:a8bd60b0514d r23730:3b11f535de42 r23730:3b11f535de42 r10696:8dfe83e30d01 r23730:3b11f535de42 r23730:3b11f535de42 r10696:8dfe83e30d01 r27143:ecee9375b5d4 r10696:8dfe83e30d01 r18498:e200d299014d r10696:8dfe83e30d01 r23607:36c15679007d r11121:b7c57fb5f2a7 r17364:eb97848263b6 r18498:e200d299014d r23730:3b11f535de42 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r18498:e200d299014d r18498:e200d299014d r18498:e200d299014d r18498:e200d299014d r21503:8c1c128b45b6 r21503:8c1c128b45b6 r21503:8c1c128b45b6 r21503:8c1c128b45b6 r21503:8c1c128b45b6 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r27143:ecee9375b5d4 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r27143:ecee9375b5d4 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r18498:e200d299014d r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r18512:1adfa053a958 r18512:1adfa053a958 r18512:1adfa053a958 r18512:1adfa053a958 r18512:1adfa053a958 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r27353:e630ed301eee r27353:e630ed301eee r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r27353:e630ed301eee r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r23607:36c15679007d r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r12557:c2a1f0721f17 r12557:c2a1f0721f17 r12557:c2a1f0721f17 r15882:30fbd9be7c68 r15882:30fbd9be7c68 r15882:30fbd9be7c68 r15882:30fbd9be7c68 r15882:30fbd9be7c68 r15882:30fbd9be7c68 r12557:c2a1f0721f17 r12557:c2a1f0721f17 r12557:c2a1f0721f17 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10990:c51128ad9005 r12747:88887bb65108 r12747:88887bb65108 r12747:88887bb65108 r12747:88887bb65108 r12747:88887bb65108 r10990:c51128ad9005 r10990:c51128ad9005 r10990:c51128ad9005 r10990:c51128ad9005 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r15882:30fbd9be7c68 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r11121:b7c57fb5f2a7 r10696:8dfe83e30d01 r16571:511b3c71e60d r23607:36c15679007d r27352:2279f2687a7b r16571:511b3c71e60d r16571:511b3c71e60d r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r13060:e57594b0ca84 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r18498:e200d299014d r10696:8dfe83e30d01 r10696:8dfe83e30d01 r27365:849bb90cdbff r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r27365:849bb90cdbff r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r25705:db1afb7a7392 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r21639:04805e592ebb r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r11720:a2a7bf20700e r11720:a2a7bf20700e r11720:a2a7bf20700e r11720:a2a7bf20700e r11720:a2a7bf20700e r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r27357:d987424862c7 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r11065:0af2fa697c41 r11065:0af2fa697c41 r11065:0af2fa697c41 r11065:0af2fa697c41 r11065:0af2fa697c41 r11121:b7c57fb5f2a7 r11121:b7c57fb5f2a7 r11121:b7c57fb5f2a7 r11121:b7c57fb5f2a7 r11121:b7c57fb5f2a7 r11121:b7c57fb5f2a7 r11121:b7c57fb5f2a7 r11121:b7c57fb5f2a7 r11121:b7c57fb5f2a7 r11121:b7c57fb5f2a7 r11121:b7c57fb5f2a7 r11121:b7c57fb5f2a7 r11121:b7c57fb5f2a7 r18412:5dc426e50f35 r12392:a1db9214fc64 r12392:a1db9214fc64 r12392:a1db9214fc64 r12392:a1db9214fc64 r12087:0095f1069b29 r12087:0095f1069b29 r12087:0095f1069b29 r18272:acd8b4f10c7a r18272:acd8b4f10c7a r18272:acd8b4f10c7a r18272:acd8b4f10c7a r18272:acd8b4f10c7a r21503:8c1c128b45b6 r21503:8c1c128b45b6 r21503:8c1c128b45b6 r21503:8c1c128b45b6 r21503:8c1c128b45b6 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r23730:3b11f535de42 r10696:8dfe83e30d01 r10696:8dfe83e30d01 r10696:8dfe83e30d01 | /*
* 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 squirrel.hpp defines the Squirrel class */
#ifndef SQUIRREL_HPP
#define SQUIRREL_HPP
#include <squirrel.h>
/** The type of script we're working with, i.e. for who is it? */
enum class ScriptType {
AI, ///< The script is for AI scripts.
GS, ///< The script is for Game scripts.
};
struct ScriptAllocator;
class Squirrel {
friend class ScriptAllocatorScope;
private:
typedef void (SQPrintFunc)(bool error_msg, const std::string &message);
HSQUIRRELVM vm; ///< The VirtualMachine instance for squirrel
void *global_pointer; ///< Can be set by who ever initializes Squirrel
SQPrintFunc *print_func; ///< Points to either nullptr, or a custom print handler
bool crashed; ///< True if the squirrel script made an error.
int overdrawn_ops; ///< The amount of operations we have overdrawn.
const char *APIName; ///< Name of the API used for this squirrel.
std::unique_ptr<ScriptAllocator> allocator; ///< Allocator object used by this script.
/**
* The internal RunError handler. It looks up the real error and calls RunError with it.
*/
static SQInteger _RunError(HSQUIRRELVM vm);
/**
* Get the API name.
*/
const char *GetAPIName() { return this->APIName; }
/** Perform all initialization steps to create the engine. */
void Initialize();
/** Perform all the cleanups for the engine. */
void Uninitialize();
protected:
/**
* The CompileError handler.
*/
static void CompileError(HSQUIRRELVM vm, const SQChar *desc, const SQChar *source, SQInteger line, SQInteger column);
/**
* The RunError handler.
*/
static void RunError(HSQUIRRELVM vm, const SQChar *error);
/**
* If a user runs 'print' inside a script, this function gets the params.
*/
static void PrintFunc(HSQUIRRELVM vm, const std::string &s);
/**
* If an error has to be print, this function is called.
*/
static void ErrorPrintFunc(HSQUIRRELVM vm, const std::string &s);
public:
Squirrel(const char *APIName);
~Squirrel();
/**
* Get the squirrel VM. Try to avoid using this.
*/
HSQUIRRELVM GetVM() { return this->vm; }
/**
* Load a script.
* @param script The full script-name to load.
* @return False if loading failed.
*/
bool LoadScript(const std::string &script);
bool LoadScript(HSQUIRRELVM vm, const std::string &script, bool in_root = true);
/**
* Load a file to a given VM.
*/
SQRESULT LoadFile(HSQUIRRELVM vm, const std::string &filename, SQBool printerror);
/**
* Adds a function to the stack. Depending on the current state this means
* either a method or a global function.
*/
void AddMethod(const char *method_name, SQFUNCTION proc, uint nparam = 0, const char *params = nullptr, void *userdata = nullptr, int size = 0);
/**
* Adds a const to the stack. Depending on the current state this means
* either a const to a class or to the global space.
*/
void AddConst(const char *var_name, int value);
/**
* Adds a const to the stack. Depending on the current state this means
* either a const to a class or to the global space.
*/
void AddConst(const char *var_name, uint value) { this->AddConst(var_name, (int)value); }
/**
* Adds a const to the stack. Depending on the current state this means
* either a const to a class or to the global space.
*/
void AddConst(const char *var_name, bool value);
/**
* Adds a class to the global scope. Make sure to call AddClassEnd when you
* are done adding methods.
*/
void AddClassBegin(const char *class_name);
/**
* Adds a class to the global scope, extending 'parent_class'.
* Make sure to call AddClassEnd when you are done adding methods.
*/
void AddClassBegin(const char *class_name, const char *parent_class);
/**
* Finishes adding a class to the global scope. If this isn't called, no
* class is really created.
*/
void AddClassEnd();
/**
* Resume a VM when it was suspended via a throw.
*/
bool Resume(int suspend = -1);
/**
* Resume the VM with an error so it prints a stack trace.
*/
void ResumeError();
/**
* Tell the VM to do a garbage collection run.
*/
void CollectGarbage();
void InsertResult(bool result);
void InsertResult(int result);
void InsertResult(uint result) { this->InsertResult((int)result); }
/**
* Call a method of an instance, in various flavors.
* @return False if the script crashed or returned a wrong type.
*/
bool CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT *ret, int suspend);
bool CallMethod(HSQOBJECT instance, const char *method_name, int suspend) { return this->CallMethod(instance, method_name, nullptr, suspend); }
bool CallStringMethod(HSQOBJECT instance, const char *method_name, std::string *res, int suspend);
bool CallIntegerMethod(HSQOBJECT instance, const char *method_name, int *res, int suspend);
bool CallBoolMethod(HSQOBJECT instance, const char *method_name, bool *res, int suspend);
/**
* Check if a method exists in an instance.
*/
bool MethodExists(HSQOBJECT instance, const char *method_name);
/**
* Creates a class instance.
* @param vm The VM to create the class instance for
* @param class_name The name of the class of which we create an instance.
* @param real_instance The instance to the real class, if it represents a real class.
* @param instance Returning value with the pointer to the instance.
* @param release_hook Optional param to give a release hook.
* @param prepend_API_name Optional parameter; if true, the class_name is prefixed with the current API name.
* @return False if creating failed.
*/
static bool CreateClassInstanceVM(HSQUIRRELVM vm, const std::string &class_name, void *real_instance, HSQOBJECT *instance, SQRELEASEHOOK release_hook, bool prepend_API_name = false);
/**
* Exactly the same as CreateClassInstanceVM, only callable without instance of Squirrel.
*/
bool CreateClassInstance(const std::string &class_name, void *real_instance, HSQOBJECT *instance);
/**
* Get the real-instance pointer.
* @note This will only work just after a function-call from within Squirrel
* to your C++ function.
*/
static bool GetRealInstance(HSQUIRRELVM vm, SQUserPointer *ptr) { return SQ_SUCCEEDED(sq_getinstanceup(vm, 1, ptr, nullptr)); }
/**
* Get the Squirrel-instance pointer.
* @note This will only work just after a function-call from within Squirrel
* to your C++ function.
*/
static bool GetInstance(HSQUIRRELVM vm, HSQOBJECT *ptr, int pos = 1) { sq_getclass(vm, pos); sq_getstackobj(vm, pos, ptr); sq_pop(vm, 1); return true; }
/**
* Convert a Squirrel-object to a string.
*/
static const char *ObjectToString(HSQOBJECT *ptr) { return sq_objtostring(ptr); }
/**
* Convert a Squirrel-object to an integer.
*/
static int ObjectToInteger(HSQOBJECT *ptr) { return sq_objtointeger(ptr); }
/**
* Convert a Squirrel-object to a bool.
*/
static bool ObjectToBool(HSQOBJECT *ptr) { return sq_objtobool(ptr) == 1; }
/**
* Sets a pointer in the VM that is reachable from where ever you are in SQ.
* Useful to keep track of the main instance.
*/
void SetGlobalPointer(void *ptr) { this->global_pointer = ptr; }
/**
* Get the pointer as set by SetGlobalPointer.
*/
static void *GetGlobalPointer(HSQUIRRELVM vm) { return ((Squirrel *)sq_getforeignptr(vm))->global_pointer; }
/**
* Set a custom print function, so you can handle outputs from SQ yourself.
*/
void SetPrintFunction(SQPrintFunc *func) { this->print_func = func; }
/**
* Throw a Squirrel error that will be nicely displayed to the user.
*/
void ThrowError(const std::string_view error) { sq_throwerror(this->vm, error); }
/**
* Release a SQ object.
*/
void ReleaseObject(HSQOBJECT *ptr) { sq_release(this->vm, ptr); }
/**
* Tell the VM to remove \c amount ops from the number of ops till suspend.
*/
static void DecreaseOps(HSQUIRRELVM vm, int amount);
/**
* Did the squirrel code suspend or return normally.
* @return True if the function suspended.
*/
bool IsSuspended();
/**
* Find out if the squirrel script made an error before.
*/
bool HasScriptCrashed();
/**
* Set the script status to crashed.
*/
void CrashOccurred();
/**
* Are we allowed to suspend the squirrel script at this moment?
*/
bool CanSuspend();
/**
* How many operations can we execute till suspension?
*/
SQInteger GetOpsTillSuspend();
/**
* Completely reset the engine; start from scratch.
*/
void Reset();
/**
* Get number of bytes allocated by this VM.
*/
size_t GetAllocatedMemory() const noexcept;
};
extern ScriptAllocator *_squirrel_allocator;
class ScriptAllocatorScope {
ScriptAllocator *old_allocator;
public:
ScriptAllocatorScope(const Squirrel *engine)
{
this->old_allocator = _squirrel_allocator;
/* This may get called with a nullptr engine, in case of a crashed script */
_squirrel_allocator = engine != nullptr ? engine->allocator.get() : nullptr;
}
~ScriptAllocatorScope()
{
_squirrel_allocator = this->old_allocator;
}
};
#endif /* SQUIRREL_HPP */
|