File: EngineSEXP.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 (214 lines) | stat: -rw-r--r-- 5,209 bytes parent folder | download | duplicates (2)
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
#pragma once

#include "globalincs/pstypes.h"

#include "DynamicSEXP.h"
#include "SEXPParameterExtractor.h"

namespace sexp {

class EngineSEXP;

struct dummy_return {
};

using EngineSexpAction = std::function<int(SEXPParameterExtractor* extractor)>;

class EngineSEXPFactory {
	std::unique_ptr<EngineSEXP> m_sexp;

	SCP_string _helpText;

	int _category = OP_CATEGORY_NONE;
	SCP_string _categoryName;

	int _subcategory = OP_SUBCATEGORY_NONE;
	SCP_string _subcategoryName;

	int _returnType = -1;

	EngineSexpAction _action;

	struct argument {
		int type = -1;
		SCP_string help_text;

		bool optional_marker = false;
		bool varargs_marker = false;
	};
	static bool isArgumentOptional(const argument& arg);
	static bool isArgumentVarargsMarker(const argument& arg);

	SCP_vector<argument> _arguments;

	class ArgumentListBuilder {
		EngineSEXPFactory* _parent;

	  public:
		ArgumentListBuilder(EngineSEXPFactory* parent);

		/**
		 * @brief Adds a parameter of the specified type with help text.
		 * @param type The type of this parameter
		 * @param help_text A helpful text for this parameter
		 * @return The arglist builder
		 */
		ArgumentListBuilder& arg(int type, SCP_string help_text);
		/**
		 * @brief Specifies that all following arguments are optional
		 * @return The arglist builder
		 */
		ArgumentListBuilder& beginOptional();
		/**
		 * @brief Begins the part of the parameter list which can be repeated
		 * @return The arglist builder
		 */
		ArgumentListBuilder& beginVarargs();

		/**
		 * @brief Finishes the argument list
		 * @return The parent engine SEXP factory
		 */
		EngineSEXPFactory& finishArguments();
	};

	friend ArgumentListBuilder;

  public:
	EngineSEXPFactory(std::unique_ptr<EngineSEXP> sexp);
	virtual ~EngineSEXPFactory();

	EngineSEXPFactory(EngineSEXPFactory&&) noexcept = default;
	EngineSEXPFactory& operator=(EngineSEXPFactory&&) noexcept = default;

	/**
	 * @brief Specifies the help text of the SEXP
	 * @param text The help text
	 * @return The factory
	 */
	EngineSEXPFactory& helpText(SCP_string text);

	/**
	 * @brief The return type of the SEXP
	 *
	 * This is a required value!
	 *
	 * @param type The OPR_ value
	 * @return The factory
	 */
	EngineSEXPFactory& returnType(int type);

	/**
	 * @brief The category where this SEXP will be located
	 *
	 * This is a required value!
	 *
	 * @param cat The OP_CATEGORY_ value
	 * @return The factory
	 */
	EngineSEXPFactory& category(int cat);
	/**
	 * @brief Sets the category of the SEXP.
	 *
	 * This can be a new category which will be created automatically.
	 *
	 * This or the number variant is a required value!
	 *
	 * @param cat The name of the category
	 * @return The factory
	 */
	EngineSEXPFactory& category(const SCP_string& cat);

	/**
	 * @brief The subcategory of this SEXP
	 *
	 * This or the string variant is a required value!
	 *
	 * @param subcat The *_SUBCATEGORY_* value
	 * @return The factory
	 */
	EngineSEXPFactory& subcategory(int subcat);
	/**
	 * @brief Sets the subcategory of the SEXP.
	 *
	 * This can be a new subcategory which will be created automatically.
	 *
	 * This or the number variant is a required value!
	 *
	 * @param subcat The name of the subcategory
	 * @return The factory
	 */
	EngineSEXPFactory& subcategory(const SCP_string& subcat);

	/**
	 * @brief Begins specifying arguments for the SEXP
	 * @return
	 */
	ArgumentListBuilder beginArgList();

	/**
	 * @brief The function that will be called for executing the SEXP
	 * @param act The function to execute
	 * @return The factory
	 */
	EngineSEXPFactory& action(EngineSexpAction act);

	/**
	 * @brief Finishes the construction of the SEXP
	 * @return A dummy value to allow SEXPs to be added statically at application start
	 */
	dummy_return finish();
};

class EngineSEXP : public DynamicSEXP {
	EngineSEXP(const SCP_string& name);

  public:
	void initialize() override;
	int getMinimumArguments() const override;
	int getMaximumArguments() const override;
	int getArgumentType(int argnum) const override;
	int execute(int node, int parent_node = -1) override;
	int getReturnType() override;
	int getSubcategory() override;
	int getCategory() override;

	/**
	 * @brief Start creating an engine SEXP.
	 *
	 * This returns a factory with which the various parameters of the SEXP can be configured
	 *
	 * @param name The name of the SEXP
	 * @return The engine SEXP factory
	 */
	static EngineSEXPFactory create(const SCP_string& name);

  private:
	void setCategory(int category);
	void setCategoryName(SCP_string category);
	void setSubcategory(int subcategory);
	void setSubcategoryName(SCP_string subcategory);
	void setHelpText(SCP_string helpText);
	void setReturnType(int returnType);
	void initArguments(int minArgs, int maxArgs, SCP_vector<int> argTypes, SCP_vector<int> varargsTypes);
	void setAction(EngineSexpAction action);

	int _category = OP_CATEGORY_NONE;
	SCP_string _categoryName;

	int _subcategory = OP_SUBCATEGORY_NONE;
	SCP_string _subcategoryName;

	int _returnType = -1;

	int _minArgs = -1;
	int _maxArgs = -1;
	SCP_vector<int> _argumentTypes;
	SCP_vector<int> _variableArgumentsTypes;

	EngineSexpAction _action;

	friend EngineSEXPFactory;
};

} // namespace sexp