Difference between revisions of "Projects/Games/Porting to libkdegames v5"

Jump to: navigation, search
m (QLatin1String -> QStringLiteral)
(Moved to Community Wiki)
 
Line 1: Line 1:
This document describes the changes introduced with libkdegames v5, which first appeared in the KDE 4.9 release.
+
{{Moved_To_Community|Projects/Games/Porting_to_libkdegames_v5}}
== New components ==
 
 
 
* '''KgSound''' provides a simple API for playback of short event sounds. Low latency is achieved through the use of OpenAL, with a Phonon fallback if the required libraries are not available.
 
 
 
Also, multiple new components have been added which replace existing components. These can be identified by the common class name prefix "Kg". See [[#Reworked components|Reworked components]] for details.
 
 
 
== Removed components ==
 
 
 
* The '''KGGZ''' framework has been removed completely.
 
* '''KGameLCD''' — Use QLCDNumber instead.
 
* '''KGameMisc''' — Instead of a random name, we advise to use generic names where appropriate.
 
* '''KGameProgress''' — Use QProgressBar instead.
 
* '''KGameSvgDigits''' — If you need SVG digits, include them in your own SVG theme.
 
* '''KGrid2D''' — You'll need to do the math yourself.
 
 
 
== Reworked components ==
 
 
 
=== Difficulty ===
 
 
 
'''KGameDifficulty''' has been replaced by the '''KgDifficulty''' and '''KgDifficultyLevel''' classes. KgDifficulty stores the current level by itself, and allows for multiple KgDifficulty instances at the same time, although a singleton is provided by the Kg::difficulty() function. The following table shows how to port common uses of KGameDifficulty to this singleton:
 
 
 
{| border="1" cellpadding="5" cellspacing="0" style="border: gray solid 1px; border-collapse: collapse; text-align: left; width:100%;"
 
|- style="background: #ececec; white-space:nowrap;"
 
! Replace this...
 
! ...by this
 
! Comment
 
|- style="border:gray solid 1px; border-collapse: collapse;"
 
| style="white-space:nowrap" | <tt>KGameDifficulty::standardLevel</tt>
 
| style="white-space:nowrap" | <tt>KgDifficultyLevel::StandardLevel</tt>
 
|
 
|- style="border:gray solid 1px; border-collapse: collapse;"
 
| style="white-space:nowrap" | <tt>KGameDifficulty::Medium etc.</tt>
 
| style="white-space:nowrap" | <tt>KgDifficultyLevel::Medium etc.</tt>
 
|
 
|- style="border:gray solid 1px; border-collapse: collapse;"
 
| style="white-space:nowrap" | <tt>KGameDifficulty::addStandardLevel(level)</tt>
 
| style="white-space:nowrap" | <tt>Kg::difficulty()->addStandardLevel(level)</tt>
 
| As a convenience, consider to use the new <tt>addStandardLevelRange()</tt> method.
 
|- style="border:gray solid 1px; border-collapse: collapse;"
 
| rowspan="2" style="white-space:nowrap" | <tt>KGameDifficulty::init<br/>(window, receiver, slot)</tt>
 
| style="white-space:nowrap" | <tt>KgDifficultyGUI::init(window);</tt>
 
|
 
|- style="border:gray solid 1px; border-collapse: collapse;"
 
| style="white-space:nowrap" | <tt>QObject::connect(Kg::difficulty(),<br/>SLOT(currentLevelChanged(const KgDifficultyLevel*)),<br/>receiver, slot);</tt>
 
| Change the slot to the new signature. The old signature contained a standard level argument: Use the "standardLevel" property of the new argument instead.
 
|- style="border:gray solid 1px; border-collapse: collapse;"
 
| style="white-space:nowrap" | <tt>KGameDifficulty::level()</tt>
 
| style="white-space:nowrap" | <tt>Kg::difficultyLevel()</tt>
 
|
 
|- style="border:gray solid 1px; border-collapse: collapse;"
 
| style="white-space:nowrap" | <tt>KGameDifficulty::setLevel(level)</tt>
 
| style="white-space:nowrap" | <tt>Kg::difficulty()->select(level)</tt>
 
| If used to restore the selected difficulty from the config file, delete the whole call and your custom config key. KgDifficulty remembers the level selection by itself. Please refer to the APIDOX for details, e.g. how to specify a default difficulty for the first run.
 
|- style="border:gray solid 1px; border-collapse: collapse;"
 
| style="white-space:nowrap" | <tt>KGameDifficulty::levelWeights(),<br />KGameDifficulty::localizedLevelStrings(),</tt><br/>etc. while setting up a KScoreDialog
 
| style="white-space:nowrap" | <tt>dialog->initFromDifficulty(Kg::difficulty());</tt>
 
| If you need the QMaps from these KGameDifficulty functions, you can construct them by iterating over the <tt>KgDifficultyLevel</tt>s. <tt>levelWeights</tt> maps <tt>hardness-&gt;key</tt> and <tt>localizedLevelStrings</tt> maps <tt>key-&gt;title</tt>.
 
|- style="border:gray solid 1px; border-collapse: collapse;"
 
| style="white-space:nowrap" | <tt>KGameDifficulty::setRestartOnChange(roc)</tt>
 
| rowspan="2" style="white-space:nowrap" | <tt>Kg::difficulty()->setGameRunning(roc && running)</tt>
 
| rowspan="2" | These two properties of KGameDifficulty are redundant: If both are true, the user will be asked for confirmation before the level is changed. If you do not want this, just do not use the <tt>setGameRunning</tt> method.
 
|- style="border:gray solid 1px; border-collapse: collapse;"
 
| style="white-space:nowrap" | <tt>KGameDifficulty::setRunning(running)</tt>
 
|- style="border:gray solid 1px; border-collapse: collapse;"
 
| style="white-space:nowrap" | <tt>KGameDifficulty::setEnabled()</tt>
 
| style="white-space:nowrap" | <tt>Kg::difficulty()->setEditable()</tt>
 
| The property has been renamed to clarify its purpose.
 
|}
 
 
 
=== Theming and KGameRenderer ===
 
 
 
'''KGameTheme''' has been replaced by the '''KgTheme''' and '''KgThemeProvider''' classes, which generalize its behavior, overcome several hardcoded assumptions and offer some additional convenience.
 
 
 
KGameTheme implicitly looks for themes in KStandardDirs::locate("appdata", "themes"). KgTheme expects you to discover themes with a KgThemeProvider. The following mimics the old KGameTheme behavior:
 
 
 
<syntaxhighlight lang="cpp-qt">
 
KgThemeProvider* provider = new KgThemeProvider(QByteArray(), parent);
 
provider->discoverThemes("appdata", QStringLiteral("themes"));
 
</syntaxhighlight>
 
 
 
If you want to use KgThemeProvider's functionality to automatically save the selected theme, give a non-empty value in the first parameter (see documentation). The default is "Theme". The following explanations will assume that you use this new functionality.
 
 
 
'''KGameRenderer'''<nowiki></nowiki>'s constructor syntax has changed. If you use KGameRenderer, give a KgThemeProvider to it:
 
 
 
<syntaxhighlight lang="cpp-qt">
 
//before
 
KGameRenderer renderer("themes/default.desktop");
 
//after
 
KGameRenderer renderer(provider);
 
</syntaxhighlight>
 
 
 
And redirect the <tt>setTheme()</tt> calls to KgThemeProvider:
 
 
 
<syntaxhighlight lang="cpp-qt">
 
//before
 
renderer.setTheme("themes/default.desktop");
 
//after
 
provider->setCurrentTheme(provider->defaultTheme());
 
</syntaxhighlight>
 
 
 
Themes in the context of KgThemeProvider are KgTheme instances, rather than simple strings. The valid instances are usually created with <tt>discoverThemes()</tt>, and can be retrieved with the <tt>themes()</tt> method.
 
 
 
The <tt>KGameRenderer::themeChanged(QString)</tt> signal is replaced by <tt>KgThemeProvider::currentThemeChanged(const KgTheme*)</tt>.
 
 
 
Replace '''KGameThemeSelector''' by the new '''KgThemeSelector''' class.
 
 
 
<syntaxhighlight lang="cpp-qt">
 
//before
 
KGameThemeSelector selector(parent, Settings::self(),
 
    KGameThemeSelector::NewStuffEnableDownload);
 
//after
 
KgThemeSelector selector(provider,
 
    KgThemeSelector::EnableNewStuffDownload, parent);
 
</syntaxhighlight>
 
 
 
If the theme selector is the only page in your KConfigDialog, you can discard the dialog and use KgThemeSelector's stand-alone behavior:
 
 
 
<syntaxhighlight lang="cpp-qt">
 
//simple example
 
selector->showAsDialog();
 
//complex example
 
KStandardGameAction::preferences(selector, SLOT(showAsDialog()), actionCollection());
 
</syntaxhighlight>
 
 
 
Just constructing and displaying a KgThemeSelector is enough if you use automatic theme selection saving. Since KgThemeSelector applies selection changes automatically, you need to listen to <tt>KgThemeProvider::currentThemeChanged</tt> if you need to act on theme changes manually.
 
 
 
Any manual selection saving code can be discarded. Selections in the KgThemeSelector will automatically be saved to the application config file.  Since KgThemeProvider always saves in the <tt>[KgTheme]</tt> config group, you might need to migrate the old configuration key. Refer to the [[Development/Tools/Using_kconf_update|kconf_update documentation]] for details, or look at the update script for the kdegames module (in the libkdegames source tree).
 
 
 
== Build system changes ==
 
 
 
If you use a version of libkdegames from before the 4.9 release, you're CMakeLists.txt looks like this:
 
 
 
<syntaxhighlight lang="cmake">
 
find_package(KDE4 REQUIRED)
 
include(KDE4Defaults)
 
find_package(LibKDEGames REQUIRED)
 
 
 
add_definitions(${QT4_DEFINITIONS} ${KDE4_DEFINITIONS}
 
include_directories(${KDE4_INCLUDES} ${KDEGAMES_INCLUDE_DIRS})
 
 
 
...
 
 
 
target_link_libraries(mytarget ${KDEGAMES_LIBRARY})
 
</syntaxhighlight>
 
 
 
Because the old LibKDEGames package did not have a way to specify versions, we had to change the package name. libkdegames v5 is found by the "KDEGames" package, that is: The third line in the snippet above becomes
 
 
 
<syntaxhighlight lang="cmake">
 
find_package(KDEGames REQUIRED)
 
</syntaxhighlight>
 
 
 
The old LibKDEGames package and the new KDEGames package both set the same variables (with the same semantics), so no porting needed there:
 
 
 
<syntaxhighlight lang="cmake">
 
${KDEGames_FOUND}
 
${KDEGAMES_LIBRARY}
 
${KDEGAMES_INCLUDE_DIR}
 
${KDEGAMES_INCLUDE_DIRS}
 
</syntaxhighlight>
 
 
 
You can setup your build system such that you can use either the old or new libkdegames, depending on what's available. For example, replace the <tt>find_package(KDEGames)</tt> line by
 
 
 
<syntaxhighlight lang="cmake">
 
find_package(KDEGames)
 
if (KDEGames_FOUND)
 
    add_definitions(-DNEW_LIBKDEGAMES)
 
else (KDEGames_FOUND)
 
    find_package(LibKDEGames REQUIRED)
 
    add_definitions(-DOLD_LIBKDEGAMES)
 
endif (KDEGames_FOUND)
 
</syntaxhighlight>
 
 
 
Then use the defines <tt>NEW_LIBKDEGAMES</tt> and <tt>OLD_LIBKDEGAMES</tt> in your code.
 

Latest revision as of 13:14, 7 June 2019

This page is now on the community wiki.


This page was last edited on 7 June 2019, at 13:14. Content is available under Creative Commons License SA 4.0 unless otherwise noted.