[Kde-games-devel] Draft for the core KgTheme API

Stefan Majewsky stefan.majewsky at googlemail.com
Thu Mar 15 22:48:17 UTC 2012


On Thu, Mar 15, 2012 at 4:22 AM, Parker Coates <coates at kde.org> wrote:
> See kdegames/kpat/libkcardgame/kcardtheme.h. Obviously it's not an
> apples to apples comparison, but there's plenty of common requirements.

Interesting read. KgTheme does not have anything like
KCardTheme::supportedFeatures, but a filtering API can be added to
KgThemeProvider. And of course KCardTheme could not use the discovery
algorithms from KgTheme, which operate on files rather than
directories.

> Don't
> judge too harshly, though as I have some in improvements in progress
> in a work branch. :)

apidox? *hint hint*

> The main highlights:
> * KCardTheme objects have no non-const methods (including setters). I
> couldn't find a use case in which a theme object ever needed to change
> after its creation.

KgTheme implements this via simple runtime assertions, in a way that
is identical to how KgDifficultyLevel constness is ensured. Granted,
KgDifficultyLevel does not have non-const methods, but subclasses
could add some. Subclassing KgDifficultyLevel and KgTheme is
explicitly supported, although KgTheme needs some extensions to
actually embrace it.

> * KCardTheme objects are implicitly shared, so they are always passed
> by value. Because pointers are never used, one never needs to worry
> about who "owns" the theme object and needs to delete it. As a bonus,
> because all methods are const, copies never detach.

Hm, it did not occur to me that KgTheme (and KgDifficultyLevel, for
that matter) have value semantics. They do, but still I'm more
comfortable with object semantics: First, I don't have to worry about
who deletes the instances when there's a KgThemeProvider. Second,
"const KgTheme&" looks like something I can easily copy and modify if
I like. "const KgTheme*" states more clearly that there is an object
which you can look at but don't you dare copy it.

> * Finding themes is done with a single static method and there's no
> notion of a provider. KgThemeProvider mainly provides methods for
> setting and getting the current and default themes, but personally I'd
> much rather use KConfig(XT) for this.

First, input accepted: I'll make the discovery logic available from
KgTheme if one does not like to use KgThemeProvider.

Re KConfig(XT), why would you rather use it for this? Storing and
restoring a theme selection is boiler-plate that can be trivially
automated.

Plus, KgThemeProvider gives you automatic propagation of the theme
selection to KGameRenderer. In KPat, for example, you'd only have to
connect KgThemeProvider::currentThemeChanged to Dealer::relayoutScene
manually. Everything else in MainWindow::appearanceChanged is gone.

And then, there's QML. As far as I can see, calling from QML into C++
code, even if only for a single KConfig(XT) method call, usually
generates a disproportional amount of boilerplate code. Then it's even
nicer if this stuff just happens by itself.

I actually plan to go further on this road and add
KgAudioScene::enableSounds() and a corresponding KStandardGameAction.
I like that e.g. Bomber and Kapman could then completely drop their
KConfigXT files since everything in there has moved into libkdegames.
I honestly did not expect these changes to be controversial.



Please don't take this as if I try to force this upon you. My
reasoning behind about every component I added to libkdegames in the
last years was to move code complexity either into the library (where
possible) or into the initialization. The second part is important for
the big picture.

When I started, about all KDE games had a big bunch of code that just
deals with updates following theme changes or window resize events. A
part of KGameRenderer's original intention was to get rid of this
update code by letting the framework do as much as possible of it
automagically. This pattern is not as important in KgAudio, since
there are no big updates necessary until we introduce sound themes,
but the fire-and-forget usage of KgSound::start() is reminiscent of
the original intent.

KgDifficulty and KgThemeProvider finally fully implement what one
could call the construct-and-forget pattern. You set up these objects,
perhaps wire up one change signal, and you'll never have to worry
about them again. The construct-and-forget pattern is also a guiding
principle behind QML: A QML file is basically a huge constructor for a
QML element with multitudes of subelements.

In a way, that's my contribution to the QML-readiness of libkdegames.
Sorry if this was too long of a read (I can't even think of a good
tl;dr) and thanks that you made it all the way through.

Greetings
Stefan


More information about the kde-games-devel mailing list