File: ade.h

package info (click to toggle)
freespace2 24.2.0%2Brepack-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 43,716 kB
  • sloc: cpp: 595,001; ansic: 21,741; python: 1,174; sh: 457; makefile: 248; xml: 181
file content (302 lines) | stat: -rw-r--r-- 7,129 bytes parent folder | download
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
//
//

#ifndef FS2_OPEN_ADE_H
#define FS2_OPEN_ADE_H

#include "globalincs/pstypes.h"
#include "globalincs/version.h"
#include "globalincs/utility.h"

#include "object/object.h"
#include "scripting/ade_doc.h"

extern "C" {
#include <lauxlib.h>
#include <lualib.h>
}

#include <memory>

/**
 * @defgroup ade_api ADE API functions
 *
 * @brief Functions and macros used in the ADE scripting API
 *
 * These functions enable the code to communicate with external scripts and expose an API for them to use
 */

// lua_tostring will return NULL if and only if it cannot convert to a string; nil values are converted to "nil"
#define lua_tostring_nullsafe(L,i)	coalesce(lua_tostring(L,i), "<UNABLE TO CONVERT TO STRING>")

namespace scripting {

// Forward definition
struct DocumentationElement;

using DocumentationErrorReporter = std::function<void(const SCP_string& errorMessage)>;

/**
 *
 * @param L
 * @param stackdump
 *
 * @ingroup ade_api
 */
void ade_stackdump(lua_State* L, char* stackdump);

/**
 *
 * @param L
 * @return
 *
 * @ingroup ade_api
 */
int ade_friendly_error(lua_State* L);

//*************************Lua types*************************
// Value fo ade_odata::size for when buf contains a pointer
const size_t ODATA_PTR_SIZE = (size_t) -1;

const int ADE_FUNCNAME_UPVALUE_INDEX = 1;
const int ADE_SETTING_UPVALUE_INDEX = 2;
const int ADE_DESTRUCTOR_OBJ_UPVALUE_INDEX = 3; // Upvalue which stores the reference to the ade_obj of a destructor
#define ADE_SETTING_VAR lua_toboolean(L,lua_upvalueindex(ADE_SETTING_UPVALUE_INDEX))

template <typename T>
struct ade_odata_getter {
	size_t idx;
	T* value_ptr;

	ade_odata_getter(size_t idx_in, T* ptr_in) : idx(idx_in), value_ptr(ptr_in) {}
};

template <typename T>
struct ade_odata_ptr_getter {
	size_t idx;
	T** value_ptr;

	ade_odata_ptr_getter(size_t idx_in, T** ptr_in) : idx(idx_in), value_ptr(ptr_in) {}
};

template <typename T>
struct ade_odata_setter {
	size_t idx;
	T value;

	ade_odata_setter(size_t idx_in, T value_in) : idx(idx_in), value(std::move(value_in)) {}
};

class ade_table_entry;

using ade_serialize_func = void(*)(lua_State*, const scripting::ade_table_entry&, const luacpp::LuaValue&, ubyte*, int&);
using ade_deserialize_func = void(*)(lua_State*, const scripting::ade_table_entry&, char*, ubyte*, int&);

//WMC - 'Type' is the same as ade_set_args,
//plus some extra
//b - boolean
//d - double
//f - float
//i - integer
//s - string
//x - fix
//o - object
//EXTRA:
//l - library	//WMC - no longer exists
//u - function
//v - virtual variable
//
//u - oh wait...

/**
 * @ingroup ade_api
 */
class ade_table_entry {
 public:
	const char* Name = nullptr;
	const char* ShortName = nullptr;

	//Important stuff
	size_t Idx = UINT_MAX;
	size_t ParentIdx = UINT_MAX;
	size_t DerivatorIdx = UINT_MAX;
	//ade_id AdeID;
	//ade_id DerivatorID;			//Who do we derive from

	//Type-specific
	bool Instanced = false;                //Is this a single instance?
	char Type = '\0';

	//Functions/virtfuncs
	lua_CFunction Function = nullptr;

	// For Objects, the destructor of the object
	void* Destructor_upvalue = nullptr;
	lua_CFunction Destructor = nullptr;

