]> git.lizzy.rs Git - dragonfireclient.git/blob - src/script/cpp_api/s_base.h
Move scriptapi to separate folder (by sapier)
[dragonfireclient.git] / src / script / cpp_api / s_base.h
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef S_BASE_H_
21 #define S_BASE_H_
22
23 #include <iostream>
24
25 #include "irrlichttypes.h"
26 #include "jmutex.h"
27 #include "jmutexautolock.h"
28 #include "common/c_types.h"
29 #include "debug.h"
30
31 #define LOCK_DEBUG
32
33 class Server;
34 class Environment;
35 class ServerActiveObject;
36 class LuaABM;
37 class InvRef;
38 class ModApiBase;
39 class ModApiEnvMod;
40 class ObjectRef;
41 class NodeMetaRef;
42
43
44 /* definitions */
45 // What scriptapi_run_callbacks does with the return values of callbacks.
46 // Regardless of the mode, if only one callback is defined,
47 // its return value is the total return value.
48 // Modes only affect the case where 0 or >= 2 callbacks are defined.
49 enum RunCallbacksMode
50 {
51         // Returns the return value of the first callback
52         // Returns nil if list of callbacks is empty
53         RUN_CALLBACKS_MODE_FIRST,
54         // Returns the return value of the last callback
55         // Returns nil if list of callbacks is empty
56         RUN_CALLBACKS_MODE_LAST,
57         // If any callback returns a false value, the first such is returned
58         // Otherwise, the first callback's return value (trueish) is returned
59         // Returns true if list of callbacks is empty
60         RUN_CALLBACKS_MODE_AND,
61         // Like above, but stops calling callbacks (short circuit)
62         // after seeing the first false value
63         RUN_CALLBACKS_MODE_AND_SC,
64         // If any callback returns a true value, the first such is returned
65         // Otherwise, the first callback's return value (falseish) is returned
66         // Returns false if list of callbacks is empty
67         RUN_CALLBACKS_MODE_OR,
68         // Like above, but stops calling callbacks (short circuit)
69         // after seeing the first true value
70         RUN_CALLBACKS_MODE_OR_SC,
71         // Note: "a true value" and "a false value" refer to values that
72         // are converted by lua_toboolean to true or false, respectively.
73 };
74
75
76 class ScriptApiBase {
77 public:
78
79         /* object */
80         void addObjectReference(ServerActiveObject *cobj);
81         void removeObjectReference(ServerActiveObject *cobj);
82
83         ScriptApiBase();
84
85 protected:
86         friend class LuaABM;
87         friend class InvRef;
88         friend class ObjectRef;
89         friend class NodeMetaRef;
90         friend class ModApiBase;
91         friend class ModApiEnvMod;
92
93
94         inline lua_State* getStack()
95                 { return m_luastack; }
96
97         bool setStack(lua_State* stack) {
98                 if (m_luastack == 0) {
99                         m_luastack = stack;
100                         return true;
101                 }
102                 return false;
103         }
104
105         void realityCheck();
106         void scriptError(const char *fmt, ...);
107         void stackDump(std::ostream &o);
108         void runCallbacks(int nargs,RunCallbacksMode mode);
109
110         inline Server* getServer() { return m_server; }
111         void setServer(Server* server) { m_server = server; }
112
113         Environment* getEnv() { return m_environment; }
114         void setEnv(Environment* env) { m_environment = env; }
115
116         void objectrefGetOrCreate(ServerActiveObject *cobj);
117         void objectrefGet(u16 id);
118
119         JMutex                  m_luastackmutex;
120 #ifdef LOCK_DEBUG
121         bool            m_locked;
122 #endif
123 private:
124         lua_State*      m_luastack;
125
126         Server*                 m_server;
127         Environment*    m_environment;
128
129
130 };
131
132 #ifdef LOCK_DEBUG
133 class LockChecker {
134 public:
135         LockChecker(bool* variable) {
136                 assert(*variable == false);
137
138                 m_variable = variable;
139                 *m_variable = true;
140         }
141         ~LockChecker() {
142                 *m_variable = false;
143         }
144 private:
145 bool* m_variable;
146 };
147
148 #define LOCK_CHECK LockChecker(&(this->m_locked))
149 #else
150 #define LOCK_CHECK while(0)
151 #endif
152
153 #define LUA_STACK_AUTOLOCK JMutexAutoLock(this->m_luastackmutex)
154
155 #define SCRIPTAPI_PRECHECKHEADER                                               \
156                 LUA_STACK_AUTOLOCK;                                                    \
157                 LOCK_CHECK;                                                            \
158                 realityCheck();                                                        \
159                 lua_State *L = getStack();                                             \
160                 assert(lua_checkstack(L, 20));                                         \
161                 StackUnroller stack_unroller(L);
162
163 #define PLAYER_TO_SA(p)   p->getEnv()->getScriptIface()
164 #define ENV_TO_SA(env)    env->getScriptIface()
165 #define SERVER_TO_SA(srv) srv->getScriptIface()
166
167 #endif /* S_BASE_H_ */