[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-pim
Subject:    [Kde-pim] [RFC] KRES::Resource class for KDE 4.0
From:       Tobias Koenig <tokoe () kde ! org>
Date:       2005-03-19 15:48:48
Message-ID: 20050319154848.GA26013 () ghostdog ! localnet
[Download RAW message or body]

[Attachment #2 (multipart/signed)]

[Attachment #4 (multipart/mixed)]


Hi,

attached is a first idea of how the KRES::Resource class should look
like in KDE 4.0.

I tried to design it concerning the two most important needs:
asynchronous access and a constraining API, so that the people which
have to implement the subclasses can't do anything wrong (that is a main
problem with the current version).

To make everything asynchronous, all access methods use signals to
report success or failure. The signals are emitted queued, so they are
not executed directly, but delivered when the event loop is reentered
again. That has the big advantage, that the 3rd party developer of
subclasses can emit the signals whenever they want (directly from open(),
from another thread or as result of an KIO slave), and we as application
developer have always the same behaviour of KRES::Resource.

I left out the 'configuration' stuff ATM, because we should discuss this
a bit more in detail. IMHO the resource should be 'configured' by an
external class like 'ResourceManager' and not read/store the
configuration itself.

Nevertheless the API isn't perfect yet and constructive critic is always
welcome.

Ciao,
Tobias
-- 
Separate politics from religion and economy!
The Councile of the European Union is an undemocratic and illegal institution!

["resource.cpp" (text/x-c++src)]

/*
    This file is part of libkresource

    Copyright (c) 2005 Tobias Koenig <tokoe@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include <QSignal>

#include "resource.h"

using namespace KRES;

class Resource::ResourcePrivate
{
  public:
    QSignal<void> signalOpened;
    QSignal<void> signalOpenFailed;
    QSignal<void> signalClosed;
    QSignal<void> signalCloseFailed;
    QSignal<void> signalLoaded;
    QSignal<void> signalLoadFailed;
    QSignal<void> signalSaved;
    QSignal<void> signalSaveFailed;
};

Resource::Resource()
  : QObject( 0 ),
    mIsOpening( false ),
    mIsClosing( false ),
    mIsLoading( false ),
    mIsSaving( false ),
    mIsOpen( false ),
    mIsLoaded( false ),
    d( new ResourcePrivate )
{
  /**
    We use queued connection to make sure that the resource behaves always the
    same way (the signals will be called after reentering the event loop) whether
    the emitXXX() were called directly from the xxx() method or from a thread.
   */
  d->signalOpened.connect( this, SIGNAL( opened() ), Qt::QueuedConnection );
  d->signalOpenFailed.connect( this, SIGNAL( openFailed() ), Qt::QueuedConnection );
  d->signalClosed.connect( this, SIGNAL( closed() ), Qt::QueuedConnection );
  d->signalCloseFailed.connect( this, SIGNAL( closeFailed() ), Qt::QueuedConnection );
  d->signalLoaded.connect( this, SIGNAL( loaded() ), Qt::QueuedConnection );
  d->signalLoadFailed.connect( this, SIGNAL( LoadFailed() ), Qt::QueuedConnection );
  d->signalSaved.connect( this, SIGNAL( saved() ), Qt::QueuedConnection );
  d->signalSaveFailed.connect( this, SIGNAL( saveFailed() ), Qt::QueuedConnection );
}

Resource::~Resource()
{
  delete d;
  d = 0;
}

void Resource::open()
{
  mIsOpening = true;
  doOpen();
}

void Resource::close()
{
  mIsClosing = true;
  doClose();
}

void Resource::load()
{
  mIsLoading = true;
  doLoad();
}

void Resource::save()
{
  mIsSaving = true;
  doSave();
}

bool Resource::isOpening() const
{
  return mIsOpening;
}

bool Resource::isClosing() const
{
  return mIsClosing;
}

bool Resource::isLoading() const
{
  return mIsLoading;
}

bool Resource::isSaving() const
{
  return mIsSaving;
}

bool Resource::isOpen() const
{
  return mIsOpen;
}

bool Resource::isLoaded() const
{
  return mIsLoaded;
}

void Resource::emitOpened()
{
  mIsOpening = false;
  d->signalOpened.activate();
}

void Resource::emitOpenFailed()
{
  mIsOpening = false;
  d->signalOpenFailed.activate();
}

void Resource::emitClosed()
{
  mIsClosing = false;
  d->signalClosed.activate();
}

void Resource::emitCloseFailed()
{
  mIsClosing = false;
  d->signalCloseFailed.activate();
}

void Resource::emitLoaded()
{
  mIsLoading = false;
  d->signalLoaded.activate();
}

void Resource::emitLoadFailed()
{
  mIsLoading = false;
  d->signalLoadFailed.activate();
}

void Resource::emitSaved()
{
  mIsSaving = false;
  d->signalSaved.activate();
}

void Resource::emitSaveFailed()
{
  mIsSaving = false;
  d->signalSaveFailed.activate();
}

void Resource::message( const QString& )
{
  // we use an message interface here like in kabc:addressbook
}

void Resource::error( const QString& )
{
  // we use an message interface here like in kabc:addressbook
}

["resource.h" (text/x-chdr)]

/*
    This file is part of libkresource

    Copyright (c) 2005 Tobias Koenig <tokoe@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#ifndef KRES_RESOURCE_H
#define KRES_RESOURCE_H

#include <QObject>

namespace KRES {

class Resource : public QObject
{
  Q_OBJECT

  public:
    Resource();
    virtual ~Resource();

    /**
      Opens the resource. The function call will return
      immediately, but the resource is opened until the
      opened() signal is emitted.

      When opening fails, openFailed() is emitted instead.
     */
    void open();

    /**
      Closes the resource. The function call will return
      immediately, but the resource is closed until the
      closed() signal is emitted.

      When closing fails, closeFailed() is emitted instead.
     */
    void close();

    /**
      Loads the resource. The function call will return
      immediately, but the resource is loaded until the
      loaded() signal is emitted.

      When loading fails, loadFailed() is emitted instead.
     */
    void load();

    /**
      Saves the resource. The function call will return
      immediately, but the resource is saved until the
      saved() signal is emitted.

      When saving fails, saveFailed() is emitted instead.
     */
    void save();

    /**
      Returns true if the resource is still in the opening
      state. That's the case when open() was called, but
      neither opened() nor openFailed() has been emitted yet.
     */
    bool isOpening() const;

    /**
      Returns true if the resource is still in the closing
      state. That's the case when close() was called, but
      neither closed() nor closeFailed() has been emitted yet.
     */
    bool isClosing() const;

    /**
      Returns true if the resource is still in the loading
      state. That's the case when load() was called, but
      neither loaded() nor loadFailed() has been emitted yet.
     */
    bool isLoading() const;

    /**
      Returns true if the resource is still in the saving
      state. That's the case when save() was called, but
      neither saved() nor saveFailed() has been emitted yet.
     */
    bool isSaving() const;

    /**
      Returns true if the resource was opened successfully; returns false otherwise.
      When you close the resource, it returns false as well.
     */
    bool isOpen() const;

    /**
      Returns true if the resource was loaded successfully; returns false otherwise.
     */
    bool isLoaded() const;

  signals:
    /**
      This signal is emitted when the resource was opened sucessfully.
     */
    void opened();

    /**
      This signal is emitted when opening the resource failed.
     */
    void openFailed();

    /**
      This signal is emitted when the resource was closed sucessfully.
     */
    void closed();

    /**
      This signal is emitted when closing the resource failed.
     */
    void closeFailed();

    /**
      This signal is emitted when the resource was loaded sucessfully.
     */
    void loaded();

    /**
      This signal is emitted when loading the resource failed.
     */
    void loadFailed();

    /**
      This signal is emitted when the resource was saved sucessfully.
     */
    void saved();

    /**
      This signal is emitted when saving the resource failed.
     */
    void saveFailed();
    
  protected:
    /**
      This pure abstract function must be reimplemented if you want to
      open the resource. You have to call emitOpened() or emitOpenFailed()
      to signal the success of this operation.
     */
    virtual void doOpen() = 0;

    /**
      This pure abstract function must be reimplemented if you want to
      close the resource. You have to call emitClosed() or emitCloseFailed()
      to signal the success of this operation.
     */
    virtual void doClose() = 0;

    /**
      This pure abstract function must be reimplemented if you want to
      load the resource. You have to call emitLoaded() or emitLoadFailed()
      to signal the success of this operation.
     */
    virtual void doLoad() = 0;

    /**
      This pure abstract function must be reimplemented if you want to
      save the resource. You have to call emitSaved() or emitSaveFailed()
      to signal the success of this operation.
     */
    virtual void doSave() = 0;

    /**
      This function has to be used to signal the successful end of the
      open operation.
     */
    void emitOpened();

    /**
      This function has to be used to signal an error during the
      open operation.
     */
    void emitOpenFailed();

    /**
      This function has to be used to signal the successful end of the
      close operation.
     */
    void emitClosed();

    /**
      This function has to be used to signal an error during the
      close operation.
     */
    void emitCloseFailed();

    /**
      This function has to be used to signal the successful end of the
      load operation.
     */
    void emitLoaded();

    /**
      This function has to be used to signal an error during the
      load operation.
     */
    void emitLoadFailed();

    /**
      This function has to be used to signal the successful end of the
      save operation.
     */
    void emitSaved();

    /**
      This function has to be used to signal an error during the
      save operation.
     */
    void emitSaveFailed();

    /**
      This function should be used to publish information to the user.

      @param msg The message that shall be published to the user.
     */
    void message( const QString &msg );

    /**
      This function should be used to publish error messages to the user.

      @param msg The message that shall be published to the user.
     */
    void error( const QString &msg );

  private:
    bool mIsOpening;
    bool mIsClosing;
    bool mIsLoading;
    bool mIsSaving;

    bool mIsOpen;
    bool mIsLoaded;

    class ResourcePrivate;
    ResourcePrivate *d;
};

}

#endif

["signature.asc" (application/pgp-signature)]

_______________________________________________
kde-pim mailing list
kde-pim@kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
kde-pim home page at http://pim.kde.org/

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic