[Kde-games-devel] Fwd: KDE/kdegames (Highscores)

Matt Williams matt at milliams.com
Sun Apr 8 16:23:31 CEST 2007


Hi all, I've been doing some work on the libkdegames highscore system 
recently. I've been working on getting system-wide highscores working,as 
mentioned in the last meeting. This is being done in the KHighscore class 
which is essentially a convenience wrapper around KConfig.

Due to KExtHighscore being in such a mess at the moment I would recommend to 
anyone wanting to implement a simple sighscore table in their game to use 
KScoreDialog. Despite its name, it isn't just a dialog. It also acts as an 
interface with KHighscore to handle highscore table entries.

It's still not perfect and I'm expecting few bugs to still be around but don't 
hesitate to poke me to fix them.

Just letting you know what's going on with the highscore system.

Matt Williams

----------  Forwarded Message  ----------

Subject: KDE/kdegames
Date: Sunday 08 April 2007
From: Matt Williams <matt at milliams.com>
To: kde-commits at kde.org

SVN commit 651579 by milliams:

Start to port system-wide highscores in KHighscore
Port KScoreDialog to use KHighscore

 _M            . (directory)  
 M  +1 -3      CMakeLists.txt  
 M  +17 -11    libkdegames/highscore/khighscore.cpp  
 M  +6 -4      libkdegames/highscore/khighscore.h  
 M  +41 -39    libkdegames/highscore/kscoredialog.cpp  
 M  +1 -1      libkdegames/highscore/kscoredialog.h  


** trunk/KDE/kdegames #property svn:ignore
   - configure.in
