DUDS
Distributed Update of Data from Something
BppStringCache.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the DUDS project. It is subject to the BSD-style
3  * license terms in the LICENSE file found in the top-level directory of this
4  * distribution and at https://github.com/jjackowski/duds/blob/master/LICENSE.
5  * No part of DUDS, including this file, may be copied, modified, propagated,
6  * or distributed except according to the terms contained in the LICENSE file.
7  *
8  * Copyright (C) 2019 Jeff Jackowski
9  */
12 #include <duds/general/Errors.hpp>
13 #include <codecvt>
14 
15 namespace duds { namespace ui { namespace graphics {
16 
18  const BppFontSptr &font,
19  unsigned int maxBytes,
20  unsigned int maxStrings
21 ) : fnt(font), maxB(maxBytes), maxS(maxStrings) {
22  if (!maxS) {
24  }
25 }
26 
28  BppFontSptr &&font,
29  unsigned int maxBytes,
30  unsigned int maxStrings
31 ) : fnt(std::move(font)), maxB(maxBytes), maxS(maxStrings) {
32  if (!maxS) {
34  }
35 }
36 
38  std::lock_guard<duds::general::Spinlock> lock(block);
39  cache.clear();
40  curB = 0;
41 }
42 
44  const std::u32string &str,
45  BppFont::Flags flags
46 ) {
47  // check for a single character string
48  if (str.length() == 1) {
49  // attempt to provide the string image from the font; do not cache
50  // what the font already holds
51  return fnt->get(str[0]);
52  }
53  {
54  std::lock_guard<duds::general::Spinlock> lock(block);
55  // attempt to find a match
56  Cache::iterator iter = cache.find(std::make_tuple(str, flags));
57  if (iter != cache.end()) {
58  // move item to the end of the sequence
59  Cache::index<index_seq>::type::iterator siter =
60  cache.project<index_seq>(iter);
61  Cache::index<index_seq>::type &sidx = cache.get<index_seq>();
62  sidx.relocate(sidx.end(), siter);
63  return iter->img;
64  }
65  }
66  // no match; it must be rendered
67  BppImageSptr img = fnt->render(str, flags);
68  // much easier to get to size this way than through res later
69  unsigned int imgSize = img->data().size();
70  std::lock_guard<duds::general::Spinlock> lock(block);
71  // store the result for later
72  std::pair<Cache::iterator, bool> res =
73  cache.emplace(BppString{std::move(img), str, flags});
74  // insertion check
75  if (res.second) {
76  // update current image size sum
77  curB += imgSize * sizeof(BppImage::PixelBlock);
78  // cache size limit hit?
79  if ((curB > maxB) || (cache.size() > maxS)) {
80  Cache::index<index_seq>::type &sidx = cache.get<index_seq>();
81  // loop through removals
82  Cache::index<index_seq>::type::iterator iter = sidx.begin();
83  do {
84  // remove area from the sum
85  curB -= iter->img->data().size() * sizeof(BppImage::PixelBlock);
86  // remove item
87  iter = sidx.erase(iter);
88  }
89  // loop until size of data is within limits, or the just added item
90  // is the only item left
91  while ((curB > maxB) && (cache.size() > 1));
92  }
93  }
94  // else {
95  // Must have had multiple requests for the same string simultaneously
96  // that resulted in multiple renderings during time without a lock.
97  // Moving the lock to cover the whole function will prevent this, but
98  // I suspect this condition will be very rare, and releasing the lock
99  // during rendering will allow more time for multiple threads to use
100  // the cache without blocking.
101  // }
102  // return from item in cache
103  return res.first->img;
104 }
105 
107  const std::string &str,
108  BppFont::Flags flags
109 ) {
110  std::wstring_convert< std::codecvt_utf8< char32_t >, char32_t > conv;
111  std::u32string cstr = conv.from_bytes(str);
112  return text(cstr, flags);
113 }
114 
115 } } }
std::uintptr_t PixelBlock
The type used to hold pixel values, one bit per pixel.
Definition: BppImage.hpp:326
const BppFontSptr & font() const
Returns the font object used by this cache to render text.
std::shared_ptr< BppFont > BppFontSptr
Definition: BppFont.hpp:263
unsigned int maxStrings() const
Returns the maximum number of cached images.
Stores an image and the data used to create it using the font.
std::shared_ptr< const BppImage > ConstBppImageSptr
Definition: BppImage.hpp:1778
unsigned int maxBytes() const
Returns the maximum size of the cached images in bytes.
STL namespace.
move_impl move(unsigned int c, unsigned int r)
Display stream manipulator that moves the display cursor to the given location.
The maximum size of a BppStringCache is zero.
BppStringCache(const BppFontSptr &font, unsigned int maxBytes=256 *1024, unsigned int maxStrings=-1)
Creates a cache of rendered strings made using the given font.
unsigned int curB
The current size of all rendered text images in the cache.
void clear()
Clears all text images from the cache.
ConstBppImageSptr text(const std::string &str, BppFont::Flags flags=BppFont::AlignLeft)
Returns an image of the requested string either from a pre-rendered item in the cache or by rendering...
std::shared_ptr< BppImage > BppImageSptr
Definition: BppImage.hpp:1777
duds::general::Spinlock block
Used for thread safety.
static std::wstring_convert< std::codecvt_utf8< char32_t >, char32_t > conv
String converter; UTF-8 to/from UTF-32.
Definition: BppFont.cpp:165
unsigned int maxB
The maximum size of rendered text images, in bytes, the cache may hold.
BppFontSptr fnt
The font to use for rendering.
General graphics related code.
Definition: HD44780.hpp:15
Cache cache
The cache of rendered strings.
unsigned int maxS
The maximum number of strings the cache may hold.
General errors.
#define DUDS_THROW_EXCEPTION(x)
Works like BOOST_THROW_EXCEPTION, but includes a stack trace if DUDS_ERRORS_VERBOSE is defined...
Definition: Errors.hpp:48