From 0d300e7aa5699154810af67282dacbcd65929768 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 22 Apr 2013 21:24:52 +0300 Subject: impliment new list in sdlfont. --- src/Makefile.am | 1 + src/commands.cpp | 8 +- src/gui/sdlfont.cpp | 381 ++++++++++++++++++++++++++++---------------- src/gui/sdlfont.h | 54 ++++++- src/gui/sdlfont_unittest.cc | 304 +++++++++++++++++++++++++++++++++++ 5 files changed, 599 insertions(+), 149 deletions(-) create mode 100644 src/gui/sdlfont_unittest.cc (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 38b37afe1..d4b994988 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -828,6 +828,7 @@ manaplus_SOURCES += \ if ENABLE_UNITTESTS manaplus_CXXFLAGS += -DUNITTESTS manaplus_SOURCES += \ + gui/sdlfont_unittest.cc \ gui/widgets/browserbox_unittest.cc \ utils/stringutils_unittest.cc endif diff --git a/src/commands.cpp b/src/commands.cpp index 065983a01..8f03780ba 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -920,11 +920,12 @@ impHandler0(cacheInfo) if (!chatWindow || !debugChatTab) return; +/* SDLFont *const font = dynamic_cast(chatWindow->getFont()); if (!font) return; - const std::list *const cache = font->getCache(); + const TextChunkList *const cache = font->getCache(); if (!cache) return; @@ -933,9 +934,9 @@ impHandler0(cacheInfo) std::string str; for (int f = 0; f < 256; f ++) { - if (!cache[f].empty()) + if (!cache[f].size) { - const unsigned int sz = static_cast(cache[f].size()); + const unsigned int sz = static_cast(cache[f].size); all += sz; str.append(strprintf("%d: %u, ", f, sz)); } @@ -949,6 +950,7 @@ impHandler0(cacheInfo) debugChatTab->chatLog(strprintf("%s %d", _("Deleted:"), font->getDeleteCounter())); #endif +*/ } impHandler0(serverIgnoreAll) diff --git a/src/gui/sdlfont.cpp b/src/gui/sdlfont.cpp index 1acb50720..8ffb14b13 100644 --- a/src/gui/sdlfont.cpp +++ b/src/gui/sdlfont.cpp @@ -46,116 +46,220 @@ const int OUTLINE_SIZE = 1; char *strBuf; -class SDLTextChunk final +const unsigned int CACHES_NUMBER = 256; + +#ifdef UNITTESTS +int sdlTextChunkCnt = 0; +#endif + +SDLTextChunk::SDLTextChunk(const std::string &text0, const gcn::Color &color0, + const gcn::Color &color1) : + img(nullptr), + text(text0), + color(color0), + color2(color1), + next(nullptr) { - public: - SDLTextChunk(const std::string &text0, const gcn::Color &color0, - const gcn::Color &color1) : - img(nullptr), text(text0), color(color0), color2(color1) - { - } +#ifdef UNITTESTS + sdlTextChunkCnt ++; +#endif +} +SDLTextChunk::~SDLTextChunk() +{ + delete img; + img = nullptr; +#ifdef UNITTESTS + sdlTextChunkCnt --; +#endif +} - ~SDLTextChunk() +bool SDLTextChunk::operator==(const SDLTextChunk &chunk) const +{ + return (chunk.text == text && chunk.color == color + && chunk.color2 == color2); +} + +void SDLTextChunk::generate(TTF_Font *const font, const float alpha) +{ + BLOCK_START("SDLTextChunk::generate") + SDL_Color sdlCol; + sdlCol.b = static_cast(color.b); + sdlCol.r = static_cast(color.r); + sdlCol.g = static_cast(color.g); + sdlCol.unused = 0; + + getSafeUtf8String(text, strBuf); + + SDL_Surface *surface = TTF_RenderUTF8_Blended( + font, strBuf, sdlCol); + + if (!surface) + { + img = nullptr; + BLOCK_END("SDLTextChunk::generate") + return; + } + + const int width = surface->w; + const int height = surface->h; + + if (color.r != color2.r || color.g != color2.g + || color.b != color2.b) + { // outlining + SDL_Color sdlCol2; + SDL_Surface *background = imageHelper->create32BitSurface( + width, height); + if (!background) { - delete img; img = nullptr; + SDL_FreeSurface(surface); + BLOCK_END("SDLTextChunk::generate") + return; } - - bool operator==(const SDLTextChunk &chunk) const + sdlCol2.b = static_cast(color2.b); + sdlCol2.r = static_cast(color2.r); + sdlCol2.g = static_cast(color2.g); + sdlCol2.unused = 0; + SDL_Surface *const surface2 = TTF_RenderUTF8_Blended( + font, strBuf, sdlCol2); + if (!surface2) { - return (chunk.text == text && chunk.color == color - && chunk.color2 == color2); + img = nullptr; + SDL_FreeSurface(surface); + BLOCK_END("SDLTextChunk::generate") + return; } - - void generate(TTF_Font *const font, const float alpha) + SDL_Rect rect = { - BLOCK_START("SDLTextChunk::generate") - SDL_Color sdlCol; - sdlCol.b = static_cast(color.b); - sdlCol.r = static_cast(color.r); - sdlCol.g = static_cast(color.g); - sdlCol.unused = 0; - - getSafeUtf8String(text, strBuf); - - SDL_Surface *surface = TTF_RenderUTF8_Blended( - font, strBuf, sdlCol); - - if (!surface) - { - img = nullptr; - BLOCK_END("SDLTextChunk::generate") - return; - } - - const int width = surface->w; - const int height = surface->h; - - if (color.r != color2.r || color.g != color2.g - || color.b != color2.b) - { // outlining - SDL_Color sdlCol2; - SDL_Surface *background = imageHelper->create32BitSurface( - width, height); - if (!background) - { - img = nullptr; - SDL_FreeSurface(surface); - BLOCK_END("SDLTextChunk::generate") - return; - } - sdlCol2.b = static_cast(color2.b); - sdlCol2.r = static_cast(color2.r); - sdlCol2.g = static_cast(color2.g); - sdlCol2.unused = 0; - SDL_Surface *const surface2 = TTF_RenderUTF8_Blended( - font, strBuf, sdlCol2); - if (!surface2) - { - img = nullptr; - SDL_FreeSurface(surface); - BLOCK_END("SDLTextChunk::generate") - return; - } - SDL_Rect rect = - { - OUTLINE_SIZE, - 0, - static_cast(surface->w), - static_cast(surface->h) - }; + OUTLINE_SIZE, + 0, + static_cast(surface->w), + static_cast(surface->h) + }; // SDL_SetAlpha(surface2, 0, SDL_ALPHA_OPAQUE); - MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect); - rect.x = -OUTLINE_SIZE; - MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect); - rect.x = 0; - rect.y = -OUTLINE_SIZE; - MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect); - rect.y = OUTLINE_SIZE; - MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect); - rect.x = 0; - rect.y = 0; + MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect); + rect.x = -OUTLINE_SIZE; + MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect); + rect.x = 0; + rect.y = -OUTLINE_SIZE; + MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect); + rect.y = OUTLINE_SIZE; + MSDL_gfxBlitRGBA(surface2, nullptr, background, &rect); + rect.x = 0; + rect.y = 0; // SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE); - MSDL_gfxBlitRGBA(surface, nullptr, background, &rect); - SDL_FreeSurface(surface); - SDL_FreeSurface(surface2); - surface = background; - } - img = imageHelper->createTextSurface( - surface, width, height, alpha); - SDL_FreeSurface(surface); + MSDL_gfxBlitRGBA(surface, nullptr, background, &rect); + SDL_FreeSurface(surface); + SDL_FreeSurface(surface2); + surface = background; + } + img = imageHelper->createTextSurface( + surface, width, height, alpha); + SDL_FreeSurface(surface); + + BLOCK_END("SDLTextChunk::generate") +} - BLOCK_END("SDLTextChunk::generate") - } - Image *img; - std::string text; - gcn::Color color; - gcn::Color color2; -}; +TextChunkList::TextChunkList() : + start(nullptr), + end(nullptr), + size(0) +{ +} -typedef std::list::iterator CacheIterator; +void TextChunkList::insertFirst(SDLTextChunk *const item) +{ + SDLTextChunk *const oldFirst = start; + if (start) + start->prev = item; + item->prev = nullptr; + if (oldFirst) + item->next = oldFirst; + else + end = item; + start = item; + size ++; +} + +void TextChunkList::moveToFirst(SDLTextChunk *item) +{ + if (item == start) + return; + + SDLTextChunk *oldPrev = item->prev; + if (oldPrev) + oldPrev->next = item->next; + SDLTextChunk *oldNext = item->next; + if (oldNext) + oldNext->prev = item->prev; + else + end = oldPrev; + SDLTextChunk *const oldFirst = start; + if (start) + start->prev = item; + item->prev = nullptr; + item->next = oldFirst; + start = item; +} + +void TextChunkList::removeBack() +{ + SDLTextChunk *oldEnd = end; + if (oldEnd) + { + end = oldEnd->prev; + if (end) + end->next = nullptr; + else + start = nullptr; + delete oldEnd; + size --; + } +} + +void TextChunkList::removeBack(int n) +{ + SDLTextChunk *item = end; + while (n && item) + { + n --; + SDLTextChunk *oldEnd = item; + item = item->prev; + delete oldEnd; + size --; + } + if (item) + { + item->next = nullptr; + end = item; + } + else + { + start = nullptr; + end = nullptr; + } +} + +void TextChunkList::clear() +{ + SDLTextChunk *item = start; + while (item) + { + SDLTextChunk *item2 = item->next; + delete item; + item = item2; + } + start = nullptr; + end = nullptr; + size = 0; +} + +namespace +{ + TextChunkList mCache[CACHES_NUMBER]; +} // namespace static int fontCounter; @@ -205,6 +309,7 @@ SDLFont::~SDLFont() TTF_CloseFont(mFont); mFont = nullptr; --fontCounter; + clear(); if (fontCounter == 0) { @@ -246,9 +351,7 @@ void SDLFont::loadFont(std::string filename, const int size, const int style) void SDLFont::clear() { for (size_t f = 0; f < CACHES_NUMBER; f ++) - { mCache[f].clear(); - } } void SDLFont::drawString(gcn::Graphics *const graphics, @@ -278,7 +381,7 @@ void SDLFont::drawString(gcn::Graphics *const graphics, SDLTextChunk chunk(text, col, col2); const unsigned char chr = text[0]; - std::list *const cache = &mCache[chr]; + TextChunkList *const cache = &mCache[chr]; bool found = false; @@ -286,19 +389,22 @@ void SDLFont::drawString(gcn::Graphics *const graphics, int cnt = 0; #endif - FOR_EACHP (CacheIterator, i, cache) + SDLTextChunk *i = cache->start; + while (i) { - if (chunk == (*i)) + if (*i == chunk) { // Raise priority: move it to front - cache->splice(cache->begin(), *cache, i); + cache->moveToFirst(i); found = true; break; } + i = i->next; #ifdef DEBUG_FONT cnt ++; #endif } + #ifdef DEBUG_FONT logger->log(std::string("drawString: ").append(text).append( ", iterations: ").append(toString(cnt))); @@ -307,28 +413,33 @@ void SDLFont::drawString(gcn::Graphics *const graphics, // Surface not found if (!found) { - if (cache->size() >= CACHE_SIZE) + if (cache->size >= CACHE_SIZE) { #ifdef DEBUG_FONT_COUNTERS mDeleteCounter ++; #endif - cache->pop_back(); + cache->removeBack(); } #ifdef DEBUG_FONT_COUNTERS mCreateCounter ++; #endif - cache->push_front(chunk); - SDLTextChunk &data = cache->front(); - data.generate(mFont, alpha); + SDLTextChunk *chunk2 = new SDLTextChunk(text, col, col2); + + chunk2->generate(mFont, alpha); + cache->insertFirst(chunk2); - if (data.img) - g->drawImage(data.img, x, y); + const Image *const image = chunk2->img; + if (image) + g->drawImage(image, x, y); } - else if (cache->front().img) + else { - Image *const image = cache->front().img; - image->setAlpha(alpha); - g->drawImage(image, x, y); + Image *const image = cache->start->img; + if (image) + { + image->setAlpha(alpha); + g->drawImage(image, x, y); + } } BLOCK_END("SDLFont::drawString") } @@ -348,40 +459,33 @@ void SDLFont::slowLogic(const int rnd) BLOCK_END("SDLFont::slowLogic") } -void SDLFont::createSDLTextChunk(SDLTextChunk *const chunk) -{ - if (!chunk || chunk->text.empty()) - return; - - const float alpha = static_cast(chunk->color.a) / 255.0f; - chunk->color.a = 255; - chunk->generate(mFont, alpha); -} - int SDLFont::getWidth(const std::string &text) const { if (text.empty()) return 0; const unsigned char chr = text[0]; - std::list *const cache = &mCache[chr]; + TextChunkList *const cache = &mCache[chr]; #ifdef DEBUG_FONT int cnt = 0; #endif - FOR_EACHP (CacheIterator, i, cache) + SDLTextChunk *i = cache->start; + while (i) { if (i->text == text) { // Raise priority: move it to front // Assumption is that TTF::draw will be called next - cache->splice(cache->begin(), *cache, i); - if (i->img) - return i->img->getWidth(); + cache->moveToFirst(i); + const Image *const image = i->img; + if (image) + return image->getWidth(); else return 0; } + i = i->next; #ifdef DEBUG_FONT cnt ++; #endif @@ -407,8 +511,8 @@ void SDLFont::doClean() { for (unsigned int f = 0; f < CACHES_NUMBER; f ++) { - std::list *const cache = &mCache[f]; - const size_t size = cache->size(); + TextChunkList *const cache = &mCache[f]; + const size_t size = cache->size; #ifdef DEBUG_FONT_COUNTERS logger->log("ptr: %d, size: %d", f, size); #endif @@ -417,10 +521,7 @@ void SDLFont::doClean() #ifdef DEBUG_FONT_COUNTERS mDeleteCounter += 100; #endif - const std::list::iterator it_end = cache->end(); - std::list::iterator it = cache->begin(); - std::advance(it, -100); - cache->erase(it, it_end); + cache->removeBack(100); #ifdef DEBUG_FONT_COUNTERS logger->log("delete3"); #endif @@ -430,10 +531,7 @@ void SDLFont::doClean() #ifdef DEBUG_FONT_COUNTERS mDeleteCounter += 20; #endif - const std::list::iterator it_end = cache->end(); - std::list::iterator it = cache->begin(); - std::advance(it, -20); - cache->erase(it, it_end); + cache->removeBack(20); #ifdef DEBUG_FONT_COUNTERS logger->log("delete2"); #endif @@ -443,10 +541,15 @@ void SDLFont::doClean() #ifdef DEBUG_FONT_COUNTERS mDeleteCounter ++; #endif - cache->pop_back(); + cache->removeBack(); #ifdef DEBUG_FONT_COUNTERS logger->log("delete1"); #endif } } } + +TextChunkList *SDLFont::getCache() +{ + return mCache; +} diff --git a/src/gui/sdlfont.h b/src/gui/sdlfont.h index 4e77943f8..2e5376148 100644 --- a/src/gui/sdlfont.h +++ b/src/gui/sdlfont.h @@ -24,6 +24,7 @@ #ifndef SDLFONT_H #define SDLFONT_H +#include #include #ifdef __WIN32__ @@ -37,9 +38,48 @@ #include "localconsts.h" -const unsigned int CACHES_NUMBER = 256; +class Image; -class SDLTextChunk; +class SDLTextChunk final +{ + public: + SDLTextChunk(const std::string &text0, const gcn::Color &color0, + const gcn::Color &color1); + + ~SDLTextChunk(); + + bool operator==(const SDLTextChunk &chunk) const; + + void generate(TTF_Font *const font, const float alpha); + + Image *img; + std::string text; + gcn::Color color; + gcn::Color color2; + SDLTextChunk *prev; + SDLTextChunk *next; +}; + + +class TextChunkList final +{ + public: + TextChunkList(); + + void insertFirst(SDLTextChunk *const item); + + void moveToFirst(SDLTextChunk *item); + + void removeBack(); + + void removeBack(int n); + + void clear(); + + SDLTextChunk *start; + SDLTextChunk *end; + uint32_t size; +}; /** * A wrapper around SDL_ttf for allowing the use of TrueType fonts. @@ -67,14 +107,11 @@ class SDLFont final : public gcn::Font void loadFont(std::string filename, const int size, const int style = 0); - void createSDLTextChunk(SDLTextChunk *const chunk); - virtual int getWidth(const std::string &text) const A_WARN_UNUSED; virtual int getHeight() const A_WARN_UNUSED; - std::list *getCache() A_WARN_UNUSED - { return mCache; } + TextChunkList *getCache() A_WARN_UNUSED; /** * @see Font::drawString @@ -101,8 +138,11 @@ class SDLFont final : public gcn::Font unsigned mDeleteCounter; // Word surfaces cache - mutable std::list mCache[CACHES_NUMBER]; int mCleanTime; }; +#ifdef UNITTESTS +extern int sdlTextChunkCnt; +#endif + #endif diff --git a/src/gui/sdlfont_unittest.cc b/src/gui/sdlfont_unittest.cc new file mode 100644 index 000000000..31b76f131 --- /dev/null +++ b/src/gui/sdlfont_unittest.cc @@ -0,0 +1,304 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "logger.h" + +#include "gui/sdlfont.h" +#include "gui/theme.h" + +#include "gtest/gtest.h" + +#include "debug.h" + +TEST(TextChunkList, empty) +{ + TextChunkList list; + + EXPECT_EQ(0, list.size); + EXPECT_EQ(nullptr, list.start); + EXPECT_EQ(nullptr, list.end); +} + +TEST(TextChunkList, add1) +{ + TextChunkList list; + + SDLTextChunk *chunk = new SDLTextChunk("test", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk); + + EXPECT_EQ(1, list.size); + EXPECT_EQ(chunk, list.start); + EXPECT_EQ(chunk, list.end); + EXPECT_EQ(nullptr, chunk->prev); + EXPECT_EQ(nullptr, chunk->next); +} + +TEST(TextChunkList, add2) +{ + TextChunkList list; + + SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk2 = new SDLTextChunk("test", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk2); + list.insertFirst(chunk1); + + EXPECT_EQ(2, list.size); + EXPECT_EQ(chunk1, list.start); + EXPECT_EQ(chunk2, list.end); + EXPECT_EQ(nullptr, chunk1->prev); + EXPECT_EQ(chunk2, chunk1->next); + EXPECT_EQ(chunk1, chunk2->prev); + EXPECT_EQ(nullptr, chunk2->next); +} + +TEST(TextChunkList, addRemoveBack1) +{ + TextChunkList list; + + SDLTextChunk *chunk = new SDLTextChunk("test", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk); + list.removeBack(); + + EXPECT_EQ(0, list.size); + EXPECT_EQ(nullptr, list.start); + EXPECT_EQ(nullptr, list.end); +} + +TEST(TextChunkList, addRemoveBack2) +{ + TextChunkList list; + + SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk2); + list.insertFirst(chunk1); + list.removeBack(); + + EXPECT_EQ(1, list.size); + EXPECT_EQ(chunk1, list.start); + EXPECT_EQ(chunk1, list.end); + EXPECT_EQ(nullptr, chunk1->prev); + EXPECT_EQ(nullptr, chunk1->next); +} + +TEST(TextChunkList, addRemoveBack3) +{ + TextChunkList list; + + SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk2); + list.insertFirst(chunk1); + list.removeBack(2); + + EXPECT_EQ(0, list.size); + EXPECT_EQ(nullptr, list.start); + EXPECT_EQ(nullptr, list.end); +} + +TEST(TextChunkList, addRemoveBack4) +{ + TextChunkList list; + + SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk3 = new SDLTextChunk("test3", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk3); + list.insertFirst(chunk2); + list.insertFirst(chunk1); + list.removeBack(); + list.removeBack(); + + EXPECT_EQ(1, list.size); + EXPECT_EQ(chunk1, list.start); + EXPECT_EQ(chunk1, list.end); + EXPECT_EQ(nullptr, chunk1->prev); + EXPECT_EQ(nullptr, chunk1->next); +} + +TEST(TextChunkList, moveToFirst1) +{ + TextChunkList list; + + SDLTextChunk *chunk = new SDLTextChunk("test", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk); + list.moveToFirst(chunk); + + EXPECT_EQ(1, list.size); + EXPECT_EQ(chunk, list.start); + EXPECT_EQ(chunk, list.end); + EXPECT_EQ(nullptr, chunk->prev); + EXPECT_EQ(nullptr, chunk->next); +} + +TEST(TextChunkList, moveToFirst2) +{ + TextChunkList list; + + SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk1); + list.insertFirst(chunk2); + list.moveToFirst(chunk1); + + EXPECT_EQ(2, list.size); + EXPECT_EQ(chunk1, list.start); + EXPECT_EQ(chunk2, list.end); + EXPECT_EQ(nullptr, chunk1->prev); + EXPECT_EQ(chunk2, chunk1->next); + EXPECT_EQ(chunk1, chunk2->prev); + EXPECT_EQ(nullptr, chunk2->next); +} + +TEST(TextChunkList, moveToFirst3) +{ + TextChunkList list; + + SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk3 = new SDLTextChunk("test3", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk3); + list.insertFirst(chunk1); + list.insertFirst(chunk2); + list.moveToFirst(chunk1); + + EXPECT_EQ(3, list.size); + EXPECT_EQ(chunk1, list.start); + EXPECT_EQ(chunk3, list.end); + EXPECT_EQ(nullptr, chunk1->prev); + EXPECT_EQ(chunk2, chunk1->next); + EXPECT_EQ(chunk1, chunk2->prev); + EXPECT_EQ(chunk3, chunk2->next); + EXPECT_EQ(chunk2, chunk3->prev); + EXPECT_EQ(nullptr, chunk3->next); +} + +TEST(TextChunkList, moveToFirst4) +{ + TextChunkList list; + + SDLTextChunk *chunk1 = new SDLTextChunk("test", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk3 = new SDLTextChunk("test3", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk1); + list.insertFirst(chunk3); + list.insertFirst(chunk2); + list.moveToFirst(chunk1); + + EXPECT_EQ(3, list.size); + EXPECT_EQ(chunk1, list.start); + EXPECT_EQ(chunk3, list.end); + EXPECT_EQ(nullptr, chunk1->prev); + EXPECT_EQ(chunk2, chunk1->next); + EXPECT_EQ(chunk1, chunk2->prev); + EXPECT_EQ(chunk3, chunk2->next); + EXPECT_EQ(chunk2, chunk3->prev); + EXPECT_EQ(nullptr, chunk3->next); +} + +TEST(TextChunkList, clear1) +{ + TextChunkList list; + int chunksLeft = sdlTextChunkCnt; + + SDLTextChunk *chunk = new SDLTextChunk("test", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk); + list.clear(); + + EXPECT_EQ(0, list.size); + EXPECT_EQ(nullptr, list.start); + EXPECT_EQ(nullptr, list.end); + EXPECT_EQ(chunksLeft, sdlTextChunkCnt); +} + +TEST(TextChunkList, clear2) +{ + TextChunkList list; + int chunksLeft = sdlTextChunkCnt; + + SDLTextChunk *chunk1 = new SDLTextChunk("test1", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk3 = new SDLTextChunk("test3", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk1); + list.insertFirst(chunk2); + list.insertFirst(chunk3); + list.clear(); + + EXPECT_EQ(0, list.size); + EXPECT_EQ(nullptr, list.start); + EXPECT_EQ(nullptr, list.end); + EXPECT_EQ(chunksLeft, sdlTextChunkCnt); +} + +TEST(TextChunkList, clear3) +{ + TextChunkList list; + int chunksLeft = sdlTextChunkCnt; + + SDLTextChunk *chunk1 = new SDLTextChunk("test1", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk3 = new SDLTextChunk("test3", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk1); + list.insertFirst(chunk2); + list.insertFirst(chunk3); + list.moveToFirst(chunk1); + EXPECT_EQ(chunksLeft + 3, sdlTextChunkCnt); + + list.removeBack(); + EXPECT_EQ(chunksLeft + 2, sdlTextChunkCnt); + + list.clear(); + EXPECT_EQ(chunksLeft, sdlTextChunkCnt); +} + +TEST(TextChunkList, clear4) +{ + TextChunkList list; + int chunksLeft = sdlTextChunkCnt; + + SDLTextChunk *chunk1 = new SDLTextChunk("test1", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk2 = new SDLTextChunk("test2", gcn::Color(), gcn::Color()); + SDLTextChunk *chunk3 = new SDLTextChunk("test3", gcn::Color(), gcn::Color()); + + list.insertFirst(chunk1); + list.insertFirst(chunk2); + list.insertFirst(chunk3); + list.moveToFirst(chunk2); + EXPECT_EQ(chunksLeft + 3, sdlTextChunkCnt); + + list.removeBack(2); + EXPECT_EQ(chunksLeft + 1, sdlTextChunkCnt); + + list.clear(); + EXPECT_EQ(chunksLeft, sdlTextChunkCnt); +} -- cgit v1.2.3-70-g09d2