cloud

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  29 Posts :: 1 Stories :: 4 Comments :: 0 Trackbacks

常用链接

留言簿(5)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

    最近在游戏编程精粹4(Game Programming Gems 4)中看到了对于XDS的介绍,解开了我对于XML低效的困惑。也许在小型的XML应用中不觉得,但是在大数据量的应用中XML的速度甚至无法和普通的.ini相提并论。首先让我们来看看XDS是什么吧。
 
    XDS技术由DSD和XDS两种文件格式组成。前者跟XSD相似,后者跟XML相似,只不过这两种格式都是二进制的。正是采用了二进制格式,无论是在体积还是在速度上XDS的性能比XML都有明显的提升。目前支持XDS的免费库主要有XDSToolkit,现在可以下载到1.03版本。这是一个开源项目,解压后我们可以看到它由两个工具一个API包组成,另外还附一个例子。两个工具的名字分别叫做xdsConvert和xdsMakeSchema,分别是用来进行XML和XDS相互转换,以及生成DSD文件的。
 
    在一个C/C++项目中,我们经常需要用struct定义一系列数据结构。xdsMakeSchema就可以通过输入数据结构的定义文件.h来生成DSD和相应的c头文件。在一个项目的初期,你可能需要用XML编辑器来编写这个项目所需要的XML数据,然后在程序中通过XDSLiteAPI来进行解析。这套API有两个Paser,一个服务于XML,另一个服务于XDS。当你的项目完全可以自动生成XML的时候就可以由XML转向XDS了。游戏编程精粹中解释的很详细,这边就说说需要注意的地方了。
 
    要利用API对XDS进行解析需要以下步骤:
①     以struct定义的C数据类型
②     XDS的数据类型定义,可以在DSD中,也可以在程序中定义
③     回调函数的编写,主要是XDS_PROCESSNODE函数
 
以该工具包附带的Powerup为例,struct看起来是这样的:
struct PowerUp_t {
    char szName[10];        // display name
    char szImage[16];       // image file name
 
    // health increase/decrease (-128 to 127)
    signed char   iHealth;
 
    // temporary abilities/penalties
    // (value is duration in seconds)
    unsigned char iInvulnerability;
    unsigned char iFastMove;
    unsigned char iHighJump;
    unsigned char iStunPlayer;
 
    // extra life (count)
    unsigned char iLifeUp;
};
 
// global power-up definition cache
extern struct PowerUp_t *g_PowerUps;
 
可以通过使用xdsMakeSchema来生成dsd,同时生成的xxxx_dsd.h只是为了免除将dsd文件读入内存,查看它的内容就可以看到它定义了一个dsd数组:
// XDS DSD literal -- use this in calls to xdsInit()
//
#ifdef DEFINE_DSD
 
const unsigned char XDSDSD_Powerups[216] = {
    0x58, 0x44, 0x53, 0x21, 0x30, 0x33, 。。。
};
 
#else
 
extern const unsigned char XDSDSD_Powerups[216];
 
#endif
 
 
// XDS DSD IDs -- use these in implementation of XDS_PROCESSNODE()
//
#define XDS_Powerups_Powerup    0x0100 // Record
#define XDS_Powerups_PowerUp_t 0x0101 // Type
#define XDS_Powerups__xdsType1 0x0102 // Type
#define XDS_Powerups_g_PowerUps 0x0103 // Element
 
同时还定义了一些常量,这些常量在解析xds中会用到。
除了在dsd中对于xds格式的定义之外,我们还可以在main.cpp中看到程序内的定义:
#ifdef XDS_SUPPORT_DEFTYPE
void regDsd(struct xdsHandle *hXds)
{
    // Register my types (test only)
 
    xdsDefRecord(hXds, "Powerup", 2);
 
    unsigned short iStructType = xdsDefStructType(hXds, "PowerUp_t");
    xdsDefStructField(hXds, iStructType, "szName", XDS_TYPE_CHAR, 10);
    xdsDefStructField(hXds, iStructType, "szImage", XDS_TYPE_CHAR, 16);
    xdsDefStructField(hXds, iStructType, "iHealth", XDS_TYPE_CHAR, 0);
xdsDefStructField(hXds, iStructType, "iInvulnerability", XDS_TYPE_BYTE, 0);
    xdsDefStructField(hXds, iStructType, "iFastMove", XDS_TYPE_BYTE, 0);
    xdsDefStructField(hXds, iStructType, "iHighJump", XDS_TYPE_BYTE, 0);
    xdsDefStructField(hXds, iStructType, "iStunPlayer", XDS_TYPE_BYTE, 0);
    xdsDefStructField(hXds, iStructType, "iLifeUp", XDS_TYPE_BYTE, 0);
 
    xdsDefStructDone(hXds, iStructType);
    unsigned short iArrayType = xdsDefArrayType(hXds, "_xdsType1", iStructType, 0, 2);
 
    xdsDefElement(hXds, "g_PowerUps", iArrayType, 0);
}
#endif
 
    注意:交叉使用dsd定义和程序定义容易造成一个错误,就是在程序和dsd可能在定义的时候冲突,数据类型冲突,或者数据长度冲突,从而导致程序的崩溃。附带的例子中程序定义数据类型如下:
#ifdef XDS_SUPPORT_DEFTYPE
void regDsd(struct xdsHandle *hXds)
{
    // Register my types (test only)
 
    xdsDefRecord(hXds, "Powerup", 4);
 
    unsigned short iStructType = xdsDefStructType(hXds, "PowerUp_t");
    xdsDefStructField(hXds, iStructType, "szName", XDS_TYPE_CHAR, 10);
    xdsDefStructField(hXds, iStructType, "szImage", XDS_TYPE_CHAR, 16);
    xdsDefStructField(hXds, iStructType, "iHealth", XDS_TYPE_CHAR, 0);
    xdsDefStructField(hXds, iStructType, "iInvulnerability", XDS_TYPE_BYTE, 0);
    xdsDefStructField(hXds, iStructType, "iFastMove", XDS_TYPE_BYTE, 0);
    xdsDefStructField(hXds, iStructType, "iHighJump", XDS_TYPE_BYTE, 0);
    xdsDefStructField(hXds, iStructType, "iStunPlayer", XDS_TYPE_BYTE, 0);
    xdsDefStructField(hXds, iStructType, "iLifeUp", XDS_TYPE_BYTE, 0);
 
    xdsDefStructDone(hXds, iStructType);
    unsigned short iArrayType = xdsDefArrayType(hXds, "_xdsType1", iStructType, 0, 2);
 
    xdsDefElement(hXds, "g_PowerUps", iArrayType, 0);
}
#endif
 
要是在生成dsd时用参数-r Powerup:2而这里用xdsDefRecord(hXds, "Powerup", 4)的话就会导致冲突。
posted on 2008-11-12 15:34 cloud 阅读(725) 评论(0)  编辑 收藏 引用 所属分类: c++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理