28 #include "../client.h"
42 #include "../../shared/parse.h"
43 #include "../cl_language.h"
46 static bool UI_ParseProperty(
void*
object,
const value_t* property,
const char* objectName,
const char** text,
const char** token);
99 if ((name[0] >=
'0' && name[0] <=
'9') || name[0] ==
'-' || name[0] ==
'.')
110 if ((name[0] >=
'A' && name[0] <=
'Z') || name[0] ==
'_') {
111 bool onlyUpperCase =
true;
112 while (*name !=
'\0') {
113 if ((name[0] >=
'A' && name[0] <=
'Z') || name[0] ==
'_' || (name[0] >=
'0' && name[0] <=
'9')) {
120 return onlyUpperCase;
131 if ((name[0] >=
'a' && name[0] <=
'z') || (name[0] >=
'A' && name[0] <=
'Z') || name[0] ==
'_') {
132 bool onlyUpperCase =
true;
133 while (*name !=
'\0') {
134 if (name[0] >=
'a' && name[0] <=
'z') {
135 onlyUpperCase =
false;
136 }
else if ((name[0] >=
'0' && name[0] <=
'9') || (name[0] >=
'A' && name[0] <=
'Z') || name[0] ==
'_') {
143 return !onlyUpperCase;
156 const value_t* current = propertyList;
157 while (current->
string !=
nullptr) {
176 if (result ==
nullptr)
192 if (result ==
nullptr)
208 size = strlen(
string) + 1;
211 if (result ==
nullptr)
240 if (property ==
nullptr) {
249 if (sprite ==
nullptr) {
255 action->
d.
terminal.d2.integer =
property->type;
258 const int baseType =
property->type &
V_UI_MASK;
259 if (baseType != 0 && baseType !=
V_UI_CVAR) {
266 action->
d.
terminal.d2.integer =
property->type;
282 assert((*token)[0] ==
'*');
290 Com_Printf(
"UI_ParseSetAction: Cvar or Node property expected. Type '%i' found\n", type);
299 Com_Printf(
"UI_ParseSetAction: Assign sign '=' expected between variable and value. '%s' found in node %s.\n", *token,
UI_GetPath(node));
324 if (actionList ==
nullptr)
329 localAction->
d.
terminal.d1.data = actionList;
367 if (expression ==
nullptr)
371 Com_Printf(
"UI_ParseCallAction: \"call\" keyword only support pathnode and pathproperty (node: %s)\n",
UI_GetPath(node));
379 if ((*token)[0] ==
'\0')
395 if (param ==
nullptr) {
396 Com_Printf(
"UI_ParseCallAction: problem with the %i parameter\n", paramID);
399 if (lastParam ==
nullptr)
402 lastParam->
next = param;
413 Com_Printf(
"UI_ParseCallAction: Invalidate end of 'call' after param %i\n", paramID);
429 const char* errhead =
"UI_ParseActionList: unexpected end of file (in event)";
434 lastAction =
nullptr;
435 firstAction =
nullptr;
438 if ((*token)[0] !=
'{') {
439 Com_Printf(
"UI_ParseActionList: token \"{\" expected, but \"%s\" found (in event) (node: %s)\n", *token,
UI_GetPath(node));
452 if ((*token)[0] ==
'}')
457 if (type ==
EA_NULL && (*token)[0] ==
'*')
462 Com_Printf(
"UI_ParseActionList: unknown token \"%s\" ignored (in event) (node: %s)\n", *token,
UI_GetPath(node));
470 lastAction->
next = action;
472 firstAction = action;
476 switch (action->
type) {
503 if (expression ==
nullptr)
507 Com_Printf(
"UI_ParseActionList: \"delete\" keyword only support cvarname (node: %s)\n",
UI_GetPath(node));
517 Com_Printf(
"UI_ParseActionList: 'elif' must be set after an 'if' or an 'elif' (node: %s)\n",
UI_GetPath(node));
528 if (expression ==
nullptr)
538 switch (action->
type) {
546 Com_Printf(
"UI_ParseActionList: block expected after \"while\" (node: %s)\n",
UI_GetPath(node));
549 Com_Printf(
"UI_ParseActionList: cannot determine statement type (node: %s)\n",
UI_GetPath(node));
562 if (expression ==
nullptr) {
570 Com_Printf(
"UI_ParseActionList: Node property expected. Type '%x' found\n", type);
580 Com_Printf(
"UI_ParseActionList: block expected after \"forchildin\" (node: %s)\n",
UI_GetPath(node));
589 Com_Printf(
"UI_ParseActionList: 'else' must be set after an 'if' or an 'elif' (node: %s)\n",
UI_GetPath(node));
613 assert((*token)[0] ==
'}');
616 if (firstAction ==
nullptr) {
632 if ((*token)[0] !=
'{') {
633 Com_Printf(
"UI_ParseExcludeRect: node with bad excluderect ignored (node \"%s\")\n",
UI_GetPath(node));
647 }
else if (
Q_streq(*token,
"size")) {
653 }
while ((*token)[0] !=
'}');
656 if (newRect ==
nullptr) {
657 Com_Printf(
"UI_ParseExcludeRect: ui hunk memory exceeded.");
671 uiAction_t** action = &Com_GetValue<uiAction_t*>(node, event);
672 for (; *action; action = &(*action)->
next) {}
675 *token =
Com_EParse(text, errhead, node->name);
679 if ((*token)[0] !=
'{') {
685 if (*action ==
nullptr)
689 assert((*token)[0] ==
'}');
698 static bool UI_ParseProperty (
void*
object,
const value_t* property,
const char* objectName,
const char** text,
const char** token)
700 const char* errhead =
"UI_ParseProperty: unexpected end of file (object";
701 static const char* notWellFormedValue =
"UI_ParseProperty: \"%s\" is not a well formed node name (it must be quoted, uppercase const, a number, or prefixed with '*')\n";
704 const int specialType =
property->type &
V_UI_MASK;
710 switch (specialType) {
713 *token =
Com_EParse(text, errhead, objectName);
723 char*
const target = Com_GetValue<char[]>(object, property);
724 const char* translatableToken = *token;
725 assert(property->
size);
726 if (translatableToken[0] ==
'_')
739 *token =
Com_EParse(text, errhead, objectName);
752 assert((*token)[0] !=
'*');
756 Com_Printf(
"UI_ParseProperty: Value '%s' is too long (key %s)\n", *token, property->
string);
770 *token =
Com_EParse(text, errhead, objectName);
779 if ((*token)[0] ==
'*') {
785 if (strlen(*token) >
MAX_VAR - 1) {
786 Com_Printf(
"UI_ParseProperty: Value '%s' is too long (key %s)\n", *token, property->
string);
803 Com_Printf(
"UI_ParseProperty: Value '%s' is too long (key %s)\n", *token, property->
string);
818 switch ((
int)property->
type) {
833 *token =
Com_EParse(text, errhead, objectName);
837 uiSprite_t const*& sprite = Com_GetValue<uiSprite_t const*>(object, property);
840 Com_Printf(
"UI_ParseProperty: sprite '%s' not found (object %s)\n", *token, objectName);
847 *token =
Com_EParse(text, errhead, objectName);
851 uiAction_t*& expression = Com_GetValue<uiAction_t*>(object, property);
860 *token =
Com_EParse(text, errhead, objectName);
864 int& dataId = Com_GetValue<int>(object, property);
867 Com_Printf(
"UI_ParseProperty: Could not find shared data ID '%s' (%s@%s)\n",
868 *token, objectName, property->
string);
875 Com_Printf(
"UI_ParseProperty: unknown property type '%d' (0x%X) (%s@%s)\n",
882 Com_Printf(
"UI_ParseProperties: unknown property type '%d' (0x%X) (%s@%s)\n",
897 if (*action ==
nullptr)
900 return (*token)[0] ==
'}';
922 const char* errhead =
"UI_ParseNodeProperties: unexpected end of file (node";
923 bool nextTokenAlreadyRead =
false;
925 if ((*token)[0] !=
'{')
926 nextTokenAlreadyRead =
true;
933 if (!nextTokenAlreadyRead) {
938 nextTokenAlreadyRead =
false;
942 if ((*token)[0] ==
'}')
949 Com_Printf(
"UI_ParseNodeProperties: unknown property \"%s\", node ignored (node %s)\n",
957 Com_Printf(
"UI_ParseNodeProperties: Problem with parsing of node property '%s@%s'. See upper\n",
982 if ((*token)[0] !=
'{') {
987 if ((*token)[0] !=
'{') {
988 Com_Printf(
"UI_ParseNodeBody: node doesn't have body, token '%s' read (node \"%s\")\n", *token,
UI_GetPath(node));
1004 if ((*token)[0] ==
'{') {
1016 while ((*token)[0] !=
'}') {
1022 if (*text ==
nullptr)
1030 while ((*token)[0] !=
'}') {
1036 if (*text ==
nullptr)
1048 assert((*token)[0] ==
'}');
1070 if (behaviour ==
nullptr && component ==
nullptr) {
1071 Com_Printf(
"UI_ParseNode: node behaviour/component '%s' doesn't exist (%s)\n", *token,
UI_GetPath(parent));
1080 Com_Printf(
"UI_ParseNode: \"%s\" is not a well formed node name ([a-zA-Z_][a-zA-Z0-9_]*)\n", *token);
1084 Com_Printf(
"UI_ParseNode: \"%s\" is a reserved token, we can't call a node with it\n", *token);
1095 const uiBehaviour_t* test = (behaviour !=
nullptr) ? behaviour : (component !=
nullptr) ? component->
behaviour :
nullptr;
1104 else if (component) {
1105 node =
UI_CloneNode(component,
nullptr,
true, *token,
true);
1136 const char* errhead =
"UI_ParseUIModel: unexpected end of file (names ";
1141 Com_Printf(
"UI_ParseUIModel: menu_model \"%s\" with same name found, second ignored\n", name);
1146 Com_Printf(
"UI_ParseUIModel: Max UI models reached\n");
1162 if (!*text || token[0] !=
'{') {
1163 Com_Printf(
"UI_ParseUIModel: Model \"%s\" without body ignored\n", model->
id);
1175 if (token[0] ==
'}')
1180 Com_Printf(
"UI_ParseUIModel: unknown token \"%s\" ignored (UI model %s)\n", token, name);
1189 if (model->
next !=
nullptr)
1190 Sys_Error(
"UI_ParseUIModel: second 'need' token found in model %s", name);
1193 Com_Printf(
"Could not find UI model %s\n", token);
1223 assert(token[0] ==
'{');
1230 if (*text ==
nullptr)
1233 if (token[0] ==
'}')
1238 Com_Printf(
"UI_ParseIcon: unknown options property: '%s' - ignore it\n", token);
1245 Com_Printf(
"UI_ParseIcon: Parsing for sprite '%s'. See upper\n", icon->
name);
1263 const char* errhead =
"UI_ParseComponent: unexpected end of file (component";
1266 if (!
Q_streq(type,
"component")) {
1267 Com_Error(
ERR_FATAL,
"UI_ParseComponent: \"component\" expected but \"%s\" found.\n", type);
1273 Com_Printf(
"UI_ParseNode: \"%s\" is not a well formed node name ([a-zA-Z_][a-zA-Z0-9_]*)\n", name);
1277 Com_Printf(
"UI_ParseNode: \"%s\" is a reserved token, we can't call a node with it\n", name);
1282 if (text ==
nullptr)
1286 if (!
Q_streq(token,
"extends")) {
1287 Com_Printf(
"UI_ParseComponent: \"extends\" expected but \"%s\" found (component %s)\n", token, name);
1291 if (text ==
nullptr)
1303 if (inheritedComponent) {
1305 component =
UI_CloneNode(inheritedComponent,
nullptr,
true, name,
false);
1307 Com_Printf(
"UI_ParseComponent: node behaviour/component '%s' doesn't exists (component %s)\n", token, name);
1338 const char* errhead =
"UI_ParseWindow: unexpected end of file (window";
1343 if (!
Q_streq(type,
"window")) {
1349 Com_Printf(
"UI_ParseWindow: \"%s\" is not a well formed node name ([a-zA-Z_][a-zA-Z0-9_]*)\n", name);
1353 Com_Printf(
"UI_ParseWindow: \"%s\" is a reserved token, we can't call a node with it (node \"%s\")\n", name, name);
1365 Com_Printf(
"UI_ParseWindow: %s \"%s\" with same name found, second ignored\n", type, name);
1377 if (
Q_streq(token,
"extends")) {
1381 if (superWindow ==
nullptr)
1382 Sys_Error(
"Could not get the super window \"%s\"", token);
1383 window =
UI_CloneNode(superWindow,
nullptr,
true, name,
true);
1387 window->
root = window;
1422 if (token[0] ==
'\0')
1425 Sys_Error(
"UI_GetReferenceString: unknown reference %s", token);
1438 if (
char const*
const token =
Q_strstart((
char const*)ref,
"*")) {
1439 if (token[0] ==
'\0')
1442 if (
char const*
const cvar =
Q_strstart(token,
"cvar:")) {
1448 return *(
const float*) ref;
vec4_t * UI_AllocStaticColor(int count)
Allocate a color into the UI static memory.
const char * Com_GetLastParseError(void)
bool UI_IsInjectedString(const char *string)
Test if a string use an injection syntax.
uiAction_t * UI_AllocStaticAction(void)
Allocate an action.
static bool UI_ParseFunction(uiNode_t *node, const char **text, const char **token)
struct uiAction_s::@14::@16 terminal
Stores a terminal action (a value, which must be a leaf in the tree)
void Sys_Error(const char *error,...)
void * UI_AllocHunkMemory(size_t size, int align, bool reset)
QGL_EXTERN GLint GLenum type
uiAction_t * UI_AllocStaticStringCondition(const char *description)
Allocate and initialize an expression according to a string.
void UI_InsertWindow(uiNode_t *window)
Add a new window to the list of all windows.
valueTypes_t
possible values for parsing functions
static uiNode_t * UI_ParseNode(uiNode_t *parent, const char **text, const char **token, const char *errhead)
parse a node
bool UI_ParseComponent(const char *type, const char *name, const char **text)
Parse a component.
#define V_BASETYPEMASK
Allow to add extra bit into the type.
void UI_UpdateRoot(uiNode_t *node, uiNode_t *newRoot)
uiNode_t * UI_GetComponent(const char *name)
Searches all components for the specified one.
float * UI_AllocStaticFloat(int count)
Allocate a float into the UI static memory.
bool UI_TokenIsReserved(const char *name)
uiBehaviour_t * behaviour
static bool UI_TokenIsValue(const char *name, bool isQuoted)
uiExcludeRect_t * firstExcludeRect
static bool UI_ParseProperty(void *object, const value_t *property, const char *objectName, const char **text, const char **token)
Parse a property value.
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
void Com_Printf(const char *const fmt,...)
void UI_AppendNode(uiNode_t *const parent, uiNode_t *newNode)
add a node at the end of the node child
uiModel_t models[UI_MAX_MODELS]
uiAction_t * UI_ParseExpression(const char **text)
union uiAction_s::@14 d
Stores data about the action.
struct uiAction_s * onClick
uiAction_t actions[UI_MAX_ACTIONS]
const value_t * UI_GetPropertyFromBehaviour(const uiBehaviour_t *behaviour, const char *name)
Get a property from a behaviour or his inheritance It use a dichotomic search.
bool UI_ParseUIModel(const char *name, const char **text)
parses the models.ufo and all files where UI models (menu_model) are defined
#define Mem_PoolStrDupTo(in, out, pool, tagNum)
int UI_GetDataIDByName(const char *name)
Return a dataId by name.
Internal data use by the UI package.
C interface to allow to access to cpp node code.
void Com_Error(int code, const char *fmt,...)
uiNode_t * UI_AllocNode(const char *name, const char *type, bool isDynamic)
Allocate a node into the UI memory.
uiSprite_t * UI_AllocStaticSprite(const char *name)
Allocate an sprite to the UI static memory.
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
struct uiAction_s::@14::@15 nonTerminal
Stores a none terminal action (a command or an operator)
int UI_GetActionTokenType(const char *token, int group)
return an action type from a token, and a group
#define STRUCT_MEMORY_ALIGN
bool UI_TokenIsName(const char *name, bool isQuoted)
float Cvar_GetValue(const char *varName)
Returns the float value of a cvar.
#define Vector4Set(v, r, g, b, a)
static char const *const reservedTokens[]
reserved token preventing calling a node with it
const char * Com_MacroExpandString(const char *text)
Expands strings with cvar values that are dereferenced by a '*cvar'.
void UI_Node_Loaded(uiNode_t *node)
bool UI_ParseWindow(const char *type, const char *name, const char **text)
Parse a window.
const char * UI_GetPath(const uiNode_t *node)
Return a path from a window to a node.
const char * Com_EParse(const char **text, const char *errhead, const char *errinfo, char *target, size_t size)
Parsing function that prints an error message when there is no text in the buffer.
char const * Q_strstart(char const *str, char const *start)
Matches the start of a string.
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Data and interface to share data.
const char * UI_GetReferenceString(const uiNode_t *const node, const char *ref)
#define Q_strcasecmp(a, b)
static bool UI_ParseSetAction(uiNode_t *node, uiAction_t *action, const char **text, const char **token, const char *errhead)
Parser for setter command.
Atomic structure used to define most of the UI.
resultStatus_t Com_ParseValue(void *base, const char *token, valueTypes_t type, int ofs, size_t size, size_t *writtenBytes)
Parse a value from a string.
static uiAction_t * UI_ParseActionList(uiNode_t *node, const char **text, const char **token)
Parse actions and return action list.
uiNode_t * windows[UI_MAX_WINDOWS]
bool UI_ParseSprite(const char *name, const char **text)
float UI_GetReferenceFloat(const uiNode_t *const node, const void *ref)
Returns the value of the reference variable.
uiNode_t * UI_CloneNode(const uiNode_t *node, uiNode_t *newWindow, bool recursive, const char *newName, bool isDynamic)
Clone a node.
uiModel_t * UI_GetUIModel(const char *modelName)
Returns pointer to UI model.
const value_t ui_spriteProperties[]
uiNode_t * UI_GetWindow(const char *name)
Searches all windows for the specified one.
const value_t * UI_FindPropertyByName(const value_t *propertyList, const char *name)
Find a value_t by name into a array of value_t.
int Com_EParseValue(void *base, const char *token, valueTypes_t type, int ofs, size_t size)
static bool UI_ParseNodeBody(uiNode_t *node, const char **text, const char **token, const char *errhead)
Read a node body.
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
const char * CL_Translate(const char *t)
static bool UI_ParseEventProperty(uiNode_t *node, const value_t *event, const char **text, const char **token, const char *errhead)
uiNode_t * UI_GetNode(const uiNode_t *node, const char *name)
Search a child node by given name.
node behaviour, how a node work
uiBehaviour_t * UI_GetNodeBehaviour(const char *name)
Return a node behaviour by name.
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
bool UI_InitRawActionValue(uiAction_t *action, uiNode_t *node, const value_t *property, const char *string)
Com_TokenType_t Com_GetType(const char **data_p)
Get the current token type.
struct uiAction_s * next
Next element in the action list.
static bool UI_ParseCallAction(uiNode_t *node, uiAction_t *action, const char **text, const char **token, const char *errhead)
Parser for call command.
void * Com_AlignPtr(const void *memory, valueTypes_t type)
Align a memory to use a natural address for the data type we will write.
void Com_UnParseLastToken(void)
Put back the last token into the parser The next call of Com_Parse will return the same token again...
#define Mem_PoolStrDup(in, pool, tagNum)
Model that have more than one part (top and down part of an aircraft)
bool UI_Node_IsFunction(uiNode_t const *node)
uiSprite_t * UI_GetSpriteByName(const char *name)
Return an sprite by is name.
static const value_t uiModelProperties[]
valid properties for a UI model definition
struct uiExcludeRect_s * next
QGL_EXTERN int GLboolean GLfloat * v
static bool UI_ParseNodeProperties(uiNode_t *node, const char **text, const char **token)
parse all sequencial properties into a block
char * UI_AllocStaticString(const char *string, int size)
Allocate a string into the UI static memory.
static bool UI_ParseExcludeRect(uiNode_t *node, const char **text, const char **token, const char *errhead)
short type
Define the type of the element, it can be a command, an operator, or a value.
Atomic element to store UI scripts The parser use this atom to translate script action into many tree...
void UI_InsertComponent(uiNode_t *component)
Add a new component to the list of all components.