1 /**
2  * @file
3  */
4 
5 /*
6 Copyright (C) 2002-2013 UFO: Alien Invasion.
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 
23 */
24 
25 #pragma once
26 
27 #include "../../common/common.h"
28 
29 /** @brief Type for uiAction_t
30  * It also contain type about type (for example EA_BINARYOPERATOR)
31  * @sa uiAction_t
32  */
33 typedef enum uiActionType_s {
34 	EA_NULL = 0,
35 
36 	EA_BINARYOPERATOR,
37 	EA_UNARYOPERATOR,
38 
39 	/* masks */
40 	EA_HIGHT_MASK = 0xFF00,
41 
42 	/* actions */
43 	EA_ACTION = 0x0100,
44 	EA_CMD = EA_ACTION + 1,
45 	EA_CALL = EA_ACTION + 2,
46 	EA_ASSIGN = EA_ACTION + 3,
47 	EA_IF = EA_ACTION + 4,
48 	EA_ELSE = EA_ACTION + 5,
49 	EA_ELIF = EA_ACTION + 6,
50 	EA_WHILE = EA_ACTION + 7,
51 	EA_DELETE = EA_ACTION + 8,
52 	EA_LISTENER = EA_ACTION + 9,
53 	EA_PUSHVARS = EA_ACTION + 10,
54 	EA_POPVARS = EA_ACTION + 11,
55 
56 	/* boolean to boolean operators */
57 	EA_OPERATOR_BOOLEAN2BOOLEAN = 0x0300,
58 	EA_OPERATOR_AND = EA_OPERATOR_BOOLEAN2BOOLEAN + 1,
59 	EA_OPERATOR_OR = EA_OPERATOR_BOOLEAN2BOOLEAN + 2,
60 	EA_OPERATOR_XOR = EA_OPERATOR_BOOLEAN2BOOLEAN + 3,
61 	EA_OPERATOR_NOT = EA_OPERATOR_BOOLEAN2BOOLEAN + 4,
62 
63 	/* float to boolean operators */
64 	EA_OPERATOR_FLOAT2BOOLEAN = 0x0400,
65 	EA_OPERATOR_EQ = EA_OPERATOR_FLOAT2BOOLEAN + 1, /**< == */
66 	EA_OPERATOR_LE = EA_OPERATOR_FLOAT2BOOLEAN + 2, /**< <= */
67 	EA_OPERATOR_GE = EA_OPERATOR_FLOAT2BOOLEAN + 3, /**< >= */
68 	EA_OPERATOR_GT = EA_OPERATOR_FLOAT2BOOLEAN + 4, /**< > */
69 	EA_OPERATOR_LT = EA_OPERATOR_FLOAT2BOOLEAN + 5, /**< < */
70 	EA_OPERATOR_NE = EA_OPERATOR_FLOAT2BOOLEAN + 6, /**< != */
71 
72 	/* float to float operators */
73 	EA_OPERATOR_FLOAT2FLOAT = 0x0500,
74 	EA_OPERATOR_ADD = EA_OPERATOR_FLOAT2FLOAT + 1,
75 	EA_OPERATOR_SUB = EA_OPERATOR_FLOAT2FLOAT + 2,
76 	EA_OPERATOR_MUL = EA_OPERATOR_FLOAT2FLOAT + 3,
77 	EA_OPERATOR_DIV = EA_OPERATOR_FLOAT2FLOAT + 4,
78 	EA_OPERATOR_MOD = EA_OPERATOR_FLOAT2FLOAT + 5,
79 
80 	/* string operators */
81 	EA_OPERATOR_STRING2BOOLEAN = 0x0600,
82 	EA_OPERATOR_STR_EQ = EA_OPERATOR_STRING2BOOLEAN + 1,	/**< eq */
83 	EA_OPERATOR_STR_NE = EA_OPERATOR_STRING2BOOLEAN + 2,	/**< ne */
84 
85 	/* unary operators */
86 	EA_OPERATOR_UNARY = 0x0700,
87 	EA_OPERATOR_EXISTS = EA_OPERATOR_UNARY + 1,				/**< only cvar given - check for existence */
88 	EA_OPERATOR_PATHFROM = EA_OPERATOR_UNARY + 2,			/**< apply a relative path to a node an return a node */
89 	EA_OPERATOR_PATHPROPERTYFROM = EA_OPERATOR_UNARY + 3,	/**< apply a relative path to a node an return a property */
90 
91 	/* terminal values (leafs) */
92 	EA_VALUE = 0x0A00,
93 	EA_VALUE_STRING = EA_VALUE + 1,						/**< reference to a string */
94 	EA_VALUE_STRING_WITHINJECTION = EA_VALUE + 2,		/**< reference to a injected string */
95 	EA_VALUE_FLOAT = EA_VALUE + 3,						/**< embedded float */
96 	EA_VALUE_RAW = EA_VALUE + 4,						/**< reference to a binary value */
97 	EA_VALUE_CVARNAME = EA_VALUE + 5,					/**< reference to a cvarname */
98 	EA_VALUE_CVARNAME_WITHINJECTION = EA_VALUE + 6,		/**< should be into an extra action type */
99 	EA_VALUE_PATHNODE = EA_VALUE + 7,					/**< reference to a path, without property */
100 	EA_VALUE_PATHNODE_WITHINJECTION = EA_VALUE + 8,		/**< should be into an extra action type */
101 	EA_VALUE_PATHPROPERTY = EA_VALUE + 9,				/**< reference to a path, and a property */
102 	EA_VALUE_PATHPROPERTY_WITHINJECTION = EA_VALUE + 10,/**< should be into an extra action type */
103 	EA_VALUE_NODEPROPERTY = EA_VALUE + 11,				/**< reference to a node, and a property (not a string) */
104 	EA_VALUE_VAR = EA_VALUE + 12,						/**< reference to a var */
105 	EA_VALUE_CVAR = EA_VALUE + 13,						/**< reference to a cvar */
106 	EA_VALUE_NODE = EA_VALUE + 14,						/**< reference to a node */
107 	EA_VALUE_PARAM = EA_VALUE + 15,						/**< reference to a param */
108 	EA_VALUE_PARAMCOUNT = EA_VALUE + 16,				/**< reference to the number of params */
109 	EA_VALUE_THIS = EA_VALUE + 17,						/**< reference to the current node */
110 	EA_VALUE_WINDOW = EA_VALUE + 18,					/**< reference to the window node */
111 	EA_VALUE_PARENT = EA_VALUE + 19						/**< reference to the parent node */
112 } uiActionType_t;
113 
114 
115 
116 /**
117  * @brief Defines the data of a @c uiAction_t leaf.
118  * It allows different kind of data without cast
119  * @sa uiAction_t
120  */
121 typedef union {
122 	int integer;
123 	float number;
124 	const char* constString;
125 	void* data;
126 	const void* constData;
127 } uiTerminalActionData_t;
128 
129 /**
130  * @brief Atomic element to store UI scripts
131  * The parser use this atom to translate script action into many trees of actions.
132  * One function is one tree, and when we call this function, the tree is executed.
133  *
134  * An atom can be a command, an operator, or a value:
135  * <ul> <li>Each command (EA_ACTION like EA_CALL, EA_CMD...) uses its own action structure. It can sometimes use child actions, or can be a leaf.</li>
136  * <li> Operators (EA_OPERATOR_*) use binary tree structure (left and right operands), else are unary.</li>
137  * <li> A value (EA_VALUE_*) is a terminal action (a leaf).</li></ul>
138  * @todo FIXME Merge terminal and nonTerminal, this way is finally stupid. Left can be terminal and right can be non terminal,
139  * then the structure make non sens and can create hidden bugs.
140  */
141 typedef struct uiAction_s {
142 	/**
143 	 * @brief Define the type of the element, it can be a command, an operator, or a value
144 	 * @sa ea_t
145 	 */
146 	short type;
147 
148 	/**
149 	 * @brief Some operators/commands/values can use it to store info about the content
150 	 */
151 	short subType;
152 
153 	/**
154 	 * @brief Stores data about the action
155 	 */
156 	union {
157 		/**
158 		 * @brief Stores a none terminal action (a command or an operator)
159 		 * @note The action type must be a command or an operator
160 		 */
161 		struct {
162 			struct uiAction_s* left;
163 			struct uiAction_s* right;
164 		} nonTerminal;
165 
166 		/**
167 		 * @brief Stores a terminal action (a value, which must be a leaf in the tree)
168 		 * @note The action type must be value (or sometimes a command)
169 		 * @todo Define the "sometimes"
170 		 */
171 		struct {
172 			uiTerminalActionData_t d1;
173 			uiTerminalActionData_t d2;
174 		} terminal;
175 	} d;
176 
177 	/**
178 	 * @brief Next element in the action list
179 	 */
180 	struct uiAction_s* next;
181 } uiAction_t;
182 
183 /* prototype */
184 struct uiNode_t;
185 struct cvar_s;
186 
187 /** @brief Type for uiAction_t
188  * It also contain type about type (for example EA_BINARYOPERATOR)
189  * @sa uiAction_t
190  */
191 typedef struct uiValue_s {
192 	uiActionType_t type;	/** Subset of action type to identify the value */
193 	union {
194 		int integer;
195 		float number;
196 		char* string;
197 		struct cvar_s* cvar;
198 		uiNode_t* node;
199 	} value;
200 } uiValue_t;
201 
202 /**
203  * @brief Contain the context of the calling of a function
204  */
205 typedef struct uiCallContext_s {
206 	/** node owning the action */
207 	uiNode_t* source;
208 	/** is the function can use param from command line */
209 	bool useCmdParam;
210 	linkedList_t* params;
211 	int paramNumber;
212 	int varPosition;
213 	int varNumber;
214 } uiCallContext_t;
215 
216 void UI_ExecuteEventActions(uiNode_t* source, const uiAction_t* firstAction);
217 void UI_ExecuteConFuncActions(uiNode_t* source, const uiAction_t* firstAction);
218 void UI_ExecuteEventActionsEx (uiNode_t* source, const uiAction_t* firstAction, linkedList_t* params);
219 bool UI_IsInjectedString(const char* string);
220 void UI_FreeStringProperty(void* pointer);
221 const char* UI_GenInjectedString(const char* input, bool addNewLine, const uiCallContext_t* context);
222 int UI_GetActionTokenType(const char* token, int group);
223 uiValue_t* UI_GetVariable (const uiCallContext_t* context, int relativeVarId);
224 
225 void UI_PoolAllocAction(uiAction_t** action, int type, const void* data);
226 uiAction_t* UI_AllocStaticCommandAction(const char* command);
227 void UI_InitActions(void);
228 void UI_AddListener(uiNode_t* node, const value_t* property, uiNode_t const* functionNode);
229 void UI_RemoveListener(uiNode_t* node, const value_t* property, uiNode_t* functionNode);
230 
231 const char* UI_GetParam(const uiCallContext_t* context, int paramID);
232 int UI_GetParamNumber(const uiCallContext_t* context);
233