Tuesday, 20 January 2009

Aware objects

"Aware objects" were created because of my laziness. In Kadu exists lot of objects that should change their behaviour/look when the configuration changes. The change invokes ConfigurationWindow::updateConfig() which (before introduction of ConfigurationAwareObject class) emited a signal.

Each object that wanted to be informed about it had to connect to this signal. It needed a lot of code: slot implementation, connection in constructor, disconnection in destructor. To free myself from writing this I've created ConfigurationAwareObject class. It has very simple interface:
class KADUAPI ConfigurationAwareObject
{
  static QList<ConfigurationAwareObject *> objects;

  static void registerObject(ConfigurationAwareObject *object);
  static void unregisterObject(ConfigurationAwareObject *object);

public:
  static void notifyAll();

  ConfigurationAwareObject();
  virtual ~ConfigurationAwareObject();

  virtual void configurationUpdated() = 0;

};


The objects field contains list of all objects of this class. Its gets updated each time the ConfigurationAwareObject contructor or destructor is called.

Static method notifyAll (called from ConfigurationWindow::updateConfig()) iterates over all objects and calls configurationUpdated on them.

So if you need to create a class that reacts to changes in configuration just make it inherit from ConfigurationAwareObject and reimplement virtual method configurationUpdated(). No need to connect/disconnect signals and slots.

In 0.6.6 AccountsAwareObject class was added with 2 abstract virtual methods: accountRegistered(Account *) and accountUnregistered(Account *) and two normal methods: triggerAllAccountsRegistered and triggerAllAccountsUnregistered (these two just call virtual methods with all currently active account).

So if you want information about accounts changes - make a class inherit from AccountsAwareObject and reimplement virtual methods. Also add call to triggerAllAccountsRegistered in constructor and triggerAllAccountsUnregistered in destructor - so it will be aware of accounts that existed before the object was created.

You could ask why triggerAllAccountsRegistered and triggerAllAccountsUnregistered are not called in AccountsAwareObject's constructor/destructor. It is because AccountsAwareObject's constructor will be called before your class constructor, and call accountRegistered(Account *) on object that can be not ready for this.

I hope that in near future we will create more aware objects in Kadu and remove many unnecessary signal/slots connections.

No comments:

Post a Comment