Weak references, alternative approach

ATS asteinarson at gmail.com
Sat Dec 22 09:45:12 PST 2007


(Follow-up to original "weak reference patch")


Alternative solution, Weak References:

This supports two types of references:

- A simple wxWeakRef<T> which is the smart pointer type
  (where T usually derives from wxObject).

- A wxEvtHandlerRef which is used to handle track a dynamic 
  event connection. It contains a ref count, since one event 
  handler may have multiple dynamic connections to another one. 

Separating the two cases slightly allows wxWeakRef to be efficient
while still handling particulars for wxEvtHandler case. 

- Both wxWeakRef<T> and wxEvtHandlerRef derive from wxObjectTracker:

  struct wxObjectTracker {
    virtual void OnObjectDestroy( wxObject *pobj ) = 0;
    virtual void* GetRef( ) = 0;  // Returns actual tracker object 
    virtual bool AddRef( ) { return false; } 
    virtual bool ReleaseRef( ) { return false; }
  }

- wxWeakRef<T> in itself is the tracker object. 

- wxEvtHandlerRef is not a base class of wxEvtHandler, since with 
  dynamic events, we have a multi-to-multi connection scenario.
  wxEvtHandlerRef represents all connections between a given pair
  of event handlers (in my code I connect up to ten events from 
  a given event source. This approach creates a single reference 
  for that case, but with ref count 10).

- Then we have a global API (or static member functions for wxObject):
  // Notify tracker and remove from table
  void OnObjectDestroy( wxObject *pobj ); 
  // some more functions ...to be defined. 


A couple of concerns / questions:

1 - Every wxObject destructor will have to call OnObjectDestroy.
The cost of looking in the hash table is O(1) but we will have 
this limited cost (for every wxColour, wxPen, ...). 

1a - The alternative is a member variable in wxObject:

  wxObjectTracker *m_first

Is the final say here "HashTable instead of member variable)?

(Probably a global #define WX_ENABLE_WEAK_REFS is needed anyway). 


2 - In wxHashTable, wxObject* will be a lookup key. Since a hash 
node looks something like:

  template<class Key, class Value>
  struct wxHashNode {
    Key m_key;
    Value m_value;
    wxHashNode<Key,Value> *m_next;
  };

the key has to be stored twice for each node (in m_key and inside 
m_value). Do we have any alternative hash table implementation?
It would look more like:

  template<class Key, class Value>
  struct wxHashNode {
    Key GetKey();   // Avoid double storing key
    Value m_value;
    wxHashNode<Key,Value> *m_next;
  };


Regards
// ATS




More information about the wx-dev mailing list