aclocal.m4
acinclude.m4
stamp-h.in
config.h.in
Makefile.in
configure
SUBDIRS
config.h
inst-apps
stamp-h
Makefile
stamp-h1.in
stamp-h1
libtool
configure.files
subdirs
autom4te.cache
Makefile.am
.autoconf_trace
makekdegames
makelibkdegames
update
--- trunk/KDE/kdegames/CMakeLists.txt #651578:651579
@@ -10,7 +10,7 @@
 
 add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
 include_directories ( ${QDBUS_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR} 
${CMAKE_BINARY_DIR} ${KDE4_INCLUDES})
-set(HIGHSCORE_DIRECTORY "" CACHE STRING "whether to use system-wide 
highscores")
+set(HIGHSCORE_DIRECTORY "" CACHE STRING "Where to install system-wide 
highscores e.g. /var/games")
 
 add_subdirectory(libkdegames)
 if(NOT WIN32)
@@ -51,5 +51,3 @@
 macro_optional_add_subdirectory(kwin4)
 
 add_subdirectory( cmake )
-
-
--- trunk/KDE/kdegames/libkdegames/highscore/khighscore.cpp #651578:651579
@@ -48,9 +48,11 @@
 };
 
 KLockFile *KHighscore::_lock = 0;
-KRawConfig *KHighscore::_config = 0;
+//KRawConfig *KHighscore::_config = 0;
+KConfig *KHighscore::_config = 0;
 static KStaticDeleter<KLockFile> lockSD;
-static KStaticDeleter<KRawConfig> configSD;
+//static KStaticDeleter<KRawConfig> configSD;
+static KStaticDeleter<KConfig> configSD;
 
 KHighscore::KHighscore(bool forceLocal, QObject* parent)
     : QObject(parent)
@@ -63,7 +65,7 @@
     d = new KHighscorePrivate;
 #ifdef HIGHSCORE_DIRECTORY
     d->global = !forceLocal;
-    if ( d->global && _lock==0 )
+    if ( d->global && _lock==0 )    //If we're doing global highscores but 
not KFileLock has been set up yet
         kFatal(11002) << "KHighscore::init should be called before!!" << 
endl;
 #else
     d->global = false;
@@ -88,13 +90,17 @@
     const QString filename =  QString::fromLocal8Bit("%1/%2.scores")
                               .arg(HIGHSCORE_DIRECTORY).arg(appname);
     //int fd = fopen(filename.toLocal8Bit(), O_RDWR);
-    QFile file(filename);
+    /*QFile file(filename);
     if ( !file.open(QIODevice::ReadWrite) ) kFatal(11002) << "cannot open 
global highscore file \""
-                               << filename << "\"" << endl;
-    lockSD.setObject(_lock, new KFileLock(filename));
-    configSD.setObject(_config, new KRawConfig(file.handle(), true)); // 
read-only
+                               << filename << "\"" << endl;*/
+    /*if (!(QFile::permissions(filename) & QFile::WriteOwner)) kFatal(11002) 
<< "cannot write to global highscore file \""
+                << filename << "\"" << endl;*/
+    kDebug() << "Global highscore file \"" << filename << "\"" << endl;
+    lockSD.setObject(_lock, new KLockFile(filename));
+    configSD.setObject(_config, new KConfig(filename, 
KConfig::OpenFlags(KConfig::NoGlobals | KConfig::OnlyLocal))); // read-only   
(matt-?)
 
     // drop the effective gid
+    #warning not portable yet. Unix only
     int gid = getgid();
     setregid(gid, gid);
 #else
@@ -172,10 +178,10 @@
 
 void KHighscore::writeEntry(int entry, const QString& key, const QString 
&value)
 {
- Q_ASSERT (isLocked() );
- KConfigGroup cg(config(), group());
- QString confKey = QString("%1_%2").arg(entry).arg(key);
- cg.writeEntry(confKey, value);
+    Q_ASSERT (isLocked() );
+    KConfigGroup cg(config(), group());
+    QString confKey = QString("%1_%2").arg(entry).arg(key);
+    cg.writeEntry(confKey, value);
 }
 
 QVariant KHighscore::readPropertyEntry(int entry, const QString& key, const 
QVariant& pDefault) const
--- trunk/KDE/kdegames/libkdegames/highscore/khighscore.h #651578:651579
@@ -29,15 +29,16 @@
 #include <kglobal.h>
 class KConfig;
 class KLockFile;
-class KRawConfig;
+//class KRawConfig;
+class KConfig;
 class KHighscorePrivate;
 
 /**
  * @short Class for managing highscore tables
  *
  * This is the KDE class for saving and reading highscore tables. It offers 
the
- * possibility for system-wide highscore tables (configure with e.g.
- * --enable-highscore-dir=/var/games) and a theoretically unlimited number of
+ * possibility for system-wide highscore tables (cmake with e.g.
+ * -DHIGHSCORE_DIRECTORY=/var/games) and a theoretically unlimited number of
  * entries.
  *
  * You can specify different "keys" for an entry - just like the KConfig
@@ -291,7 +292,8 @@
         KHighscorePrivate* d;
 
         static KLockFile *_lock; // lock on system-wide highscore file
-        static KRawConfig *_config; // config for system-wide highscore file
+        //static KRawConfig *_config; // config for system-wide highscore 
file
+        static KConfig *_config; // config for system-wide highscore file
 };
 
 #endif
--- trunk/KDE/kdegames/libkdegames/highscore/kscoredialog.cpp #651578:651579
@@ -37,6 +37,7 @@
 #include <kglobal.h>
 #include <kconfiggroup.h>
 
+#include "khighscore.h"
 #include "kscoredialog.h"
 
 class KScoreDialog::KScoreDialogPrivate
@@ -56,6 +57,7 @@
    int nrCols;
    bool loaded;
    QString configGroup;
+   KHighscore* highscoreObject;
 
    QMap<int, int> col;
    QMap<int, QString> header;
@@ -69,6 +71,7 @@
 {
     setCaption( i18n("High Scores") );
     setModal( true );
+    d->highscoreObject = new KHighscore();
    d->edit = 0;
    d->fields = fields;
    d->newName = -1;
@@ -271,53 +274,51 @@
 
 void KScoreDialog::loadScores()
 {
-   QString key, value;
-   d->loaded = true;
-   qDeleteAll( d->scores );
-   d->scores.clear();
-   KConfigGroup config(KGlobal::config(), d->configGroup.toUtf8());
+    QString key, value;
+    d->loaded = true;
+    qDeleteAll( d->scores );
+    d->scores.clear();
+    d->highscoreObject->setHighscoreGroup(d->configGroup.toUtf8());
 
-   d->player = config.readEntry("LastPlayer");
+    d->player = d->highscoreObject->readEntry(0,"LastPlayer");
 
-   QString num;
-   for (int i = 1; i <= 10; ++i) {
-      num.setNum(i);
-      FieldInfo *score = new FieldInfo();
-      for(int field = 1; field < d->fields; field = field * 2)
-      {
-         if (d->fields & field)
-         {
-            key = "Pos" + num + d->key[field];
-            (*score)[field] = config.readEntry(key, QString("-"));
-         }
-      }
-      d->scores.append(score);
-   }
+    QString num;
+    for (int i = 1; i <= 10; ++i)
+    {
+        FieldInfo *score = new FieldInfo();
+        for(int field = 1; field < d->fields; field = field * 2)
+        {
+            if (d->fields & field)
+            {
+                (*score)[field] = d->highscoreObject->readEntry(i, 
d->key[field], QString("-"));
+            }
+        }
+        d->scores.append(score);
+    }
 }
 
 void KScoreDialog::saveScores()
 {
-   QString key, value;
-   KConfigGroup config(KGlobal::config(), d->configGroup.toUtf8());
-
-   config.writeEntry("LastPlayer", d->player);
-
-   QString num;
-   for (int i = 1; i <= 10; ++i) {
-      num.setNum(i);
-      FieldInfo *score = d->scores.at(i-1);
-      for(int field = 1; field < d->fields; field = field * 2)
-      {
-         if (d->fields & field)
-         {
-            key = "Pos" + num + d->key[field];
-            config.writeEntry(key, (*score)[field]);
-         }
-      }
-   }
-   KGlobal::config()->sync();
+    QString key, value;
+    d->highscoreObject->setHighscoreGroup(d->configGroup.toUtf8());
+    
+    d->highscoreObject->writeEntry(0,"LastPlayer", d->player);
+    
+    for (int i = 1; i <= 10; ++i)
+    {
+        FieldInfo *score = d->scores.at(i-1);
+        for(int field = 1; field < d->fields; field = field * 2)
+        {
+            if (d->fields & field)
+            {
+                d->highscoreObject->writeEntry(i, d->key[field], (*score)
[field]);
+            }
+        }
+    }
+    KGlobal::config()->sync();
 }
 
+//deprecated
 int KScoreDialog::addScore(int newScore, const FieldInfo &newInfo, bool 
askName)
 {
    return addScore(newScore, newInfo, askName, false);
@@ -365,6 +366,7 @@
     return 0;
 }
 
+//deprecated
 int KScoreDialog::addScore(int newScore, const FieldInfo &newInfo, bool 
askName, bool lessIsMore)
 {
    if (!d->loaded)
--- trunk/KDE/kdegames/libkdegames/highscore/kscoredialog.h #651578:651579
@@ -134,7 +134,7 @@
         void setupDialog();
         void keyPressEvent( QKeyEvent *ev);
 
-    private:           
+    private:
         class KScoreDialogPrivate;
         KScoreDialogPrivate* const d;
 };

-------------------------------------------------------

-- 
Matt Williams
http://milliams.com


More information about the kde-games-devel mailing list