	size_t Size = 0;
	ade_serialize_func Serializer = nullptr;
	ade_deserialize_func Deserializer = nullptr;

	//Metadata
	ade_overload_list Arguments;
	const char* Description = nullptr;
	const char* ReturnType;
	const char* ReturnDescription = nullptr;
	gameversion::version DeprecationVersion;
	const char* DeprecationMessage = nullptr;

	//Subentries, of course
	//WMC - I have HAD it with these motherfriendly vectors
	//on this motherfriendly class.
	size_t Num_subentries = 0;
	size_t Subentries[256];

 private:
	//*****Internal functions
	//int IndexHandler(lua_State *L);

 public:
	//*****Constructors
	ade_table_entry();

	//*****Operators
	//ade_table_entry &operator = (const ade_table_entry &ate);

	//*****Functions
	size_t AddSubentry(ade_table_entry& n_ate);
	int SetTable(lua_State* L, int p_amt_ldx, int p_mtb_ldx);
	std::unique_ptr<DocumentationElement> ToDocumentationElement(
		const scripting::DocumentationErrorReporter& errorReporter);

	//*****Get
	const char* GetName() const;

	SCP_string GetFullPath() const;
};

/**
 * @ingroup ade_api
 */
class ade_manager {
	SCP_vector<ade_table_entry> _table_entries;

	SCP_vector<SCP_string> _type_names;

	ade_manager();
 public:
	static ade_manager* getInstance();

	// Disallow copying
	ade_manager(const ade_manager&) = delete;
	ade_manager& operator=(const ade_manager&) = delete;

	// Disallow moving
	ade_manager(ade_manager&&) = delete;
	ade_manager& operator=(ade_manager&&) = delete;

	size_t addTableEntry(const ade_table_entry& entry);

	ade_table_entry& getEntry(size_t idx);
	const ade_table_entry& getEntry(size_t idx) const;

	size_t getNumEntries() const { return _table_entries.size(); }

	const SCP_vector<SCP_string>& getTypeNames() const;
};

/**
 * @ingroup ade_api
 */
void ade_stackdump(lua_State *L, char *stackdump);

/**
 * @ingroup ade_api
 */
int ade_friendly_error(lua_State* L);

/**
 * @ingroup ade_api
 */
const char* ade_get_type_string(lua_State* L, int argnum);

/**
 * @ingroup ade_api
 */
bool ade_is_internal_type(const char* typeName);

template <typename T, typename = int>
struct ade_is_valid : std::false_type
{
	static inline bool get(const T& /*t*/)
	{
		//Things without an isValid are always considered valid from this point of view.
		return true;
	}
};

template <typename T>
struct ade_is_valid <T, decltype((void)(std::declval<T>().isValid()), 0)> : std::true_type
{
	static inline bool get(const T& t)
	{
		//Things with an isValid return that.
		return t.isValid();
	}
};

/**
 * @brief Converts an object index to something that can be used with ade_set_args.
 *
 * This respects the actual type of the object so all appropriate functions are available in Lua.
 *
 * @warning This is only used internally and should not be used by API code. Use ade_set_object_with_breed instead.
 *
 * @param obj_idx The object index
 * @return The ade odata
 */
ade_odata_setter<object_h> ade_object_to_odata(int obj_idx);

/**
 * @brief Sets an object parameter with the right type
 *
 * This should be used everywhere where an object value is returned to make sure that the scripter has access to
 * all API functions.
 *
 * @param L The lua state
 * @param obj_idx The object number
 * @return The return value of ade_set_args
 *
 * @author WMC
 * @ingroup ade_api
 */
int ade_set_object_with_breed(lua_State* L, int obj_idx);

/**
 * @brief Loads and executes a default lua script
 *
 * This uses the specified file name and either retrieves it from the default files or uses it as a file name if the mod
 * option is enabled.
 *
 * @param L The lua state
 * @param name The name of the script file
 *
 * @ingroup ade_api
 */
void load_default_script(lua_State* L, const char* name);

//Struct for converting one string for another. whee!
struct string_conv {
	const char *src;
	const char *dest;
};

const string_conv* ade_get_operator(const char *funcname);

namespace internal {

ade_table_entry& getTableEntry(size_t idx);
}
} // namespace scripting

#endif // FS2_OPEN_ADE_H