]> git.lizzy.rs Git - dragonfireclient.git/blob - src/script/cpp_api/s_base.h
8799d3c0021e5e15e7f6d8b57898ba80ab985dc3
[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         friend class LuaVoxelManip;
93
94
95         inline lua_State* getStack()
96                 { return m_luastack; }
97
98         bool setStack(lua_State* stack) {
99                 if (m_luastack == 0) {
100                         m_luastack = stack;
101                         return true;
102                 }
103                 return false;
104         }
105
106         void realityCheck();
107         void scriptError(const char *fmt, ...);
108         void stackDump(std::ostream &o);
109         void runCallbacks(int nargs,RunCallbacksMode mode);
110
111         inline Server* getServer() { return m_server; }
112         void setServer(Server* server) { m_server = server; }
113
114         Environment* getEnv() { return m_environment; }
115         void setEnv(Environment* env) { m_environment = env; }
116
117         void objectrefGetOrCreate(ServerActiveObject *cobj);
118         void objectrefGet(u16 id);
119
120         JMutex                  m_luastackmutex;
121 #ifdef LOCK_DEBUG
122         bool            m_locked;
123 #endif
124 private:
125         lua_State*      m_luastack;
126
127         Server*                 m_server;
128         Environment*    m_environment;
129
130
131 };
132
133 #ifdef LOCK_DEBUG
134 class LockChecker {
135 public:
136         LockChecker(bool* variable) {
137                 assert(*variable == false);
138
139                 m_variable = variable;
140                 *m_variable = true;
141         }
142         ~LockChecker() {
143                 *m_variable = false;
144         }
145 private:
146 bool* m_variable;
147 };
148
149 #define LOCK_CHECK LockChecker(&(this->m_locked))
150 #else
151 #define LOCK_CHECK while(0)
152 #endif
153
154 #define LUA_STACK_AUTOLOCK JMutexAutoLock(this->m_luastackmutex)
155
156 #define SCRIPTAPI_PRECHECKHEADER                                               \
157                 LUA_STACK_AUTOLOCK;                                                    \
158                 LOCK_CHECK;                                                            \
159                 realityCheck();                                                        \
160                 lua_State *L = getStack();                                             \
161                 assert(lua_checkstack(L, 20));                                         \
162                 StackUnroller stack_unroller(L);
163
164 #define PLAYER_TO_SA(p)   p->getEnv()->getScriptIface()
165 #define ENV_TO_SA(env)    env->getScriptIface()
166 #define SERVER_TO_SA(srv) srv->getScriptIface()
167
168 #endif /* S_BASE_H_ */