mirror of https://github.com/axmolengine/axmol.git
Merge branch 'develop' of git://github.com/cocos2d/cocos2d-x into header_dependency_fixes
This commit is contained in:
commit
a74a524eaa
|
@ -4,6 +4,7 @@ cocos2d-x-3.0final ?.? ?
|
|||
[NEW] Console: added the 'textures', 'fileutils dump' and 'config' commands
|
||||
[NEW] GLCache: glActiveTexture() is cached with GL::activeTexture(). All code MUST call the cached version in order to work correctly
|
||||
[NEW] Label: Uses a struct of TTF configuration for Label::createWithTTF to reduce parameters and make this interface more easily to use.
|
||||
[NEW] Label: Integrates LabelAtlas into new Label.
|
||||
[NEW] Renderer: Added BatchCommand. This command is not "batchable" with other commands, but improves performance in about 10%
|
||||
|
||||
[FIX] CocoStudio: TestColliderDetector in ArmatureTest can't work.
|
||||
|
|
|
@ -1 +1 @@
|
|||
88c095bbe123ab56df3f7870692c6631f4464c8d
|
||||
e1e5a1169e92834330092c45165660c6cbd03609
|
|
@ -1 +1 @@
|
|||
b6abaf935c97f8f1dc7a7179e54850928015b442
|
||||
1fa58d8cba77ef923c83d2860d5511d28dad6c27
|
|
@ -47,6 +47,7 @@ CCEventListenerTouch.cpp \
|
|||
CCEventMouse.cpp \
|
||||
CCEventTouch.cpp \
|
||||
CCFont.cpp \
|
||||
CCFontCharMap.cpp \
|
||||
CCFontAtlas.cpp \
|
||||
CCFontAtlasCache.cpp \
|
||||
CCFontAtlasFactory.cpp \
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "CCFontFNT.h"
|
||||
#include "CCFontFreeType.h"
|
||||
#include "CCFontCharMap.h"
|
||||
#include "edtaa3func.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
@ -116,6 +117,21 @@ Font* Font::createWithFNT(const std::string& fntFilePath)
|
|||
return FontFNT::create(fntFilePath);
|
||||
}
|
||||
|
||||
Font* Font::createWithCharMap(const std::string& plistFile)
|
||||
{
|
||||
return FontCharMap::create(plistFile);
|
||||
}
|
||||
|
||||
Font* Font::createWithCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap)
|
||||
{
|
||||
return FontCharMap::create(texture,itemWidth,itemHeight,startCharMap);
|
||||
}
|
||||
|
||||
Font* Font::createWithCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap)
|
||||
{
|
||||
return FontCharMap::create(charMapFile,itemWidth,itemHeight,startCharMap);
|
||||
}
|
||||
|
||||
unsigned char * Font::makeDistanceMap( unsigned char *img, unsigned int width, unsigned int height)
|
||||
{
|
||||
unsigned int pixelAmount = (width + 2 * DistanceMapSpread) * (height + 2 * DistanceMapSpread);
|
||||
|
|
|
@ -44,6 +44,10 @@ public:
|
|||
// create the font
|
||||
static Font* createWithTTF(const std::string& fntName, int fontSize, GlyphCollection glyphs, const char *customGlyphs);
|
||||
static Font* createWithFNT(const std::string& fntFilePath);
|
||||
|
||||
static Font * createWithCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
|
||||
static Font * createWithCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
|
||||
static Font * createWithCharMap(const std::string& plistFile);
|
||||
|
||||
static unsigned char * makeDistanceMap(unsigned char *img, unsigned int width, unsigned int height);
|
||||
void setDistanceFieldEnabled(bool distanceFieldEnabled);
|
||||
|
|
|
@ -71,6 +71,65 @@ FontAtlas * FontAtlasCache::getFontAtlasFNT(const std::string& fontFileName)
|
|||
return tempAtlas;
|
||||
}
|
||||
|
||||
FontAtlas * FontAtlasCache::getFontAtlasCharMap(const std::string& plistFile)
|
||||
{
|
||||
std::string atlasName = generateFontName(plistFile, 0, GlyphCollection::CUSTOM,false);
|
||||
FontAtlas *tempAtlas = _atlasMap[atlasName];
|
||||
|
||||
if ( !tempAtlas )
|
||||
{
|
||||
tempAtlas = FontAtlasFactory::createAtlasFromCharMap(plistFile);
|
||||
if (tempAtlas)
|
||||
_atlasMap[atlasName] = tempAtlas;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempAtlas->retain();
|
||||
}
|
||||
|
||||
return tempAtlas;
|
||||
}
|
||||
|
||||
FontAtlas * FontAtlasCache::getFontAtlasCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap)
|
||||
{
|
||||
char tmp[30];
|
||||
sprintf(tmp,"name:%u_%d_%d_%d",texture->getName(),itemWidth,itemHeight,startCharMap);
|
||||
std::string atlasName = generateFontName(tmp, 0, GlyphCollection::CUSTOM,false);
|
||||
FontAtlas *tempAtlas = _atlasMap[atlasName];
|
||||
|
||||
if ( !tempAtlas )
|
||||
{
|
||||
tempAtlas = FontAtlasFactory::createAtlasFromCharMap(texture,itemWidth,itemHeight,startCharMap);
|
||||
if (tempAtlas)
|
||||
_atlasMap[atlasName] = tempAtlas;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempAtlas->retain();
|
||||
}
|
||||
|
||||
return tempAtlas;
|
||||
}
|
||||
|
||||
FontAtlas * FontAtlasCache::getFontAtlasCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap)
|
||||
{
|
||||
std::string atlasName = generateFontName(charMapFile, 0, GlyphCollection::CUSTOM,false);
|
||||
FontAtlas *tempAtlas = _atlasMap[atlasName];
|
||||
|
||||
if ( !tempAtlas )
|
||||
{
|
||||
tempAtlas = FontAtlasFactory::createAtlasFromCharMap(charMapFile,itemWidth,itemHeight,startCharMap);
|
||||
if (tempAtlas)
|
||||
_atlasMap[atlasName] = tempAtlas;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempAtlas->retain();
|
||||
}
|
||||
|
||||
return tempAtlas;
|
||||
}
|
||||
|
||||
std::string FontAtlasCache::generateFontName(const std::string& fontFileName, int size, GlyphCollection theGlyphs, bool useDistanceField)
|
||||
{
|
||||
std::string tempName(fontFileName);
|
||||
|
|
|
@ -35,17 +35,18 @@
|
|||
NS_CC_BEGIN
|
||||
|
||||
class CC_DLL FontAtlasCache
|
||||
{
|
||||
|
||||
{
|
||||
public:
|
||||
|
||||
static FontAtlas * getFontAtlasTTF(const std::string& fontFileName, int size, GlyphCollection glyphs, const char *customGlyphs = 0, bool useDistanceField = false);
|
||||
static FontAtlas * getFontAtlasFNT(const std::string& fontFileName);
|
||||
|
||||
static FontAtlas * getFontAtlasCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
|
||||
static FontAtlas * getFontAtlasCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
|
||||
static FontAtlas * getFontAtlasCharMap(const std::string& plistFile);
|
||||
|
||||
static bool releaseFontAtlas(FontAtlas *atlas);
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
static std::string generateFontName(const std::string& fontFileName, int size, GlyphCollection theGlyphs, bool useDistanceField);
|
||||
static std::unordered_map<std::string, FontAtlas *> _atlasMap;
|
||||
};
|
||||
|
|
|
@ -60,4 +60,46 @@ FontAtlas * FontAtlasFactory::createAtlasFromFNT(const std::string& fntFilePath)
|
|||
}
|
||||
}
|
||||
|
||||
FontAtlas * FontAtlasFactory::createAtlasFromCharMap(const std::string& plistFile)
|
||||
{
|
||||
Font *font = Font::createWithCharMap(plistFile);
|
||||
|
||||
if(font)
|
||||
{
|
||||
return font->createFontAtlas();
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
FontAtlas * FontAtlasFactory::createAtlasFromCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap)
|
||||
{
|
||||
Font *font = Font::createWithCharMap(texture,itemWidth,itemHeight,startCharMap);
|
||||
|
||||
if(font)
|
||||
{
|
||||
return font->createFontAtlas();
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
FontAtlas * FontAtlasFactory::createAtlasFromCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap)
|
||||
{
|
||||
Font *font = Font::createWithCharMap(charMapFile,itemWidth,itemHeight,startCharMap);
|
||||
|
||||
if(font)
|
||||
{
|
||||
return font->createFontAtlas();
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -39,6 +39,10 @@ public:
|
|||
|
||||
static FontAtlas * createAtlasFromTTF(const std::string& fntFilePath, int fontSize, GlyphCollection glyphs, const char *customGlyphs = 0, bool useDistanceField = false);
|
||||
static FontAtlas * createAtlasFromFNT(const std::string& fntFilePath);
|
||||
|
||||
static FontAtlas * createAtlasFromCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
|
||||
static FontAtlas * createAtlasFromCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
|
||||
static FontAtlas * createAtlasFromCharMap(const std::string& plistFile);
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013 Zynga Inc.
|
||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "CCFontCharMap.h"
|
||||
#include "CCFontAtlas.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
FontCharMap * FontCharMap::create(const std::string& plistFile)
|
||||
{
|
||||
std::string pathStr = FileUtils::getInstance()->fullPathForFilename(plistFile);
|
||||
std::string relPathStr = pathStr.substr(0, pathStr.find_last_of("/"))+"/";
|
||||
|
||||
ValueMap dict = FileUtils::getInstance()->getValueMapFromFile(pathStr.c_str());
|
||||
|
||||
CCASSERT(dict["version"].asInt() == 1, "Unsupported version. Upgrade cocos2d version");
|
||||
|
||||
std::string textureFilename = relPathStr + dict["textureFilename"].asString();
|
||||
|
||||
unsigned int width = dict["itemWidth"].asInt() / CC_CONTENT_SCALE_FACTOR();
|
||||
unsigned int height = dict["itemHeight"].asInt() / CC_CONTENT_SCALE_FACTOR();
|
||||
unsigned int startChar = dict["firstChar"].asInt();
|
||||
|
||||
Texture2D *tempTexture = Director::getInstance()->getTextureCache()->addImage(textureFilename);
|
||||
if (!tempTexture)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FontCharMap *tempFont = new FontCharMap(tempTexture,width,height,startChar);
|
||||
|
||||
if (!tempFont)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
tempFont->autorelease();
|
||||
return tempFont;
|
||||
}
|
||||
|
||||
FontCharMap* FontCharMap::create(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap)
|
||||
{
|
||||
Texture2D *tempTexture = Director::getInstance()->getTextureCache()->addImage(charMapFile);
|
||||
|
||||
if (!tempTexture)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FontCharMap *tempFont = new FontCharMap(tempTexture,itemWidth,itemHeight,startCharMap);
|
||||
|
||||
if (!tempFont)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
tempFont->autorelease();
|
||||
return tempFont;
|
||||
}
|
||||
|
||||
FontCharMap* FontCharMap::create(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap)
|
||||
{
|
||||
FontCharMap *tempFont = new FontCharMap(texture,itemWidth,itemHeight,startCharMap);
|
||||
|
||||
if (!tempFont)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
tempFont->autorelease();
|
||||
return tempFont;
|
||||
}
|
||||
|
||||
FontCharMap::~FontCharMap()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Size * FontCharMap::getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const
|
||||
{
|
||||
if (!text)
|
||||
return 0;
|
||||
|
||||
outNumLetters = cc_wcslen(text);
|
||||
|
||||
if (!outNumLetters)
|
||||
return 0;
|
||||
|
||||
Size *sizes = new Size[outNumLetters];
|
||||
if (!sizes)
|
||||
return 0;
|
||||
|
||||
int advance = _itemWidth * CC_CONTENT_SCALE_FACTOR();
|
||||
for (int c = 0; c < outNumLetters; ++c)
|
||||
{
|
||||
sizes[c].width = advance;
|
||||
}
|
||||
|
||||
return sizes;
|
||||
}
|
||||
|
||||
Rect FontCharMap::getRectForChar(unsigned short theChar) const
|
||||
{
|
||||
return _charRect;
|
||||
}
|
||||
|
||||
FontAtlas * FontCharMap::createFontAtlas()
|
||||
{
|
||||
FontAtlas *tempAtlas = new FontAtlas(*this);
|
||||
if (!tempAtlas)
|
||||
return nullptr;
|
||||
|
||||
Size s = _texture->getContentSize();
|
||||
|
||||
int itemsPerColumn = (int)(s.height / _itemHeight);
|
||||
int itemsPerRow = (int)(s.width / _itemWidth);
|
||||
|
||||
tempAtlas->setCommonLineHeight(_itemHeight);
|
||||
|
||||
FontLetterDefinition tempDefinition;
|
||||
tempDefinition.textureID = 0;
|
||||
tempDefinition.anchorX = 0.5f;
|
||||
tempDefinition.anchorY = 0.5f;
|
||||
tempDefinition.offsetX = 0.0f;
|
||||
tempDefinition.offsetY = 0.0f;
|
||||
tempDefinition.validDefinition = true;
|
||||
tempDefinition.width = _itemWidth;
|
||||
tempDefinition.height = _itemHeight;
|
||||
|
||||
int charId = _mapStartChar;
|
||||
float itemWidthInPixels = _itemWidth * CC_CONTENT_SCALE_FACTOR();
|
||||
float itemHeightInPixels = _itemHeight * CC_CONTENT_SCALE_FACTOR();
|
||||
for (int row = 0; row < itemsPerColumn; ++row)
|
||||
{
|
||||
for (int col = 0; col < itemsPerRow; ++col)
|
||||
{
|
||||
tempDefinition.letteCharUTF16 = charId;
|
||||
|
||||
tempDefinition.U = _itemWidth * col;
|
||||
tempDefinition.V = _itemHeight * row;
|
||||
|
||||
tempAtlas->addLetterDefinition(tempDefinition);
|
||||
charId++;
|
||||
}
|
||||
}
|
||||
|
||||
tempAtlas->addTexture(*_texture,0);
|
||||
|
||||
return tempAtlas;
|
||||
}
|
||||
|
||||
NS_CC_END
|
|
@ -0,0 +1,65 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013 Zynga Inc.
|
||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _CCFontCharMap_h_
|
||||
#define _CCFontCharMap_h_
|
||||
|
||||
#include "cocos2d.h"
|
||||
#include "CCFont.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
class FontCharMap : public Font
|
||||
{
|
||||
public:
|
||||
static FontCharMap * create(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
|
||||
static FontCharMap * create(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
|
||||
static FontCharMap * create(const std::string& plistFile);
|
||||
|
||||
virtual Size* getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const override;
|
||||
virtual Rect getRectForChar(unsigned short theChar) const override;
|
||||
virtual FontAtlas *createFontAtlas() override;
|
||||
|
||||
protected:
|
||||
FontCharMap(Texture2D* texture,int itemWidth, int itemHeight, int startCharMap) :
|
||||
_texture(texture),_itemWidth(itemWidth),_itemHeight(itemHeight),_mapStartChar(startCharMap),_charRect(0,0,itemWidth,itemHeight){}
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
virtual ~FontCharMap();
|
||||
|
||||
private:
|
||||
Texture2D* _texture;
|
||||
int _mapStartChar;
|
||||
int _itemWidth;
|
||||
int _itemHeight;
|
||||
|
||||
Rect _charRect;
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
||||
#endif /* defined(_CCFontCharMap_h_) */
|
|
@ -98,6 +98,93 @@ Label* Label::createWithBMFont(const std::string& bmfontFilePath, const std::str
|
|||
}
|
||||
}
|
||||
|
||||
Label* Label::createWithCharMap(const std::string& plistFile)
|
||||
{
|
||||
Label *ret = new Label();
|
||||
|
||||
if (!ret)
|
||||
return nullptr;
|
||||
|
||||
if (ret->setCharMap(plistFile))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete ret;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Label* Label::createWithCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap)
|
||||
{
|
||||
Label *ret = new Label();
|
||||
|
||||
if (!ret)
|
||||
return nullptr;
|
||||
|
||||
if (ret->setCharMap(texture,itemWidth,itemHeight,startCharMap))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete ret;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Label* Label::createWithCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap)
|
||||
{
|
||||
Label *ret = new Label();
|
||||
|
||||
if (!ret)
|
||||
return nullptr;
|
||||
|
||||
if (ret->setCharMap(charMapFile,itemWidth,itemHeight,startCharMap))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete ret;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Label::setCharMap(const std::string& plistFile)
|
||||
{
|
||||
FontAtlas *newAtlas = FontAtlasCache::getFontAtlasCharMap(plistFile);
|
||||
|
||||
if (!newAtlas)
|
||||
return false;
|
||||
|
||||
return initWithFontAtlas(newAtlas);
|
||||
}
|
||||
|
||||
bool Label::setCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap)
|
||||
{
|
||||
FontAtlas *newAtlas = FontAtlasCache::getFontAtlasCharMap(texture,itemWidth,itemHeight,startCharMap);
|
||||
|
||||
if (!newAtlas)
|
||||
return false;
|
||||
|
||||
return initWithFontAtlas(newAtlas);
|
||||
}
|
||||
|
||||
bool Label::setCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap)
|
||||
{
|
||||
FontAtlas *newAtlas = FontAtlasCache::getFontAtlasCharMap(charMapFile,itemWidth,itemHeight,startCharMap);
|
||||
|
||||
if (!newAtlas)
|
||||
return false;
|
||||
|
||||
return initWithFontAtlas(newAtlas);
|
||||
}
|
||||
|
||||
Label::Label(FontAtlas *atlas, TextHAlignment alignment, bool useDistanceField,bool useA8Shader)
|
||||
: _reusedLetter(nullptr)
|
||||
, _commonLineHeight(0.0f)
|
||||
|
|
|
@ -62,12 +62,12 @@ typedef struct _ttfConfig
|
|||
const char *customGlyphs;
|
||||
bool distanceFieldEnabled;
|
||||
|
||||
_ttfConfig(const char* filePath,int fontSize = 36, const GlyphCollection& glyphs = GlyphCollection::NEHE,
|
||||
const char *customGlyphs = nullptr,bool useDistanceField = false)
|
||||
_ttfConfig(const char* filePath,int size = 36, const GlyphCollection& glyphCollection = GlyphCollection::NEHE,
|
||||
const char *customGlyphCollection = nullptr,bool useDistanceField = false)
|
||||
:fontFilePath(filePath)
|
||||
,fontSize(fontSize)
|
||||
,glyphs(glyphs)
|
||||
,customGlyphs(customGlyphs)
|
||||
,fontSize(size)
|
||||
,glyphs(glyphCollection)
|
||||
,customGlyphs(customGlyphCollection)
|
||||
,distanceFieldEnabled(useDistanceField)
|
||||
{}
|
||||
}TTFConfig;
|
||||
|
@ -82,10 +82,18 @@ public:
|
|||
|
||||
static Label* createWithBMFont(const std::string& bmfontFilePath, const std::string& text,const TextHAlignment& alignment = TextHAlignment::CENTER, int lineWidth = 0);
|
||||
|
||||
static Label * createWithCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
|
||||
static Label * createWithCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
|
||||
static Label * createWithCharMap(const std::string& plistFile);
|
||||
|
||||
bool setTTFConfig(const TTFConfig& ttfConfig);
|
||||
|
||||
bool setBMFontFilePath(const std::string& bmfontFilePath);
|
||||
|
||||
bool setCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
|
||||
bool setCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
|
||||
bool setCharMap(const std::string& plistFile);
|
||||
|
||||
bool setString(const std::string& text, const TextHAlignment& alignment = TextHAlignment::CENTER, float lineWidth = -1, bool lineBreakWithoutSpaces = false);
|
||||
|
||||
//only support for TTF
|
||||
|
|
|
@ -353,7 +353,7 @@ bool LabelTextFormatter::createStringSprites(LabelTextFormatProtocol *theLabel)
|
|||
|
||||
|
||||
Point fontPos = Point((float)nextFontPositionX + charXOffset + charRect.size.width * 0.5f + kerningAmount,
|
||||
(float)nextFontPositionY + yOffset - charRect.size.height * 0.5f);
|
||||
(float)nextFontPositionY + yOffset - charRect.size.height * 0.5f);
|
||||
|
||||
if( theLabel->recordLetterInfo(CC_POINT_PIXELS_TO_POINTS(fontPos),c,i) == false)
|
||||
{
|
||||
|
|
|
@ -71,6 +71,7 @@ set(COCOS2D_SRC
|
|||
CCFontDefinition.cpp
|
||||
CCFontFNT.cpp
|
||||
CCFontFreeType.cpp
|
||||
CCFontCharMap.cpp
|
||||
CCLabel.cpp
|
||||
CCLabelAtlas.cpp
|
||||
CCLabelBMFont.cpp
|
||||
|
|
|
@ -73,7 +73,7 @@ void ccArrayEnsureExtraCapacity(ccArray *arr, ssize_t extra)
|
|||
{
|
||||
while (arr->max < arr->num + extra)
|
||||
{
|
||||
CCLOG("cocos2d: ccCArray: resizing ccArray capacity from [%d] to [%d].",
|
||||
CCLOGINFO("cocos2d: ccCArray: resizing ccArray capacity from [%d] to [%d].",
|
||||
static_cast<int>(arr->max),
|
||||
static_cast<int>(arr->max*2));
|
||||
|
||||
|
|
|
@ -279,7 +279,7 @@ cc_utf8_get_char (const char * p)
|
|||
|
||||
unsigned short* cc_utf8_to_utf16(const char* str_old, int length/* = -1 */, int* rUtf16Size/* = nullptr */)
|
||||
{
|
||||
unsigned short len = cc_utf8_strlen(str_old, length);
|
||||
long len = cc_utf8_strlen(str_old, length);
|
||||
if (rUtf16Size != nullptr) {
|
||||
*rUtf16Size = len;
|
||||
}
|
||||
|
|
|
@ -248,6 +248,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
|
|||
<ClCompile Include="CCFontAtlas.cpp" />
|
||||
<ClCompile Include="CCFontAtlasCache.cpp" />
|
||||
<ClCompile Include="CCFontAtlasFactory.cpp" />
|
||||
<ClCompile Include="CCFontCharMap.cpp" />
|
||||
<ClCompile Include="CCFontDefinition.cpp" />
|
||||
<ClCompile Include="CCFontFNT.cpp" />
|
||||
<ClCompile Include="CCFontFreeType.cpp" />
|
||||
|
@ -429,6 +430,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
|
|||
<ClInclude Include="CCFontAtlas.h" />
|
||||
<ClInclude Include="CCFontAtlasCache.h" />
|
||||
<ClInclude Include="CCFontAtlasFactory.h" />
|
||||
<ClInclude Include="CCFontCharMap.h" />
|
||||
<ClInclude Include="CCFontDefinition.h" />
|
||||
<ClInclude Include="CCFontFNT.h" />
|
||||
<ClInclude Include="CCFontFreeType.h" />
|
||||
|
|
|
@ -601,6 +601,9 @@
|
|||
<ClCompile Include="renderer\CCBatchCommand.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CCFontCharMap.cpp">
|
||||
<Filter>label_nodes</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\physics\CCPhysicsBody.h">
|
||||
|
@ -1213,5 +1216,8 @@
|
|||
<ClInclude Include="renderer\CCBatchCommand.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CCFontCharMap.h">
|
||||
<Filter>label_nodes</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -122,6 +122,7 @@ Classes/PerformanceTest/PerformanceTextureTest.cpp \
|
|||
Classes/PerformanceTest/PerformanceTouchesTest.cpp \
|
||||
Classes/PerformanceTest/PerformanceLabelTest.cpp \
|
||||
Classes/PerformanceTest/PerformanceRendererTest.cpp \
|
||||
Classes/PerformanceTest/PerformanceContainerTest.cpp \
|
||||
Classes/PhysicsTest/PhysicsTest.cpp \
|
||||
Classes/RenderTextureTest/RenderTextureTest.cpp \
|
||||
Classes/RotateWorldTest/RotateWorldTest.cpp \
|
||||
|
|
|
@ -117,6 +117,7 @@ set(SAMPLE_SRC
|
|||
Classes/PerformanceTest/PerformanceTouchesTest.cpp
|
||||
Classes/PerformanceTest/PerformanceLabelTest.cpp
|
||||
Classes/PerformanceTest/PerformanceRendererTest.cpp
|
||||
Classes/PerformanceTest/PerformanceContainerTest.cpp
|
||||
Classes/PhysicsTest/PhysicsTest.cpp
|
||||
Classes/RenderTextureTest/RenderTextureTest.cpp
|
||||
Classes/RotateWorldTest/RotateWorldTest.cpp
|
||||
|
|
|
@ -67,6 +67,7 @@ static std::function<Layer*()> createFunctions[] =
|
|||
CL(LabelBMFontTestNew),
|
||||
CL(LabelTTFDistanceField),
|
||||
CL(LabelTTFDistanceFieldEffect),
|
||||
CL(LabelCharMapTest),
|
||||
CL(LabelCrashTest)
|
||||
};
|
||||
|
||||
|
@ -1244,6 +1245,52 @@ std::string LabelTTFDistanceFieldEffect::subtitle() const
|
|||
return "Testing effect base on DistanceField";
|
||||
}
|
||||
|
||||
LabelCharMapTest::LabelCharMapTest()
|
||||
{
|
||||
_time = 0.0f;
|
||||
|
||||
auto label1 = Label::createWithCharMap("fonts/tuffy_bold_italic-charmap.plist");
|
||||
addChild(label1, 0, kTagSprite1);
|
||||
label1->setPosition( Point(10,100) );
|
||||
label1->setOpacity( 200 );
|
||||
|
||||
auto label2 = Label::createWithCharMap("fonts/tuffy_bold_italic-charmap.plist");
|
||||
addChild(label2, 0, kTagSprite2);
|
||||
label2->setPosition( Point(10,160) );
|
||||
label2->setOpacity( 32 );
|
||||
|
||||
auto label3 = Label::createWithCharMap("fonts/tuffy_bold_italic-charmap.png", 48, 64, ' ');
|
||||
label3->setString("123 Test");
|
||||
addChild(label3, 0, kTagSprite3);
|
||||
label3->setPosition( Point(10,220) );
|
||||
|
||||
schedule(schedule_selector(LabelCharMapTest::step));
|
||||
}
|
||||
|
||||
void LabelCharMapTest::step(float dt)
|
||||
{
|
||||
_time += dt;
|
||||
char string[12] = {0};
|
||||
sprintf(string, "%2.2f Test", _time);
|
||||
|
||||
auto label1 = (Label*)getChildByTag(kTagSprite1);
|
||||
label1->setString(string);
|
||||
|
||||
auto label2 = (Label*)getChildByTag(kTagSprite2);
|
||||
sprintf(string, "%d", (int)_time);
|
||||
label2->setString(string);
|
||||
}
|
||||
|
||||
std::string LabelCharMapTest::title() const
|
||||
{
|
||||
return "New Label + char map file";
|
||||
}
|
||||
|
||||
std::string LabelCharMapTest::subtitle() const
|
||||
{
|
||||
return "Updating label should be fast.";
|
||||
}
|
||||
|
||||
LabelCrashTest::LabelCrashTest()
|
||||
{
|
||||
auto size = Director::getInstance()->getWinSize();
|
||||
|
|
|
@ -347,6 +347,22 @@ public:
|
|||
virtual std::string subtitle() const override;
|
||||
};
|
||||
|
||||
class LabelCharMapTest : public AtlasDemoNew
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(LabelCharMapTest);
|
||||
|
||||
LabelCharMapTest();
|
||||
|
||||
virtual std::string title() const override;
|
||||
virtual std::string subtitle() const override;
|
||||
|
||||
void step(float dt);
|
||||
|
||||
private:
|
||||
float _time;
|
||||
};
|
||||
|
||||
class LabelCrashTest : public AtlasDemoNew
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -0,0 +1,711 @@
|
|||
/*
|
||||
*
|
||||
*/
|
||||
#include "PerformanceContainerTest.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// Enable profiles for this file
|
||||
#undef CC_PROFILER_DISPLAY_TIMERS
|
||||
#define CC_PROFILER_DISPLAY_TIMERS() Profiler::getInstance()->displayTimers()
|
||||
#undef CC_PROFILER_PURGE_ALL
|
||||
#define CC_PROFILER_PURGE_ALL() Profiler::getInstance()->releaseAllTimers()
|
||||
|
||||
#undef CC_PROFILER_START
|
||||
#define CC_PROFILER_START(__name__) ProfilingBeginTimingBlock(__name__)
|
||||
#undef CC_PROFILER_STOP
|
||||
#define CC_PROFILER_STOP(__name__) ProfilingEndTimingBlock(__name__)
|
||||
#undef CC_PROFILER_RESET
|
||||
#define CC_PROFILER_RESET(__name__) ProfilingResetTimingBlock(__name__)
|
||||
|
||||
#undef CC_PROFILER_START_CATEGORY
|
||||
#define CC_PROFILER_START_CATEGORY(__cat__, __name__) do{ if(__cat__) ProfilingBeginTimingBlock(__name__); } while(0)
|
||||
#undef CC_PROFILER_STOP_CATEGORY
|
||||
#define CC_PROFILER_STOP_CATEGORY(__cat__, __name__) do{ if(__cat__) ProfilingEndTimingBlock(__name__); } while(0)
|
||||
#undef CC_PROFILER_RESET_CATEGORY
|
||||
#define CC_PROFILER_RESET_CATEGORY(__cat__, __name__) do{ if(__cat__) ProfilingResetTimingBlock(__name__); } while(0)
|
||||
|
||||
#undef CC_PROFILER_START_INSTANCE
|
||||
#define CC_PROFILER_START_INSTANCE(__id__, __name__) do{ ProfilingBeginTimingBlock( String::createWithFormat("%08X - %s", __id__, __name__)->getCString() ); } while(0)
|
||||
#undef CC_PROFILER_STOP_INSTANCE
|
||||
#define CC_PROFILER_STOP_INSTANCE(__id__, __name__) do{ ProfilingEndTimingBlock( String::createWithFormat("%08X - %s", __id__, __name__)->getCString() ); } while(0)
|
||||
#undef CC_PROFILER_RESET_INSTANCE
|
||||
#define CC_PROFILER_RESET_INSTANCE(__id__, __name__) do{ ProfilingResetTimingBlock( String::createWithFormat("%08X - %s", __id__, __name__)->getCString() ); } while(0)
|
||||
|
||||
static std::function<PerformanceContainerScene*()> createFunctions[] =
|
||||
{
|
||||
CL(TemplateVectorPerfTest),
|
||||
CL(ArrayPerfTest)
|
||||
};
|
||||
|
||||
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
|
||||
|
||||
enum {
|
||||
kTagInfoLayer = 1,
|
||||
|
||||
kTagBase = 20000,
|
||||
};
|
||||
|
||||
enum {
|
||||
kMaxNodes = 15000,
|
||||
kNodesIncrease = 500,
|
||||
};
|
||||
|
||||
static int g_curCase = 0;
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// ContainerBasicLayer
|
||||
//
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
ContainerBasicLayer::ContainerBasicLayer(bool bControlMenuVisible, int nMaxCases, int nCurCase)
|
||||
: PerformBasicLayer(bControlMenuVisible, nMaxCases, nCurCase)
|
||||
{
|
||||
}
|
||||
|
||||
void ContainerBasicLayer::showCurrentTest()
|
||||
{
|
||||
int nodes = ((PerformanceContainerScene*)getParent())->getQuantityOfNodes();
|
||||
|
||||
auto scene = createFunctions[_curCase]();
|
||||
|
||||
g_curCase = _curCase;
|
||||
|
||||
if (scene)
|
||||
{
|
||||
scene->initWithQuantityOfNodes(nodes);
|
||||
|
||||
Director::getInstance()->replaceScene(scene);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// PerformanceContainerScene
|
||||
//
|
||||
////////////////////////////////////////////////////////
|
||||
void PerformanceContainerScene::initWithQuantityOfNodes(unsigned int nNodes)
|
||||
{
|
||||
_type = 0;
|
||||
//srand(time());
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
|
||||
// Title
|
||||
auto label = LabelTTF::create(title().c_str(), "Arial", 40);
|
||||
addChild(label, 1, TAG_TITLE);
|
||||
label->setPosition(Point(s.width/2, s.height-32));
|
||||
label->setColor(Color3B(255,255,40));
|
||||
|
||||
// Subtitle
|
||||
std::string strSubTitle = subtitle();
|
||||
if(strSubTitle.length())
|
||||
{
|
||||
auto l = LabelTTF::create(strSubTitle.c_str(), "Thonburi", 16);
|
||||
addChild(l, 1, TAG_SUBTITLE);
|
||||
l->setPosition(Point(s.width/2, s.height-80));
|
||||
}
|
||||
|
||||
lastRenderedCount = 0;
|
||||
currentQuantityOfNodes = 0;
|
||||
quantityOfNodes = nNodes;
|
||||
|
||||
MenuItemFont::setFontSize(65);
|
||||
auto decrease = MenuItemFont::create(" - ", [&](Object *sender) {
|
||||
quantityOfNodes -= kNodesIncrease;
|
||||
if( quantityOfNodes < 0 )
|
||||
quantityOfNodes = 0;
|
||||
|
||||
updateQuantityLabel();
|
||||
updateQuantityOfNodes();
|
||||
updateProfilerName();
|
||||
CC_PROFILER_PURGE_ALL();
|
||||
srand(0);
|
||||
});
|
||||
decrease->setColor(Color3B(0,200,20));
|
||||
_decrease = decrease;
|
||||
|
||||
auto increase = MenuItemFont::create(" + ", [&](Object *sender) {
|
||||
quantityOfNodes += kNodesIncrease;
|
||||
if( quantityOfNodes > kMaxNodes )
|
||||
quantityOfNodes = kMaxNodes;
|
||||
|
||||
updateQuantityLabel();
|
||||
updateQuantityOfNodes();
|
||||
updateProfilerName();
|
||||
CC_PROFILER_PURGE_ALL();
|
||||
srand(0);
|
||||
});
|
||||
increase->setColor(Color3B(0,200,20));
|
||||
_increase = increase;
|
||||
|
||||
auto menu = Menu::create(decrease, increase, NULL);
|
||||
menu->alignItemsHorizontally();
|
||||
menu->setPosition(Point(s.width/2, s.height/2+15));
|
||||
addChild(menu, 1);
|
||||
|
||||
auto infoLabel = LabelTTF::create("0 nodes", "Marker Felt", 30);
|
||||
infoLabel->setColor(Color3B(0,200,20));
|
||||
infoLabel->setPosition(Point(s.width/2, s.height/2-15));
|
||||
addChild(infoLabel, 1, kTagInfoLayer);
|
||||
|
||||
auto menuLayer = new ContainerBasicLayer(true, MAX_LAYER, g_curCase);
|
||||
addChild(menuLayer);
|
||||
menuLayer->release();
|
||||
|
||||
printf("Size of Node: %lu\n", sizeof(Node));
|
||||
|
||||
int oldFontSize = MenuItemFont::getFontSize();
|
||||
MenuItemFont::setFontSize(24);
|
||||
|
||||
Vector<cocos2d::MenuItem *> toggleItems;
|
||||
|
||||
generateTestFunctions();
|
||||
|
||||
CCASSERT(!_testFunctions.empty(), "Should not be empty after generate test functions");
|
||||
|
||||
|
||||
for (const auto& f : _testFunctions)
|
||||
{
|
||||
toggleItems.pushBack(MenuItemFont::create(f.name));
|
||||
}
|
||||
|
||||
auto toggle = MenuItemToggle::createWithCallback([this](Object* sender){
|
||||
auto toggle = static_cast<MenuItemToggle*>(sender);
|
||||
this->_type = toggle->getSelectedIndex();
|
||||
auto label = static_cast<LabelTTF*>(this->getChildByTag(TAG_SUBTITLE));
|
||||
label->setString(StringUtils::format("Test '%s', See console", this->_testFunctions[this->_type].name));
|
||||
this->updateProfilerName();
|
||||
}, toggleItems);
|
||||
|
||||
toggle->setAnchorPoint(Point::ANCHOR_MIDDLE_LEFT);
|
||||
toggle->setPosition(VisibleRect::left());
|
||||
_toggle = toggle;
|
||||
|
||||
auto start = MenuItemFont::create("start", [this](Object* sender){
|
||||
auto director = Director::getInstance();
|
||||
auto sched = director->getScheduler();
|
||||
|
||||
CC_PROFILER_PURGE_ALL();
|
||||
sched->scheduleSelector(schedule_selector(PerformanceContainerScene::dumpProfilerInfo), this, 2, false);
|
||||
|
||||
this->unscheduleUpdate();
|
||||
this->scheduleUpdate();
|
||||
this->_startItem->setEnabled(false);
|
||||
this->_stopItem->setEnabled(true);
|
||||
this->_toggle->setEnabled(false);
|
||||
this->_increase->setEnabled(false);
|
||||
this->_decrease->setEnabled(false);
|
||||
});
|
||||
start->setAnchorPoint(Point::ANCHOR_MIDDLE_RIGHT);
|
||||
start->setPosition(VisibleRect::right() + Point(0, 40));
|
||||
_startItem = start;
|
||||
|
||||
auto stop = MenuItemFont::create("stop", [this](Object* sender){
|
||||
auto director = Director::getInstance();
|
||||
auto sched = director->getScheduler();
|
||||
|
||||
sched->unscheduleSelector(schedule_selector(PerformanceContainerScene::dumpProfilerInfo), this);
|
||||
|
||||
this->unscheduleUpdate();
|
||||
this->_startItem->setEnabled(true);
|
||||
this->_stopItem->setEnabled(false);
|
||||
this->_toggle->setEnabled(true);
|
||||
this->_increase->setEnabled(true);
|
||||
this->_decrease->setEnabled(true);
|
||||
});
|
||||
|
||||
stop->setEnabled(false);
|
||||
stop->setAnchorPoint(Point::ANCHOR_MIDDLE_RIGHT);
|
||||
stop->setPosition(VisibleRect::right() + Point(0, -40));
|
||||
_stopItem = stop;
|
||||
|
||||
auto menu2 = Menu::create(toggle, start, stop, NULL);
|
||||
menu2->setPosition(Point::ZERO);
|
||||
addChild(menu2);
|
||||
|
||||
MenuItemFont::setFontSize(oldFontSize);
|
||||
|
||||
updateQuantityLabel();
|
||||
updateQuantityOfNodes();
|
||||
updateProfilerName();
|
||||
}
|
||||
|
||||
std::string PerformanceContainerScene::title() const
|
||||
{
|
||||
return "No title";
|
||||
}
|
||||
|
||||
std::string PerformanceContainerScene::subtitle() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
void PerformanceContainerScene::updateQuantityLabel()
|
||||
{
|
||||
if( quantityOfNodes != lastRenderedCount )
|
||||
{
|
||||
auto infoLabel = static_cast<LabelTTF*>( getChildByTag(kTagInfoLayer) );
|
||||
char str[20] = {0};
|
||||
sprintf(str, "%u nodes", quantityOfNodes);
|
||||
infoLabel->setString(str);
|
||||
|
||||
lastRenderedCount = quantityOfNodes;
|
||||
}
|
||||
}
|
||||
|
||||
const char * PerformanceContainerScene::profilerName()
|
||||
{
|
||||
return _profilerName;
|
||||
}
|
||||
|
||||
void PerformanceContainerScene::updateProfilerName()
|
||||
{
|
||||
snprintf(_profilerName, sizeof(_profilerName)-1, "%s(%d)", testName(), quantityOfNodes);
|
||||
}
|
||||
|
||||
void PerformanceContainerScene::onExitTransitionDidStart()
|
||||
{
|
||||
Scene::onExitTransitionDidStart();
|
||||
|
||||
auto director = Director::getInstance();
|
||||
auto sched = director->getScheduler();
|
||||
|
||||
sched->unscheduleSelector(schedule_selector(PerformanceContainerScene::dumpProfilerInfo), this);
|
||||
}
|
||||
|
||||
void PerformanceContainerScene::onEnterTransitionDidFinish()
|
||||
{
|
||||
Scene::onEnterTransitionDidFinish();
|
||||
|
||||
auto director = Director::getInstance();
|
||||
auto sched = director->getScheduler();
|
||||
|
||||
CC_PROFILER_PURGE_ALL();
|
||||
sched->scheduleSelector(schedule_selector(PerformanceContainerScene::dumpProfilerInfo), this, 2, false);
|
||||
}
|
||||
|
||||
void PerformanceContainerScene::dumpProfilerInfo(float dt)
|
||||
{
|
||||
CC_PROFILER_DISPLAY_TIMERS();
|
||||
}
|
||||
|
||||
void PerformanceContainerScene::update(float dt)
|
||||
{
|
||||
_testFunctions[_type].func();
|
||||
}
|
||||
|
||||
void PerformanceContainerScene::updateQuantityOfNodes()
|
||||
{
|
||||
currentQuantityOfNodes = quantityOfNodes;
|
||||
}
|
||||
|
||||
const char* PerformanceContainerScene::testName()
|
||||
{
|
||||
return _testFunctions[_type].name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// TemplateVectorPerfTest
|
||||
//
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
void TemplateVectorPerfTest::generateTestFunctions()
|
||||
{
|
||||
auto createVector = [this](){
|
||||
Vector<Node*> ret;
|
||||
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
{
|
||||
auto node = Node::create();
|
||||
node->setTag(i);
|
||||
ret.pushBack(node);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
TestFunction testFunctions[] = {
|
||||
{ "pushBack", [=](){
|
||||
Vector<Node*> nodeVector;
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector.pushBack(Node::create());
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
{ "insert", [=](){
|
||||
Vector<Node*> nodeVector;
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector.insert(0, Node::create());
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
{ "replace", [=](){
|
||||
Vector<Node*> nodeVector = createVector();
|
||||
|
||||
srand(time(nullptr));
|
||||
ssize_t index = rand() % quantityOfNodes;
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector.replace(index, Node::create());
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
{ "getIndex", [=](){
|
||||
|
||||
Vector<Node*> nodeVector = createVector();
|
||||
Node* objToGet = nodeVector.at(quantityOfNodes/3);
|
||||
ssize_t index = 0;
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
index = nodeVector.getIndex(objToGet);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
|
||||
// Uses `index` to avoids `getIndex` invoking was optimized in release mode
|
||||
if (index == quantityOfNodes/3)
|
||||
{
|
||||
nodeVector.clear();
|
||||
}
|
||||
} } ,
|
||||
{ "find", [=](){
|
||||
Vector<Node*> nodeVector = createVector();
|
||||
Node* objToGet = nodeVector.at(quantityOfNodes/3);
|
||||
Vector<Node*>::iterator iter;
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
iter = nodeVector.find(objToGet);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
|
||||
// Uses `iter` to avoids `find` invoking was optimized in release mode
|
||||
if (*iter == objToGet)
|
||||
{
|
||||
nodeVector.clear();
|
||||
}
|
||||
|
||||
} } ,
|
||||
{ "at", [=](){
|
||||
Vector<Node*> nodeVector = createVector();
|
||||
Node* objToGet = nullptr;
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
objToGet = nodeVector.at(quantityOfNodes/3);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
|
||||
// Uses `objToGet` to avoids `at` invoking was optimized in release mode
|
||||
if (nodeVector.getIndex(objToGet) == quantityOfNodes/3)
|
||||
{
|
||||
nodeVector.clear();
|
||||
}
|
||||
} } ,
|
||||
{ "contains", [=](){
|
||||
Vector<Node*> nodeVector = createVector();
|
||||
Node* objToGet = nodeVector.at(quantityOfNodes/3);
|
||||
|
||||
bool ret = false;
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
ret = nodeVector.contains(objToGet);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
|
||||
// Uses `ret` to avoids `contains` invoking was optimized in release mode
|
||||
if (ret)
|
||||
{
|
||||
nodeVector.clear();
|
||||
}
|
||||
} } ,
|
||||
{ "eraseObject", [=](){
|
||||
Vector<Node*> nodeVector = createVector();
|
||||
Node** nodes = (Node**)malloc(sizeof(Node*) * quantityOfNodes);
|
||||
|
||||
for (int i = 0; i < quantityOfNodes; ++i)
|
||||
{
|
||||
nodes[i] = nodeVector.at(i);
|
||||
}
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector.eraseObject(nodes[i]);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
|
||||
CCASSERT(nodeVector.empty(), "nodeVector was not empty.");
|
||||
|
||||
free(nodes);
|
||||
} } ,
|
||||
{ "erase", [=](){
|
||||
Vector<Node*> nodeVector = createVector();
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector.erase(nodeVector.begin());
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
|
||||
CCASSERT(nodeVector.empty(), "nodeVector was not empty.");
|
||||
|
||||
} } ,
|
||||
{ "clear", [=](){
|
||||
Vector<Node*> nodeVector = createVector();
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector.clear();
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
|
||||
CCASSERT(nodeVector.empty(), "nodeVector was not empty.");
|
||||
} } ,
|
||||
{ "swap by index", [=](){
|
||||
Vector<Node*> nodeVector = createVector();
|
||||
|
||||
int swapIndex1 = quantityOfNodes / 3;
|
||||
int swapIndex2 = quantityOfNodes / 3 * 2;
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector.swap(swapIndex1, swapIndex2);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
|
||||
{ "swap by object", [=](){
|
||||
Vector<Node*> nodeVector = createVector();
|
||||
|
||||
Node* swapNode1 = nodeVector.at(quantityOfNodes / 3);
|
||||
Node* swapNode2 = nodeVector.at(quantityOfNodes / 3 * 2);
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector.swap(swapNode1, swapNode2);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
|
||||
{ "reverse", [=](){
|
||||
Vector<Node*> nodeVector = createVector();
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector.reverse();
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
|
||||
{ "c++11 Range Loop", [=](){
|
||||
Vector<Node*> nodeVector = createVector();
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for (const auto& e : nodeVector)
|
||||
{
|
||||
e->setTag(111);
|
||||
}
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
};
|
||||
|
||||
for (const auto& func : testFunctions)
|
||||
{
|
||||
_testFunctions.push_back(func);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string TemplateVectorPerfTest::title() const
|
||||
{
|
||||
return "Vector<T> Perf test";
|
||||
}
|
||||
|
||||
std::string TemplateVectorPerfTest::subtitle() const
|
||||
{
|
||||
return "Test 'pushBack', See console";
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// ArrayPerfTest
|
||||
//
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
std::string ArrayPerfTest::title() const
|
||||
{
|
||||
return "Array Perf test";
|
||||
}
|
||||
|
||||
std::string ArrayPerfTest::subtitle() const
|
||||
{
|
||||
return "Test `addObject`, See console";
|
||||
}
|
||||
|
||||
void ArrayPerfTest::generateTestFunctions()
|
||||
{
|
||||
auto createArray = [this](){
|
||||
Array* ret = Array::create();
|
||||
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
{
|
||||
auto node = Node::create();
|
||||
node->setTag(i);
|
||||
ret->addObject(node);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
TestFunction testFunctions[] = {
|
||||
{ "addObject", [=](){
|
||||
Array* nodeVector = Array::create();
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector->addObject(Node::create());
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
{ "insertObject", [=](){
|
||||
Array* nodeVector = Array::create();
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector->insertObject(Node::create(), 0);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
{ "setObject", [=](){
|
||||
Array* nodeVector = createArray();
|
||||
|
||||
srand(time(nullptr));
|
||||
ssize_t index = rand() % quantityOfNodes;
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector->setObject(Node::create(), index);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
{ "getIndexOfObject", [=](){
|
||||
Array* nodeVector = createArray();
|
||||
Object* objToGet = nodeVector->getObjectAtIndex(quantityOfNodes/3);
|
||||
ssize_t index = 0;
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
index = nodeVector->getIndexOfObject(objToGet);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
// Uses `index` to avoids `getIndex` invoking was optimized in release mode
|
||||
if (index == quantityOfNodes/3)
|
||||
{
|
||||
nodeVector->removeAllObjects();
|
||||
}
|
||||
} } ,
|
||||
{ "getObjectAtIndex", [=](){
|
||||
Array* nodeVector = createArray();
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector->getObjectAtIndex(quantityOfNodes/3);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
{ "containsObject", [=](){
|
||||
Array* nodeVector = createArray();
|
||||
Object* objToGet = nodeVector->getObjectAtIndex(quantityOfNodes/3);
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector->containsObject(objToGet);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
{ "removeObject", [=](){
|
||||
Array* nodeVector = createArray();
|
||||
Node** nodes = (Node**)malloc(sizeof(Node*) * quantityOfNodes);
|
||||
|
||||
for (int i = 0; i < quantityOfNodes; ++i)
|
||||
{
|
||||
nodes[i] = static_cast<Node*>(nodeVector->getObjectAtIndex(i));
|
||||
}
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector->removeObject(nodes[i]);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
|
||||
CCASSERT(nodeVector->count() == 0, "nodeVector was not empty.");
|
||||
|
||||
free(nodes);
|
||||
} } ,
|
||||
{ "removeObjectAtIndex", [=](){
|
||||
Array* nodeVector = createArray();
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector->removeObjectAtIndex(0);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
|
||||
CCASSERT(nodeVector->count() == 0, "nodeVector was not empty.");
|
||||
|
||||
} } ,
|
||||
{ "removeAllObjects", [=](){
|
||||
Array* nodeVector = createArray();
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector->removeAllObjects();
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
|
||||
CCASSERT(nodeVector->count() == 0, "nodeVector was not empty.");
|
||||
} } ,
|
||||
{ "swap by index", [=](){
|
||||
Array* nodeVector = createArray();
|
||||
|
||||
int swapIndex1 = quantityOfNodes / 3;
|
||||
int swapIndex2 = quantityOfNodes / 3 * 2;
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector->swap(swapIndex1, swapIndex2);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
|
||||
{ "swap by object", [=](){
|
||||
Array* nodeVector = createArray();
|
||||
|
||||
Object* swapNode1 = nodeVector->getObjectAtIndex(quantityOfNodes / 3);
|
||||
Object* swapNode2 = nodeVector->getObjectAtIndex(quantityOfNodes / 3 * 2);
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector->exchangeObject(swapNode1, swapNode2);
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
|
||||
{ "reverseObjects", [=](){
|
||||
Array* nodeVector = createArray();
|
||||
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
for( int i=0; i<quantityOfNodes; ++i)
|
||||
nodeVector->reverseObjects();
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
|
||||
{ "CCARRAY_FOREACH", [=](){
|
||||
Array* nodeVector = createArray();
|
||||
Object* obj;
|
||||
CC_PROFILER_START(this->profilerName());
|
||||
|
||||
CCARRAY_FOREACH(nodeVector, obj)
|
||||
{
|
||||
static_cast<Node*>(obj)->setTag(111);
|
||||
}
|
||||
CC_PROFILER_STOP(this->profilerName());
|
||||
} } ,
|
||||
};
|
||||
|
||||
for (const auto& func : testFunctions)
|
||||
{
|
||||
_testFunctions.push_back(func);
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------
|
||||
void runContainerPerformanceTest()
|
||||
{
|
||||
auto scene = createFunctions[g_curCase]();
|
||||
scene->initWithQuantityOfNodes(kNodesIncrease);
|
||||
|
||||
Director::getInstance()->replaceScene(scene);
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
*
|
||||
*/
|
||||
#ifndef __PERFORMANCE_CONTAINER_TEST_H__
|
||||
#define __PERFORMANCE_CONTAINER_TEST_H__
|
||||
|
||||
#include "PerformanceTest.h"
|
||||
#include "CCProfiling.h"
|
||||
|
||||
class ContainerBasicLayer : public PerformBasicLayer
|
||||
{
|
||||
public:
|
||||
ContainerBasicLayer(bool bControlMenuVisible, int nMaxCases = 0, int nCurCase = 0);
|
||||
|
||||
virtual void showCurrentTest();
|
||||
};
|
||||
|
||||
class PerformanceContainerScene : public Scene
|
||||
{
|
||||
public:
|
||||
static const int TAG_TITLE = 100;
|
||||
static const int TAG_SUBTITLE = 101;
|
||||
|
||||
struct TestFunction
|
||||
{
|
||||
const char* name;
|
||||
std::function<void()> func;
|
||||
};
|
||||
|
||||
virtual void initWithQuantityOfNodes(unsigned int nNodes);
|
||||
virtual void generateTestFunctions() = 0;
|
||||
|
||||
virtual std::string title() const;
|
||||
virtual std::string subtitle() const;
|
||||
virtual void updateQuantityOfNodes();
|
||||
|
||||
const char* profilerName();
|
||||
void updateProfilerName();
|
||||
|
||||
// for the profiler
|
||||
virtual const char* testName();
|
||||
void updateQuantityLabel();
|
||||
int getQuantityOfNodes() { return quantityOfNodes; }
|
||||
void dumpProfilerInfo(float dt);
|
||||
|
||||
// overrides
|
||||
virtual void onExitTransitionDidStart() override;
|
||||
virtual void onEnterTransitionDidFinish() override;
|
||||
virtual void update(float dt) override;
|
||||
|
||||
protected:
|
||||
char _profilerName[256];
|
||||
int lastRenderedCount;
|
||||
int quantityOfNodes;
|
||||
int currentQuantityOfNodes;
|
||||
unsigned int _type;
|
||||
std::vector<TestFunction> _testFunctions;
|
||||
|
||||
MenuItemFont* _increase;
|
||||
MenuItemFont* _decrease;
|
||||
MenuItemFont* _startItem;
|
||||
MenuItemFont* _stopItem;
|
||||
MenuItemToggle* _toggle;
|
||||
};
|
||||
|
||||
class TemplateVectorPerfTest : public PerformanceContainerScene
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(TemplateVectorPerfTest);
|
||||
|
||||
virtual void generateTestFunctions() override;
|
||||
|
||||
virtual std::string title() const override;
|
||||
virtual std::string subtitle() const override;
|
||||
};
|
||||
|
||||
class ArrayPerfTest : public PerformanceContainerScene
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(ArrayPerfTest);
|
||||
|
||||
virtual void generateTestFunctions() override;
|
||||
|
||||
virtual std::string title() const override;
|
||||
virtual std::string subtitle() const override;
|
||||
};
|
||||
|
||||
|
||||
void runContainerPerformanceTest();
|
||||
|
||||
#endif // __PERFORMANCE_CONTAINER_TEST_H__
|
|
@ -8,6 +8,7 @@
|
|||
#include "PerformanceAllocTest.h"
|
||||
#include "PerformanceLabelTest.h"
|
||||
#include "PerformanceRendererTest.h"
|
||||
#include "PerformanceContainerTest.h"
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -28,6 +29,7 @@ struct {
|
|||
{ "Touches Perf Test",[](Object*sender){runTouchesTest();} },
|
||||
{ "Label Perf Test",[](Object*sender){runLabelTest();} },
|
||||
{ "Renderer Perf Test",[](Object*sender){runRendererTest();} },
|
||||
{ "Container Perf Test", [](Object* sender ) { runContainerPerformanceTest(); } }
|
||||
};
|
||||
|
||||
static const int g_testMax = sizeof(g_testsName)/sizeof(g_testsName[0]);
|
||||
|
|
|
@ -186,6 +186,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\websockets\prebuilt\win32\*.*" "$
|
|||
<ClCompile Include="..\Classes\NewEventDispatcherTest\NewEventDispatcherTest.cpp" />
|
||||
<ClCompile Include="..\Classes\NewRendererTest\NewRendererTest.cpp" />
|
||||
<ClCompile Include="..\Classes\PerformanceTest\PerformanceAllocTest.cpp" />
|
||||
<ClCompile Include="..\Classes\PerformanceTest\PerformanceContainerTest.cpp" />
|
||||
<ClCompile Include="..\Classes\PerformanceTest\PerformanceLabelTest.cpp" />
|
||||
<ClCompile Include="..\Classes\PerformanceTest\PerformanceRendererTest.cpp" />
|
||||
<ClCompile Include="..\Classes\PhysicsTest\PhysicsTest.cpp" />
|
||||
|
@ -332,6 +333,8 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\websockets\prebuilt\win32\*.*" "$
|
|||
<ClInclude Include="..\Classes\LabelTest\LabelTestNew.h" />
|
||||
<ClInclude Include="..\Classes\NewEventDispatcherTest\NewEventDispatcherTest.h" />
|
||||
<ClInclude Include="..\Classes\NewRendererTest\NewRendererTest.h" />
|
||||
<ClInclude Include="..\Classes\PerformanceTest\PerformanceAllocTest.h" />
|
||||
<ClInclude Include="..\Classes\PerformanceTest\PerformanceContainerTest.h" />
|
||||
<ClInclude Include="..\Classes\PerformanceTest\PerformanceLabelTest.h" />
|
||||
<ClInclude Include="..\Classes\PerformanceTest\PerformanceRendererTest.h" />
|
||||
<ClInclude Include="..\Classes\PhysicsTest\PhysicsTest.h" />
|
||||
|
|
|
@ -718,6 +718,9 @@
|
|||
<ClCompile Include="..\Classes\PerformanceTest\PerformanceRendererTest.cpp">
|
||||
<Filter>Classes\PerformanceTest</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Classes\PerformanceTest\PerformanceContainerTest.cpp">
|
||||
<Filter>Classes\PerformanceTest</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="main.h">
|
||||
|
@ -1324,5 +1327,11 @@
|
|||
<ClInclude Include="..\Classes\PerformanceTest\PerformanceRendererTest.h">
|
||||
<Filter>Classes\PerformanceTest</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Classes\PerformanceTest\PerformanceAllocTest.h">
|
||||
<Filter>Classes\PerformanceTest</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Classes\PerformanceTest\PerformanceContainerTest.h">
|
||||
<Filter>Classes\PerformanceTest</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1 +1 @@
|
|||
5ae50c3f2080b46e18ba3f5aee4c5c686d54e13a
|
||||
f056b511a4fb5efc921792e46fe57597f669de83
|
Loading…
Reference in New Issue