This page has been translated automatically.
Getting Started
Migrating to UNIGINE 2.0
C++ API Migration
UnigineScript
Core Library
Engine Library
Node-Related Classes
GUI-Related Classes
Plugins Library
High-Level Systems
Samples
Usage Examples
C++ API
API Reference
Integration Samples
Usage Examples
C++ Plugins
Warning! This version of documentation is OUTDATED, as it describes an older SDK version! Please switch to the documentation for the latest SDK version.
Warning! This version of documentation describes an old SDK version which is no longer supported! Please upgrade to the latest SDK version.

Preprocessor Directives

Preprocessor directives are special language constructs, which control the script interpreter behavior. All UnigineScript directives begin with the # sign, and each of them should be on its own line. Note that there are no semicolons at the end of strings that start with directives.

Preprocessor Macros

A macro is a fragment of code which has been given a name. Whenever the name is used, it is replaced by the contents of the macro.

There is a pre-defined set of macros:

  • _VERSION_ - the UnigineScript interpreter version, for example, "1.82"
  • NDEBUG - the binary does not contain debugging information (release build)
  • _WIN32 - target operating system is Windows
  • _LINUX - target operating system is Linux
  • _MACOS - target operating system is Mac OS X
  • HAS_BUFFER - Buffer Class is available in the Core Library
  • HAS_DIRECT3D11 - the binary is built with Direct3D 11 rendering system
  • HAS_DIRECT3D119 - the binary is built with Direct3D 11 feature level 9 rendering system
  • HAS_JOYSTICK - the binary is built with support of a joystick
  • HAS_IMAGE - Image Class is available in the Core Library
  • HAS_MEMORY - the binary is built with Unigine memory management system
  • HAS_OPENAL - the binary is built with OpenAL sound system
  • HAS_OPENGL - the binary is built with OpenGL rendering system
  • HAS_REGEXP - Regexp Class is available in the Core Library
  • HAS_SOCKET - Socket Class is available in the Core Library
  • HAS_XAUDIO21 - the binary is built with XAudio2 sound system
  • HAS_XML - Xml Class is available in the Core Library
  • HAS_XPAD360 - the binary is built with support of Xbox 360 gamepad
  • USE_DOUBLE - the binary is built with support of double precision of coordinates
  • USE_MICROPROFILE - the binary is built with support of microprofile.
  • USE_OPENGL_DEBUG_OUTPUT - the binary is built with the OpenGL debug context.

These macros can be used as conditions and combined with logical operators: () for grouping, || for "or", && for "and".

#include

Loads the content of a given file.

Syntax: #include "someFile"

Here someFile is a target file name.

Source code (UnigineScript)
#include "foo.h"
foo(); // ok if foo.h contains declaration of foo()

To avoid conflicts it's recommended to include files this way:

Source code (UnigineScript)
#ifndef __MYLIB_H__
#define __MYLIB_H__

#include "myLib.h"

#endif /* __MYLIB_H__ */
In this case, even being included several times from different places, "myLib.h" will not cause re-definition collisions, since it will be compiled only once.

Notice
If a base path to the file is not mentioned in the #include pragma, the file will be searched among all files located in the data directory of the project.

#define

Sets an identifier and a character sequence, by which the identifier will be replaced in the text of the program.

Syntax: #define macro_name character_sequence

Here macro_name will be replaced with character_sequence everywhere in the code. Note that character_sequence shouldn't contain spaces (except for strings, which must be enclosed in double quotes) and can be omitted.

Source code (UnigineScript)
#define LEFT 1
#define RIGHT 0

log.message("%d %d\n",LEFT,RIGHT);
// Output: 1 0

#define FRUIT "an apple"

log.message("%s\n", "today we will eat "FRUIT);
// Output: today we will eat an apple

// arguments are also supported:
#define saturate(v) clamp(v,0.0,1.0)

// literal # operator:
#define assert(EXP) { if(EXP) { } else { throw("Assertion: '%s'",#EXP); } }

See also Templates.

#

Turns a macro argument into a string constant.

Syntax: #macro_arg

Here macro_arg is an argument to a macro.

Source code (UnigineScript)
#define assert(EXP) { if(EXP) { } else { throw("Assertion: '%s'",#EXP); } }

See also: #define .

#undef

Removes a previously defined identifier.

Syntax: #undef macro_name

Source code (UnigineScript)
#define LOCK
#undef LOCK

#ifndef LOCK
log.message("unlocked\n"); // this fragment will be executed
#endif

#ifdef

Allows executing some fragment of code conditionally, if a given identifier is defined with #define.

Syntax: #ifdef macro_name
some_code #endif

If macro_name is defined, then some_code will be executed.

Source code (UnigineScript)
#define LOCK1
#define LOCK2

#ifdef (LOCK1 && LOCK2) || LOCK3
log.message("locked\n"); // this fragment will be executed
#endif

#ifndef

Allows executing some fragment of code conditionally, if a given identifier is not defined with #define or is undefined with #undef.

Syntax: #ifndef macro_name
some_code #endif

If macro_name is not defined, then some_code will be executed.

Source code (UnigineScript)
#define LOCK

#ifndef LOCK
log.message("unlocked\n"); // this fragment will NOT be executed
#endif

#else

Creates an alternative to #ifdef and #ifndef pragmas.

Syntax: #ifdef macro_name some_code
#else some_more_code
#endif

Here #ifndef can be used instead of #ifdef (however, the meaning of the condition will be reversed). If the first condition is false, then everything from the first #else up to the first #endif will be executed.

Source code (UnigineScript)
#define SOUND_ENABLE

#ifdef SOUND_ENABLE
log.message("sound enabled\n");
#else
log.message("sound disabled\n"); // this fragment will be executed
#endif

#elif

Create a conditional alternative to #ifdef and #ifndef pragmas.

Syntax: #ifdef macro_name1 some_code1
#elif macro_name2 some_code2
#endif

Here #ifndef can be used instead of #ifdef (however, the meaning of the condition will be reversed). If macro_name1 is false, then macro_name2 is tested, and if it's true, everything from this #elif up to the first #elif, #else or #endif will be executed.

Source code (UnigineScript)
#define VAL2

#ifdef VAL1
log.message("it is 1\n");
#elif VAL2
log.message("it is 2\n"); // this fragment will be executed
#elif VAL3
log.message("it is 3\n");
#endif

#endif

Marks an end of conditional compilation.

#error

Terminates execution of the script and logs the message into the console and a system log file.

Syntax: #error message_text

Source code (UnigineScript)
#error I don't want to execute it any longer

#warning

Logs the message into the console and a system log file, the script continues execution.

Syntax: #warning message_text

Source code (UnigineScript)
#warning There is somethings wrong in here

#warn_long

Terminates compilation if a variable of a long type is used in the script, and logs the error message into the console and a system log file.

#warn_double

Terminates compilation if a variable of a double type is used in the script, and logs the error message into the console and a system log file.

#no_long

Replaces all variables of a long type in the script with an int type.

#no_double

Replaces all variables of a double type in the script with a float type.

Last update: 2017-07-03
Build: ()