• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdegames API Reference
  • KDE Home
  • Contact Us
 

libkdegames

  • sources
  • kde-4.14
  • kdegames
  • libkdegames
kgamerenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright 2010-2012 Stefan Majewsky <majewsky@gmx.net> *
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU Library General Public License *
6  * version 2 as published by the Free Software Foundation *
7  * *
8  * This program is distributed in the hope that it will be useful, *
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
11  * GNU Library General Public License for more details. *
12  * *
13  * You should have received a copy of the GNU Library General Public *
14  * License along with this program; if not, write to the *
15  * Free Software Foundation, Inc., *
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
17  ***************************************************************************/
18 
19 #include "kgamerenderer.h"
20 #include "kgamerenderer_p.h"
21 #include "kgamerendererclient.h"
22 #include "colorproxy_p.h"
23 #include "kgtheme.h"
24 #include "kgthemeprovider.h"
25 
26 #include <QtCore/QCoreApplication>
27 #include <QtCore/QDateTime>
28 #include <QtCore/QFileInfo>
29 #include <QtCore/QScopedPointer>
30 #include <QtGui/QPainter>
31 #include <QVariant>
32 #include <KDebug>
33 
34 //TODO: automatically schedule pre-rendering of animation frames
35 //TODO: multithreaded SVG loading?
36 
37 static const QString cacheName(QByteArray theme)
38 {
39  const QString appName = QCoreApplication::instance()->applicationName();
40  //e.g. "themes/foobar.desktop" -> "themes/foobar"
41  if (theme.endsWith(QByteArray(".desktop")))
42  theme.truncate(theme.length() - 8); //8 = strlen(".desktop")
43  return QString::fromLatin1("kgamerenderer-%1-%2")
44  .arg(appName).arg(QString::fromUtf8(theme));
45 }
46 
47 KGameRendererPrivate::KGameRendererPrivate(KgThemeProvider* provider, unsigned cacheSize, KGameRenderer* parent)
48  : m_parent(parent)
49  , m_provider(provider)
50  , m_currentTheme(0) //will be loaded on first use
51  , m_frameSuffix(QString::fromLatin1("_%1"))
52  , m_sizePrefix(QString::fromLatin1("%1-%2-"))
53  , m_frameCountPrefix(QString::fromLatin1("fc-"))
54  , m_boundsPrefix(QString::fromLatin1("br-"))
55  //default cache size: 3 MiB = 3 << 20 bytes
56  , m_cacheSize((cacheSize == 0 ? 3 : cacheSize) << 20)
57  , m_strategies(KGameRenderer::UseDiskCache | KGameRenderer::UseRenderingThreads)
58  , m_frameBaseIndex(0)
59  , m_defaultPrimaryView(0)
60  , m_rendererPool(&m_workerPool)
61  , m_imageCache(0)
62 {
63  qRegisterMetaType<KGRInternal::Job*>();
64 }
65 
66 KGameRenderer::KGameRenderer(KgThemeProvider* provider, unsigned cacheSize)
67  : d(new KGameRendererPrivate(provider, cacheSize, this))
68 {
69  if (!provider->parent())
70  {
71  provider->setParent(this);
72  }
73  connect(provider, SIGNAL(currentThemeChanged(const KgTheme*)), SLOT(_k_setTheme(const KgTheme*)));
74 }
75 
76 static KgThemeProvider* providerForSingleTheme(KgTheme* theme, QObject* parent)
77 {
78  KgThemeProvider* prov = new KgThemeProvider(QByteArray(), parent);
79  prov->addTheme(theme);
80  return prov;
81 }
82 
83 KGameRenderer::KGameRenderer(KgTheme* theme, unsigned cacheSize)
84  : d(new KGameRendererPrivate(providerForSingleTheme(theme, this), cacheSize, this))
85 {
86 }
87 
88 KGameRenderer::~KGameRenderer()
89 {
90  //cleanup clients
91  while (!d->m_clients.isEmpty())
92  {
93  delete d->m_clients.constBegin().key();
94  }
95  //cleanup own stuff
96  d->m_workerPool.waitForDone();
97  delete d->m_imageCache;
98  delete d;
99 }
100 
101 QGraphicsView* KGameRenderer::defaultPrimaryView() const
102 {
103  return d->m_defaultPrimaryView;
104 }
105 
106 void KGameRenderer::setDefaultPrimaryView(QGraphicsView* view)
107 {
108  d->m_defaultPrimaryView = view;
109 }
110 
111 int KGameRenderer::frameBaseIndex() const
112 {
113  return d->m_frameBaseIndex;
114 }
115 
116 void KGameRenderer::setFrameBaseIndex(int frameBaseIndex)
117 {
118  d->m_frameBaseIndex = frameBaseIndex;
119 }
120 
121 QString KGameRenderer::frameSuffix() const
122 {
123  return d->m_frameSuffix;
124 }
125 
126 void KGameRenderer::setFrameSuffix(const QString& suffix)
127 {
128  d->m_frameSuffix = suffix.contains(QLatin1String("%1")) ? suffix : QLatin1String("_%1");
129 }
130 
131 KGameRenderer::Strategies KGameRenderer::strategies() const
132 {
133  return d->m_strategies;
134 }
135 
136 void KGameRenderer::setStrategyEnabled(KGameRenderer::Strategy strategy, bool enabled)
137 {
138  const bool oldEnabled = d->m_strategies & strategy;
139  if (enabled)
140  {
141  d->m_strategies |= strategy;
142  }
143  else
144  {
145  d->m_strategies &= ~strategy;
146  }
147  if (strategy == KGameRenderer::UseDiskCache && oldEnabled != enabled)
148  {
149  //reload theme
150  const KgTheme* theme = d->m_currentTheme;
151  if (theme)
152  {
153  d->m_currentTheme = 0; //or setTheme() will return immediately
154  d->_k_setTheme(theme);
155  }
156  }
157 }
158 
159 void KGameRendererPrivate::_k_setTheme(const KgTheme* theme)
160 {
161  const KgTheme* oldTheme = m_currentTheme;
162  if (oldTheme == theme)
163  {
164  return;
165  }
166  kDebug(11000) << "Setting theme:" << theme->name();
167  if (!setTheme(theme))
168  {
169  const KgTheme* defaultTheme = m_provider->defaultTheme();
170  if (theme != defaultTheme)
171  {
172  kDebug(11000) << "Falling back to default theme:" << defaultTheme->name();
173  setTheme(defaultTheme);
174  m_provider->setCurrentTheme(defaultTheme);
175  }
176  }
177  //announce change to KGameRendererClients
178  QHash<KGameRendererClient*, QString>::iterator it1 = m_clients.begin(), it2 = m_clients.end();
179  for (; it1 != it2; ++it1)
180  {
181  it1.value().clear(); //because the pixmap is outdated
182  it1.key()->d->fetchPixmap();
183  }
184  emit m_parent->themeChanged(m_currentTheme);
185 }
186 
187 bool KGameRendererPrivate::setTheme(const KgTheme* theme)
188 {
189  if (!theme)
190  {
191  return false;
192  }
193  //open cache (and SVG file, if necessary)
194  if (m_strategies & KGameRenderer::UseDiskCache)
195  {
196  QScopedPointer<KImageCache> oldCache(m_imageCache);
197  const QString imageCacheName = cacheName(theme->identifier());
198  m_imageCache = new KImageCache(imageCacheName, m_cacheSize);
199  m_imageCache->setPixmapCaching(false); //see big comment in KGRPrivate class declaration
200  //check timestamp of cache vs. last write access to theme/SVG
201  const uint svgTimestamp = qMax(
202  QFileInfo(theme->graphicsPath()).lastModified().toTime_t(),
203  theme->property("_k_themeDescTimestamp").value<uint>()
204  );
205  QByteArray buffer;
206  if (!m_imageCache->find(QString::fromLatin1("kgr_timestamp"), &buffer))
207  buffer = "0";
208  const uint cacheTimestamp = buffer.toInt();
209  //try to instantiate renderer immediately if the cache does not exist or is outdated
210  //FIXME: This logic breaks if the cache evicts the "kgr_timestamp" key. We need additional API in KSharedDataCache to make sure that this key does not get evicted.
211  if (cacheTimestamp < svgTimestamp)
212  {
213  kDebug(11000) << "Theme newer than cache, checking SVG";
214  QScopedPointer<QSvgRenderer> renderer(new QSvgRenderer(theme->graphicsPath()));
215  if (renderer->isValid())
216  {
217  m_rendererPool.setPath(theme->graphicsPath(), renderer.take());
218  m_imageCache->clear();
219  m_imageCache->insert(QString::fromLatin1("kgr_timestamp"), QByteArray::number(svgTimestamp));
220  }
221  else
222  {
223  //The SVG file is broken, so we deny to change the theme without
224  //breaking the previous theme.
225  delete m_imageCache;
226  KSharedDataCache::deleteCache(imageCacheName);
227  m_imageCache = oldCache.take();
228  kDebug(11000) << "Theme change failed: SVG file broken";
229  return false;
230  }
231  }
232  //theme is cached - just delete the old renderer after making sure that no worker threads are using it anymore
233  else if (m_currentTheme != theme)
234  m_rendererPool.setPath(theme->graphicsPath());
235  }
236  else // !(m_strategies & KGameRenderer::UseDiskCache) -> no cache is used
237  {
238  //load SVG file
239  QScopedPointer<QSvgRenderer> renderer(new QSvgRenderer(theme->graphicsPath()));
240  if (renderer->isValid())
241  {
242  m_rendererPool.setPath(theme->graphicsPath(), renderer.take());
243  }
244  else
245  {
246  kDebug(11000) << "Theme change failed: SVG file broken";
247  return false;
248  }
249  //disconnect from disk cache (only needed if changing strategy)
250  delete m_imageCache;
251  m_imageCache = 0;
252  }
253  //clear in-process caches
254  m_pixmapCache.clear();
255  m_frameCountCache.clear();
256  m_boundsCache.clear();
257  //done
258  m_currentTheme = theme;
259  return true;
260 }
261 
262 const KgTheme* KGameRenderer::theme() const
263 {
264  //ensure that some theme is loaded
265  if (!d->m_currentTheme)
266  {
267  d->_k_setTheme(d->m_provider->currentTheme());
268  }
269  return d->m_currentTheme;
270 }
271 
272 KgThemeProvider* KGameRenderer::themeProvider() const
273 {
274  return d->m_provider;
275 }
276 
277 QString KGameRendererPrivate::spriteFrameKey(const QString& key, int frame, bool normalizeFrameNo) const
278 {
279  //fast path for non-animated sprites
280  if (frame < 0)
281  {
282  return key;
283  }
284  //normalize frame number
285  if (normalizeFrameNo)
286  {
287  const int frameCount = m_parent->frameCount(key);
288  if (frameCount <= 0)
289  {
290  //non-animated sprite
291  return key;
292  }
293  else
294  {
295  frame = (frame - m_frameBaseIndex) % frameCount + m_frameBaseIndex;
296  }
297  }
298  return key + m_frameSuffix.arg(frame);
299 }
300 
301 int KGameRenderer::frameCount(const QString& key) const
302 {
303  //ensure that some theme is loaded
304  if (!d->m_currentTheme)
305  {
306  d->_k_setTheme(d->m_provider->currentTheme());
307  }
308  //look up in in-process cache
309  QHash<QString, int>::const_iterator it = d->m_frameCountCache.constFind(key);
310  if (it != d->m_frameCountCache.constEnd())
311  {
312  return it.value();
313  }
314  //look up in shared cache (if SVG is not yet loaded)
315  int count = -1;
316  bool countFound = false;
317  const QString cacheKey = d->m_frameCountPrefix + key;
318  if (d->m_rendererPool.hasAvailableRenderers() && (d->m_strategies & KGameRenderer::UseDiskCache))
319  {
320  QByteArray buffer;
321  if (d->m_imageCache->find(cacheKey, &buffer))
322  {
323  count = buffer.toInt();
324  countFound = true;
325  }
326  }
327  //determine from SVG
328  if (!countFound)
329  {
330  QSvgRenderer* renderer = d->m_rendererPool.allocRenderer();
331  //look for animated sprite first
332  count = d->m_frameBaseIndex;
333  while (renderer->elementExists(d->spriteFrameKey(key, count, false)))
334  {
335  ++count;
336  }
337  count -= d->m_frameBaseIndex;
338  //look for non-animated sprite instead
339  if (count == 0)
340  {
341  if (!renderer->elementExists(key))
342  {
343  count = -1;
344  }
345  }
346  d->m_rendererPool.freeRenderer(renderer);
347  //save in shared cache for following requests
348  if (d->m_strategies & KGameRenderer::UseDiskCache)
349  {
350  d->m_imageCache->insert(cacheKey, QByteArray::number(count));
351  }
352  }
353  d->m_frameCountCache.insert(key, count);
354  return count;
355 }
356 
357 QRectF KGameRenderer::boundsOnSprite(const QString& key, int frame) const
358 {
359  const QString elementKey = d->spriteFrameKey(key, frame);
360  //ensure that some theme is loaded
361  if (!d->m_currentTheme)
362  {
363  d->_k_setTheme(d->m_provider->currentTheme());
364  }
365  //look up in in-process cache
366  QHash<QString, QRectF>::const_iterator it = d->m_boundsCache.constFind(elementKey);
367  if (it != d->m_boundsCache.constEnd())
368  {
369  return it.value();
370  }
371  //look up in shared cache (if SVG is not yet loaded)
372  QRectF bounds;
373  bool boundsFound = false;
374  const QString cacheKey = d->m_boundsPrefix + elementKey;
375  if (!d->m_rendererPool.hasAvailableRenderers() && (d->m_strategies & KGameRenderer::UseDiskCache))
376  {
377  QByteArray buffer;
378  if (d->m_imageCache->find(cacheKey, &buffer))
379  {
380  QDataStream stream(buffer);
381  stream >> bounds;
382  boundsFound = true;
383  }
384  }
385  //determine from SVG
386  if (!boundsFound)
387  {
388  QSvgRenderer* renderer = d->m_rendererPool.allocRenderer();
389  bounds = renderer->boundsOnElement(elementKey);
390  d->m_rendererPool.freeRenderer(renderer);
391  //save in shared cache for following requests
392  if (d->m_strategies & KGameRenderer::UseDiskCache)
393  {
394  QByteArray buffer;
395  {
396  QDataStream stream(&buffer, QIODevice::WriteOnly);
397  stream << bounds;
398  }
399  d->m_imageCache->insert(cacheKey, buffer);
400  }
401  }
402  d->m_boundsCache.insert(elementKey, bounds);
403  return bounds;
404 }
405 
406 bool KGameRenderer::spriteExists(const QString& key) const
407 {
408  return this->frameCount(key) >= 0;
409 }
410 
411 QPixmap KGameRenderer::spritePixmap(const QString& key, const QSize& size, int frame, const QHash<QColor, QColor>& customColors) const
412 {
413  QPixmap result;
414  d->requestPixmap(KGRInternal::ClientSpec(key, frame, size, customColors), 0, &result);
415  return result;
416 }
417 
418 //Helper function for KGameRendererPrivate::requestPixmap.
419 void KGameRendererPrivate::requestPixmap__propagateResult(const QPixmap& pixmap, KGameRendererClient* client, QPixmap* synchronousResult)
420 {
421  if (client)
422  {
423  client->receivePixmap(pixmap);
424  }
425  if (synchronousResult)
426  {
427  *synchronousResult = pixmap;
428  }
429 }
430 
431 void KGameRendererPrivate::requestPixmap(const KGRInternal::ClientSpec& spec, KGameRendererClient* client, QPixmap* synchronousResult)
432 {
433  //NOTE: If client == 0, the request is synchronous and must be finished when this method returns. This behavior is used by KGR::spritePixmap(). Instead of KGameRendererClient::receivePixmap, the QPixmap* argument is then used to return the result.
434  //parse request
435  if (spec.size.isEmpty())
436  {
437  requestPixmap__propagateResult(QPixmap(), client, synchronousResult);
438  return;
439  }
440  const QString elementKey = spriteFrameKey(spec.spriteKey, spec.frame);
441  QString cacheKey = m_sizePrefix.arg(spec.size.width()).arg(spec.size.height()) + elementKey;
442  QHash<QColor, QColor>::const_iterator it1 = spec.customColors.constBegin(), it2 = spec.customColors.constEnd();
443  static const QString colorSuffix(QLatin1String( "-%1-%2" ));
444  for (; it1 != it2; ++it1)
445  {
446  cacheKey += colorSuffix.arg(it1.key().rgba()).arg(it1.value().rgba());
447  }
448  //check if update is needed
449  if (client)
450  {
451  if (m_clients.value(client) == cacheKey)
452  {
453  return;
454  }
455  m_clients[client] = cacheKey;
456  }
457  //ensure that some theme is loaded
458  if (!m_currentTheme)
459  {
460  _k_setTheme(m_provider->currentTheme());
461  }
462  //try to serve from high-speed cache
463  QHash<QString, QPixmap>::const_iterator it = m_pixmapCache.constFind(cacheKey);
464  if (it != m_pixmapCache.constEnd())
465  {
466  requestPixmap__propagateResult(it.value(), client, synchronousResult);
467  return;
468  }
469  //try to serve from low-speed cache
470  if (m_strategies & KGameRenderer::UseDiskCache)
471  {
472  QPixmap pix;
473  if (m_imageCache->findPixmap(cacheKey, &pix))
474  {
475  m_pixmapCache.insert(cacheKey, pix);
476  requestPixmap__propagateResult(pix, client, synchronousResult);
477  return;
478  }
479  }
480  //if asynchronous request, is such a rendering job already running?
481  if (client && m_pendingRequests.contains(cacheKey))
482  {
483  return;
484  }
485  //create job
486  KGRInternal::Job* job = new KGRInternal::Job;
487  job->rendererPool = &m_rendererPool;
488  job->cacheKey = cacheKey;
489  job->elementKey = elementKey;
490  job->spec = spec;
491  const bool synchronous = !client;
492  if (synchronous || !(m_strategies & KGameRenderer::UseRenderingThreads))
493  {
494  KGRInternal::Worker worker(job, true, this);
495  worker.run();
496  //if everything worked fine, result is in high-speed cache now
497  const QPixmap result = m_pixmapCache.value(cacheKey);
498  requestPixmap__propagateResult(result, client, synchronousResult);
499  }
500  else
501  {
502  m_workerPool.start(new KGRInternal::Worker(job, !client, this));
503  m_pendingRequests << cacheKey;
504  }
505 }
506 
507 void KGameRendererPrivate::jobFinished(KGRInternal::Job* job, bool isSynchronous)
508 {
509  //read job
510  const QString cacheKey = job->cacheKey;
511  const QImage result = job->result;
512  delete job;
513  //check who wanted this pixmap
514  m_pendingRequests.removeAll(cacheKey);
515  const QList<KGameRendererClient*> requesters = m_clients.keys(cacheKey);
516  //put result into image cache
517  if (m_strategies & KGameRenderer::UseDiskCache)
518  {
519  m_imageCache->insertImage(cacheKey, result);
520  //convert result to pixmap (and put into pixmap cache) only if it is needed now
521  //This optimization saves the image-pixmap conversion for intermediate sizes which occur during smooth resize events or window initializations.
522  if (!isSynchronous && requesters.isEmpty())
523  {
524  return;
525  }
526  }
527  const QPixmap pixmap = QPixmap::fromImage(result);
528  m_pixmapCache.insert(cacheKey, pixmap);
529  foreach (KGameRendererClient* requester, requesters)
530  {
531  requester->receivePixmap(pixmap);
532  }
533 }
534 
535 //BEGIN KGRInternal::Job/Worker
536 
537 KGRInternal::Worker::Worker(KGRInternal::Job* job, bool isSynchronous, KGameRendererPrivate* parent)
538  : m_job(job)
539  , m_synchronous(isSynchronous)
540  , m_parent(parent)
541 {
542 }
543 
544 static const uint transparentRgba = QColor(Qt::transparent).rgba();
545 
546 void KGRInternal::Worker::run()
547 {
548  QImage image(m_job->spec.size, QImage::Format_ARGB32_Premultiplied);
549  image.fill(transparentRgba);
550  QPainter* painter = 0;
551  QPaintDeviceColorProxy* proxy = 0;
552  //if no custom colors requested, paint directly onto image
553  if (m_job->spec.customColors.isEmpty())
554  {
555  painter = new QPainter(&image);
556  }
557  else
558  {
559  proxy = new QPaintDeviceColorProxy(&image, m_job->spec.customColors);
560  painter = new QPainter(proxy);
561  }
562 
563  //do renderering
564  QSvgRenderer* renderer = m_job->rendererPool->allocRenderer();
565  renderer->render(painter, m_job->elementKey);
566  m_job->rendererPool->freeRenderer(renderer);
567  delete painter;
568  delete proxy;
569 
570  //talk back to the main thread
571  m_job->result = image;
572  QMetaObject::invokeMethod(
573  m_parent, "jobFinished", Qt::AutoConnection,
574  Q_ARG(KGRInternal::Job*, m_job), Q_ARG(bool, m_synchronous)
575  );
576  //NOTE: KGR::spritePixmap relies on Qt::DirectConnection when this method is run in the main thread.
577 }
578 
579 //END KGRInternal::Job/Worker
580 
581 //BEGIN KGRInternal::RendererPool
582 
583 KGRInternal::RendererPool::RendererPool(QThreadPool* threadPool)
584  : m_valid(Checked_Invalid) //don't try to allocate renderers until given a valid SVG file
585  , m_threadPool(threadPool)
586 {
587 }
588 
589 KGRInternal::RendererPool::~RendererPool()
590 {
591  //This deletes all renderers.
592  setPath(QString());
593 }
594 
595 void KGRInternal::RendererPool::setPath(const QString& graphicsPath, QSvgRenderer* renderer)
596 {
597  QMutexLocker locker(&m_mutex);
598  //delete all renderers
599  m_threadPool->waitForDone();
600  QHash<QSvgRenderer*, QThread*>::const_iterator it1 = m_hash.constBegin(), it2 = m_hash.constEnd();
601  for (; it1 != it2; ++it1)
602  {
603  Q_ASSERT(it1.value() == 0); //nobody may be using our renderers anymore now
604  delete it1.key();
605  }
606  m_hash.clear();
607  //set path
608  m_path = graphicsPath;
609  //existence of a renderer instance is evidence for the validity of the SVG file
610  if (renderer)
611  {
612  m_valid = Checked_Valid;
613  m_hash.insert(renderer, 0);
614  }
615  else
616  {
617  m_valid = Unchecked;
618  }
619 }
620 
621 bool KGRInternal::RendererPool::hasAvailableRenderers() const
622 {
623  //look for a renderer which is not associated with a thread
624  QMutexLocker locker(&m_mutex);
625  return m_hash.key(0) != 0;
626 }
627 
628 QSvgRenderer* KGRInternal::RendererPool::allocRenderer()
629 {
630  QThread* thread = QThread::currentThread();
631  //look for an available renderer
632  QMutexLocker locker(&m_mutex);
633  QSvgRenderer* renderer = m_hash.key(0);
634  if (!renderer)
635  {
636  //instantiate a new renderer (only if the SVG file has not been found to be invalid yet)
637  if (m_valid == Checked_Invalid)
638  {
639  return 0;
640  }
641  renderer = new QSvgRenderer(m_path);
642  m_valid = renderer->isValid() ? Checked_Valid : Checked_Invalid;
643  }
644  //mark renderer as used
645  m_hash.insert(renderer, thread);
646  return renderer;
647 }
648 
649 void KGRInternal::RendererPool::freeRenderer(QSvgRenderer* renderer)
650 {
651  //mark renderer as available
652  QMutexLocker locker(&m_mutex);
653  m_hash.insert(renderer, 0);
654 }
655 
656 //END KGRInternal::RendererPool
657 
658 #include "kgamerenderer.moc"
659 #include "kgamerenderer_p.moc"
QPaintDeviceColorProxy
This QPaintDevice forwards all painting operations performed on it to the contained QPaintDevice...
Definition: colorproxy_p.h:46
cacheName
static const QString cacheName(QByteArray theme)
Definition: kgamerenderer.cpp:37
KgThemeProvider::setCurrentTheme
void setCurrentTheme(const KgTheme *theme)
Select a new theme.
Definition: kgthemeprovider.cpp:155
KGameRendererPrivate::m_strategies
KGameRenderer::Strategies m_strategies
Definition: kgamerenderer_p.h:127
KgTheme::name
QString name
Definition: kgtheme.h:75
KGameRendererPrivate::spriteFrameKey
QString spriteFrameKey(const QString &key, int frame, bool normalizeFrameNo=false) const
Definition: kgamerenderer.cpp:277
QHash::insert
iterator insert(const Key &key, const T &value)
KGameRendererPrivate::m_boundsPrefix
QString m_boundsPrefix
Definition: kgamerenderer_p.h:125
QSize::width
int width() const
KGRInternal::Worker::run
virtual void run()
Definition: kgamerenderer.cpp:546
QHash::key
const Key key(const T &value) const
QByteArray::toInt
int toInt(bool *ok, int base) const
KGRInternal::Job::cacheKey
QString cacheKey
Definition: kgamerenderer_p.h:87
KGameRendererPrivate
Definition: kgamerenderer_p.h:107
QSvgRenderer::render
void render(QPainter *painter)
QByteArray
QSize::isEmpty
bool isEmpty() const
KGRInternal::Job
Definition: kgamerenderer_p.h:83
KGRInternal::Job::spec
ClientSpec spec
Definition: kgamerenderer_p.h:86
QDataStream
KgThemeProvider
A theme provider manages KgTheme instances, and maintains a selection of the currentTheme().
Definition: kgthemeprovider.h:39
KGameRendererPrivate::m_frameBaseIndex
int m_frameBaseIndex
Definition: kgamerenderer_p.h:128
QThreadPool
KGameRendererPrivate::m_currentTheme
const KgTheme * m_currentTheme
Definition: kgamerenderer_p.h:124
QSvgRenderer::isValid
bool isValid() const
QSvgRenderer
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
KGameRenderer::boundsOnSprite
QRectF boundsOnSprite(const QString &key, int frame=-1) const
Definition: kgamerenderer.cpp:357
KgThemeProvider::addTheme
void addTheme(KgTheme *theme)
Adds a theme to this instance.
Definition: kgthemeprovider.cpp:98
KGameRendererPrivate::KGameRendererPrivate
KGameRendererPrivate(KgThemeProvider *provider, unsigned cacheSize, KGameRenderer *parent)
Definition: kgamerenderer.cpp:47
KGameRendererPrivate::m_rendererPool
KGRInternal::RendererPool m_rendererPool
Definition: kgamerenderer_p.h:132
QVariant::value
T value() const
QPixmap::fromImage
QPixmap fromImage(const QImage &image, QFlags< Qt::ImageConversionFlag > flags)
KGRInternal::RendererPool::~RendererPool
~RendererPool()
Definition: kgamerenderer.cpp:589
QHash::constFind
const_iterator constFind(const Key &key) const
KGameRendererPrivate::jobFinished
void jobFinished(KGRInternal::Job *job, bool isSynchronous)
Definition: kgamerenderer.cpp:507
QByteArray::length
int length() const
KGameRenderer::frameCount
int frameCount(const QString &key) const
Definition: kgamerenderer.cpp:301
KGameRenderer::setStrategyEnabled
void setStrategyEnabled(Strategy strategy, bool enabled=true)
Enables/disables an optimization strategy for this renderer.
Definition: kgamerenderer.cpp:136
kgamerendererclient.h
KGRInternal::Job::result
QImage result
Definition: kgamerenderer_p.h:88
KGameRenderer::~KGameRenderer
virtual ~KGameRenderer()
Deletes this KGameRenderer instance, as well as all clients using it.
Definition: kgamerenderer.cpp:88
KGameRenderer::themeProvider
KgThemeProvider * themeProvider() const
QString::fromUtf8
QString fromUtf8(const char *str, int size)
QString::insert
QString & insert(int position, QChar ch)
KGRInternal::RendererPool::freeRenderer
void freeRenderer(QSvgRenderer *renderer)
Definition: kgamerenderer.cpp:649
QObject::property
QVariant property(const char *name) const
QHash::constEnd
const_iterator constEnd() const
KGameRendererClient::receivePixmap
virtual void receivePixmap(const QPixmap &pixmap)=0
This method is called when the KGameRenderer has provided a new pixmap for this client (esp...
QImage::fill
void fill(uint pixelValue)
KGameRendererPrivate::m_workerPool
QThreadPool m_workerPool
Definition: kgamerenderer_p.h:131
QHash
KGameRenderer::setDefaultPrimaryView
void setDefaultPrimaryView(QGraphicsView *view)
Set the primary view which will be used by newly created KGameRenderedItem instances associated with ...
Definition: kgamerenderer.cpp:106
QObject
KGameRendererPrivate::setTheme
bool setTheme(const KgTheme *theme)
Definition: kgamerenderer.cpp:187
KGameRendererPrivate::m_provider
KgThemeProvider * m_provider
Definition: kgamerenderer_p.h:123
KGameRenderer::defaultPrimaryView
QGraphicsView * defaultPrimaryView() const
Definition: kgamerenderer.cpp:101
QScopedPointer
KGameRenderer
Cache-enabled rendering of SVG themes.
Definition: kgamerenderer.h:94
QList::isEmpty
bool isEmpty() const
QPainter
KGRInternal::Worker::Worker
Worker(Job *job, bool isSynchronous, KGameRendererPrivate *parent)
Definition: kgamerenderer.cpp:537
QList::removeAll
int removeAll(const T &value)
KGameRendererPrivate::m_frameSuffix
QString m_frameSuffix
Definition: kgamerenderer_p.h:125
QByteArray::number
QByteArray number(int n, int base)
QHash::begin
iterator begin()
KGameRenderer::strategies
Strategies strategies() const
Definition: kgamerenderer.cpp:131
kgamerenderer_p.h
KGameRenderer::theme
const KgTheme * theme() const
KGameRendererPrivate::m_sizePrefix
QString m_sizePrefix
Definition: kgamerenderer_p.h:125
QByteArray::truncate
void truncate(int pos)
KGRInternal::RendererPool::RendererPool
RendererPool(QThreadPool *threadPool)
Definition: kgamerenderer.cpp:583
QCoreApplication::instance
QCoreApplication * instance()
KGameRendererPrivate::m_cacheSize
unsigned m_cacheSize
Definition: kgamerenderer_p.h:126
KGameRendererPrivate::m_clients
QHash< KGameRendererClient *, QString > m_clients
Definition: kgamerenderer_p.h:134
QString
QList
QColor
KgTheme::graphicsPath
QString graphicsPath
Definition: kgtheme.h:79
KGameRendererPrivate::requestPixmap
void requestPixmap(const KGRInternal::ClientSpec &spec, KGameRendererClient *client, QPixmap *synchronousResult=0)
Definition: kgamerenderer.cpp:431
KGRInternal::RendererPool::setPath
void setPath(const QString &graphicsPath, QSvgRenderer *renderer=0)
Definition: kgamerenderer.cpp:595
QHash::keys
QList< Key > keys() const
QPixmap
QFileInfo
providerForSingleTheme
static KgThemeProvider * providerForSingleTheme(KgTheme *theme, QObject *parent)
Definition: kgamerenderer.cpp:76
QHash::clear
void clear()
QHash::value
const T value(const Key &key) const
kgamerenderer.h
KGameRendererPrivate::m_boundsCache
QHash< QString, QRectF > m_boundsCache
Definition: kgamerenderer_p.h:160
QObject::setParent
void setParent(QObject *parent)
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QSize
KGameRendererPrivate::m_parent
KGameRenderer * m_parent
Definition: kgamerenderer_p.h:121
transparentRgba
static const uint transparentRgba
Definition: kgamerenderer.cpp:544
QImage
QMetaObject::invokeMethod
bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0, QGenericArgument val1, QGenericArgument val2, QGenericArgument val3, QGenericArgument val4, QGenericArgument val5, QGenericArgument val6, QGenericArgument val7, QGenericArgument val8, QGenericArgument val9)
KgThemeProvider::defaultTheme
const KgTheme * defaultTheme() const
Definition: kgthemeprovider.cpp:113
KGameRendererClient
An object that receives pixmaps from a KGameRenderer.
Definition: kgamerendererclient.h:50
QThreadPool::waitForDone
void waitForDone()
QSvgRenderer::boundsOnElement
QRectF boundsOnElement(const QString &id) const
QHash::constBegin
const_iterator constBegin() const
colorproxy_p.h
KGRInternal::ClientSpec::frame
int frame
Definition: kgamerenderer_p.h:39
KGameRenderer::Strategy
Strategy
Describes the various strategies which KGameRenderer can use to speed up rendering.
Definition: kgamerenderer.h:103
KGameRenderer::setFrameSuffix
void setFrameSuffix(const QString &suffix)
Sets the frame suffix.
Definition: kgamerenderer.cpp:126
KGRInternal::Job::rendererPool
KGRInternal::RendererPool * rendererPool
Definition: kgamerenderer_p.h:85
QLatin1String
KGameRenderer::themeChanged
void themeChanged(const KgTheme *theme)
QHash::isEmpty
bool isEmpty() const
QMutexLocker
KGameRenderer::setFrameBaseIndex
void setFrameBaseIndex(int frameBaseIndex)
Sets the frame base index, i.e.
Definition: kgamerenderer.cpp:116
QThread::currentThread
QThread * currentThread()
QRectF
KGRInternal::RendererPool::hasAvailableRenderers
bool hasAvailableRenderers() const
Definition: kgamerenderer.cpp:621
QSvgRenderer::elementExists
bool elementExists(const QString &id) const
KgThemeProvider::currentTheme
const KgTheme currentTheme
Definition: kgthemeprovider.h:42
KGameRenderer::UseDiskCache
If set, pixmaps will be cached in a shared disk cache (using KSharedDataCache).
Definition: kgamerenderer.h:109
KGameRendererPrivate::m_frameCountCache
QHash< QString, int > m_frameCountCache
Definition: kgamerenderer_p.h:159
kgthemeprovider.h
QSize::height
int height() const
KGameRendererPrivate::m_pixmapCache
QHash< QString, QPixmap > m_pixmapCache
Definition: kgamerenderer_p.h:158
KGameRendererPrivate::_k_setTheme
void _k_setTheme(const KgTheme *theme)
Definition: kgamerenderer.cpp:159
KGameRendererPrivate::m_defaultPrimaryView
QGraphicsView * m_defaultPrimaryView
Definition: kgamerenderer_p.h:129
QString::fromLatin1
QString fromLatin1(const char *str, int size)
KGRInternal::RendererPool::allocRenderer
QSvgRenderer * allocRenderer()
Definition: kgamerenderer.cpp:628
KGRInternal::ClientSpec::spriteKey
QString spriteKey
Definition: kgamerenderer_p.h:38
KgTheme::identifier
QByteArray identifier
Definition: kgtheme.h:71
KGameRenderer::spriteExists
bool spriteExists(const QString &key) const
Definition: kgamerenderer.cpp:406
KGameRenderer::UseRenderingThreads
If set, pixmap requests from KGameRendererClients will be handled asynchronously if possible...
Definition: kgamerenderer.h:113
KGameRenderer::KGameRenderer
KGameRenderer(KgThemeProvider *prov, unsigned cacheSize=0)
Constructs a new KGameRenderer that renders prov->currentTheme().
Definition: kgamerenderer.cpp:66
KGameRendererPrivate::m_imageCache
KImageCache * m_imageCache
Definition: kgamerenderer_p.h:137
KgTheme
A theme describes the visual appearance of a game.
Definition: kgtheme.h:68
QHash::end
iterator end()
KGameRenderer::spritePixmap
QPixmap spritePixmap(const QString &key, const QSize &size, int frame=-1, const QHash< QColor, QColor > &customColors=(QHash< QColor, QColor >())) const
Definition: kgamerenderer.cpp:411
KGRInternal::ClientSpec
Definition: kgamerenderer_p.h:33
KGRInternal::Job::elementKey
QString elementKey
Definition: kgamerenderer_p.h:87
QThreadPool::start
void start(QRunnable *runnable, int priority)
KGRInternal::ClientSpec::size
QSize size
Definition: kgamerenderer_p.h:40
QThread
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
QScopedPointer::take
T * take()
KGRInternal::ClientSpec::customColors
QHash< QColor, QColor > customColors
Definition: kgamerenderer_p.h:41
KGRInternal::Worker
Definition: kgamerenderer_p.h:92
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QGraphicsView
KGameRendererPrivate::m_frameCountPrefix
QString m_frameCountPrefix
Definition: kgamerenderer_p.h:125
KGameRendererPrivate::m_pendingRequests
QStringList m_pendingRequests
Definition: kgamerenderer_p.h:135
QByteArray::endsWith
bool endsWith(const QByteArray &ba) const
KGameRenderer::frameSuffix
QString frameSuffix() const
Definition: kgamerenderer.cpp:121
QCoreApplication::applicationName
applicationName
QColor::rgba
QRgb rgba() const
KGameRenderer::frameBaseIndex
int frameBaseIndex() const
Definition: kgamerenderer.cpp:111
kgtheme.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:18:42 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

libkdegames

Skip menu "libkdegames"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdegames API Reference

Skip menu "kdegames API Reference"
  • granatier
  • kapman
  • kblackbox
  • kgoldrunner
  • kigo
  • kmahjongg
  • KShisen
  • ksquares
  • libkdegames
  •   highscore
  •   libkdegamesprivate
  •     kgame
  • libkmahjongg
  • palapeli
  •   libpala

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal