预处理程序指令
预处理程序指令是特殊的语言结构,这种结构能控制脚本解析器的行为。所有的UnigineScript指令以#标记打头且每个指令应在自己所在的行上。请注意指令开始的字符串末尾无分号。
预处理程序宏命令
macro(宏命令) 是一段给予名称的代码片段。无论什么时候使用此名称,其都会被宏命令的内容所取代。
此处存在一套预定义的宏命令:
- __VERSION__ - UnigineScript解析器版本,例如"1.82"。
- NDEBUG - 二进制不包含调试信息 (发布版本)。
- _WIN32 - 目标操作系统是Windows系统。
- _LINUX - 目标操作系统是Linux系统。
- _ARCH_X86 - 目标操作系统版本是32位。
- _ARCH_X64 - 目标操作系统版本是64位。
- HAS_BLOB - Blob 类在核心库内可用。
- HAS_BOUNDS - 与Bounds相关的类在核心库内可用。
- HAS_DIRECT3D11 - 使用Direct3D 11 渲染系统创建二进制。
- HAS_JOYSTICK - 使用操纵杆的支持创建二进制。
- HAS_IMAGE - Image 类 在核心库内可用。
- HAS_MESH - Mesh类 在核心库内可用。
- HAS_MEMORY -使用Unigine内存管理系统创建二进制。
- HAS_OPENAL - 使用OpenAL音响系统创建二进制。
- HAS_OPENGL - 使用OpenGL 渲染系统创建二进制。
- HAS_OPENEXR - 使用对OpenEXR格式的支持创建二进制。
- HAS_PATH - Path 类在核心库内可用。
- HAS_REGEXP - Regexp 类在核心库内可用。
- HAS_SIXAXIS - 使用对手柄控制器的支持创建二进制。
- HAS_SOCKET - Socket类在核心库内可用。
- HAS_XAUDIO2 - 使用XAudio2音响系统创建二进制。
- HAS_XML - Xml 类在核心库内可用。
- HAS_XPAD360 - 使用对Xbox 360手柄创建二进制。
- HAS_ELLIPSOID - 二进制得以创建包括椭球体功能。
- USE_DOUBLE - 使用对双精度坐标的支持创建二进制。
- USE_GEODETICS - 使用对大地测量学的支持创建二进制。
- USE_MICROPROFILE - 使用对微表面的支持创建二进制。
这些宏命令可作为条件使用也可与逻辑运算符结合使用,比如:() 用于分组 ||表示或 && 表示和。
#include
加载所给文件的内容。
语法: #include "someFile"
此处someFile 为目标文件名。
#include "foo.h"
foo(); // 如果foo.h包括foo()的声明就OK
为了避免冲突,推荐以下列方式将文件包括在内:
#ifndef __MYLIB_H__
#define __MYLIB_H__
#include "myLib.h"
#endif /* __MYLIB_H__ */
#define
设置标识符和字符序列,通过此序列标识符将在程序文本中被取代。
语法: #define macro_name character_sequence
此处macro_name 将被 character_sequence在代码中的任意位置处被替换。请注意character_sequence 不应包含有空格(除开必须包含在双引号内的字符串)也可被省略。
#define LEFT 1
#define RIGHT 0
log.message("%d %d\n",LEFT,RIGHT);
// 输出为: 1 0
#define FRUIT "an apple"
log.message("%s\n", "today we will eat "FRUIT);
// 输出为: today we will eat an apple
// 参数也得到支持:
#define saturate(v) clamp(v,0.0,1.0)
在#define指令内, 可使用#文字运算符。其会将宏参数转换成字符串常数。此运算符可在模版内进行使用。
语法: #macro_arg
此处的macro_arg是宏指令的参数。
#define assert(EXP) { if(EXP) { } else { throw("Assertion: '%s'",#EXP); } }
也看参看模板。
#undef
移除上一个定义的标识符。
语法: #undef macro_name
#define LOCK
#undef LOCK
#ifndef LOCK
log.message("unlocked\n"); // 将执行此代码片段
#endif
#ifdef
如果使用#define定义了某个所给标识符,可根据条件执行某些代码片段。
语法:
#ifdef macro_name
some_code #endif
如果未定义macro_name接下来会执行 some_code。
#define LOCK1
#define LOCK2
#ifdef (LOCK1 && LOCK2) || LOCK3
log.message("locked\n"); // 将执行此代码片段
#endif
#ifndef
如果未使用#define或 #undef 定义某个所给标识符,可根据条件执行某些代码片段。
语法:
#ifndef macro_name
some_code #endif
如果未定义macro_name 接下来会执行some_code 。
#define LOCK
#ifndef LOCK
log.message("unlocked\n"); // 此代码片段不会得到执行
#endif
#else
创造#ifdef 和 #ifndef 编译指示的替代。
语法:
#ifdef macro_name some_code
#else some_more_code
#endif
此处可使用#ifndef而不是#ifdef(而条件的意义会发生倒转)。如果第一个条件为假,接下来从第一个#else位置处向上直到第一个#endif位置处之间的代码都将得到执行。
#define SOUND_ENABLE
#ifdef SOUND_ENABLE
log.message("sound enabled\n");
#else
log.message("sound disabled\n"); // 将执行此代码片段
#endif
#elif
为#ifdef 和#ifndef标记创建条件性的替换。
语法:
#ifdef macro_name1 some_code1
#elif macro_name2 some_code2
#endif
此处可使用 #ifndef 而不是#ifdef(而条件的意义会发生倒转)。如果macro_name1为假,接下来会测试macro_name2。如果为真,那么从当前#elif 起一直向上直到第一个#elif,#else 或 #endif处之间的代码将得以执行。
#define VAL2
#ifdef VAL1
log.message("it is 1\n");
#elif VAL2
log.message("it is 2\n"); //将执行此代码片段
#elif VAL3
log.message("it is 3\n");
#endif
#endif
标志着条件编译结束。
#error
终结脚本的执行并将日志消息记录到控制台及系统日志文件中。
语法: #error message_text
#error I don't want to execute it any longer
#warning
将日志消息记录到控制台及系统日志文件中,脚本会继续执行。
语法: #warning message_text
#warning There is somethings wrong in here
#warn_long
如果在脚本中使用了长整型变量,编译动作会被终止并将错误信息记录到控制台和系统日志文件中。
#warn_double
如果在脚本中使用了双精度型变量, 编译动作会被终止并将错误信息记录到控制台和系统日志文件中。