Ogre引擎源码——String

    技术2022-05-20  40

    Ogre引擎中有关String的文件如下(只列出头文件)

    OgreString.h

    OgreStringConverter.h

    OgreStringInterface.h

    OgreStringVector.h

    OgreUTFString.h

     

    涉及String的基础操作,只做一些简单的介绍。本文的重点会解读下StringInterface部分代码。

     

    (1)OgreString.h

    这个头文件中定义了一个String基础类StringUtil,其中的函数都是公共静态的。简单整理如下 

     

    function namefunctional descriptiontrim剔除字符串两侧空格和tabsplit根据所给字符对字符串进行分割tokenise可以根据给定的两个字符对字符串进行分割toLowerCase将字符串转成小写toUpperCase将字符串转成大写startsWith检验字符串是否是以给定的字符串开头endsWith检验字符串是否是以给定的字符串结尾standardisePath将字符串转换成标准路径splitFilename分割字符串中的路径名和文件名splitFullFilename分割字符串中的路径名、文件名和文件后缀splitBaseFilename分割字符串中的文件名和文件后缀match检验字符串是否符合给定通配符replaceAll替换字符串某部分

     

    这部分中应用了大量的std::string的find、find_last_of、substr等,也用到了泛型算法replace等。这些都是书写STL的基础内容,可以通过阅读代码来温习这些内容。

     

    (2)OgreStringConverter.h

    这个头文件同样也是很简单的。定义了一个转换类StringConverter用来将Ogre中的基础类型与String之间进行转换。同样,所有的函数都是公共静态函数。

    函数可以分为两大类,toString和parseXX。顾名思义,前者通过重载方式,将不同基础类型转换为String;后者则是通过定义不同的函数(函数名中的XX为相应的基础类型),将String转换为XX类型。

    这部分的代码基本都是重复性的内容,不再赘述更多。主要的思想是通过stringstream类进行转换。

     

    (3)OgreStringInterface.h

    这个部分需要认真解读一下。

    StringInterface类的作用是将类中的属性与String之间建立相互转换的关系。由于属性可以不一定是String类型,这个类就为设置和读取这些属性定义了统一的接口。

    这个文件中包含了一下类或者枚举定义。

    类(枚举)名称功能概述ParameterType(enum)枚举所有参数的类型ParameterDef定义一个具体参数,如名称,描述,类型等ParamCommand转换命令抽象类,定义转换方式和获取方式ParamDictionary维护一个类名与该类属性的转换命令StringInterface维护所有类名的Dictionanry

     

    他们之间的关系UML图如下

     

    其实这里应用了设计模式用的COMMAND模式,抽象类ParamCommand是整个过程的关键类。ParamCommand类中定义了两个接口doSet和doGet,相应的类只需要接口继承这个ParamCommand类,实现针对自己类属性的设置和读取操作。这样就完成了定制类自身的属性设置命令类。其余的List、Map等类都是对参数类型和不同类的属性命令类进行管理的数据结构。

     

    在这里举个例子来说明。

    例子:OgreFont.h 的 Font class

    Font类定义了5个成员变量

    /// The type of font FontType mType; /// Source of the font (either an image name or a truetype font) String mSource; /// Size of the truetype font, in points Real mTtfSize; /// Resolution (dpi) of truetype font uint mTtfResolution; /// Max distance to baseline of this (truetype) font int mTtfMaxBearingY;

    针对这5个成员变量,分别声明一个ParamCommand的子类

    static CmdType msTypeCmd; static CmdSource msSourceCmd; static CmdSize msSizeCmd; static CmdResolution msResolutionCmd; static CmdCodePoints msCodePointsCmd;

    以CmdType定义为例

     class CmdType : public ParamCommand { public: String doGet(const void* target) const; void doSet(void* target, const String& val); };

    注意这些变量声明为静态,是因为这些命令类为class共有的。

     

    然后在第一次调用Font构造函数时向dictionary注册这些cmd

    if (createParamDictionary("Font")) { ParamDictionary* dict = getParamDictionary(); dict->addParameter( ParameterDef("type", "'truetype' or 'image' based font", PT_STRING),&msTypeCmd); dict->addParameter( ParameterDef("source", "Filename of the source of the font.", PT_STRING),&msSourceCmd); dict->addParameter( ParameterDef("size", "True type size", PT_REAL),&msSizeCmd); dict->addParameter( ParameterDef("resolution", "True type resolution", PT_UNSIGNED_INT),&msResolutionCmd); dict->addParameter( ParameterDef("code_points", "Add a range of code points", PT_STRING),&msCodePointsCmd); }

    然后只要通过StringInterface的getParameter和setParameter函数就可以调用注册的cmd进行读取和设定Font类的成员变量了。

     

    (4) OgreStringVector.h

    这个文件中只有两句typedef,这个比较简单。

    typedef vector<String>::type StringVector; typedef SharedPtr<StringVector> StringVectorPtr;

     

     

    (5)OgreUTFString.h

    这个头文件涉及字符编码,最近正在梳理这方面的知识,等理清后再补上。


    最新回复(0)