use wxWindowIDRef to transparently implement auto-generated ids ref-counting (slightly modified patch 1835458)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@51035 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-01-06 14:38:44 +00:00
parent 7d287e713f
commit cf2810aa39
34 changed files with 748 additions and 189 deletions

View File

@@ -233,12 +233,6 @@
typedef short int WXTYPE;
/* special care should be taken with this type under Windows where the real */
/* window id is unsigned, so we must always do the cast before comparing them */
/* (or else they would be always different!). Using wxGetWindowId() which does */
/* the cast itself is recommended. Note that this type can't be unsigned */
/* because wxID_ANY == -1 is a valid (and largely used) value for window id. */
typedef int wxWindowID;
/* ---------------------------------------------------------------------------- */
/* other feature tests */
@@ -1782,8 +1776,19 @@ enum
These ids delimit the range used by automatically-generated ids
(i.e. those used when wxID_ANY is specified during construction).
*/
#if defined(__WXMSW__) || wxUSE_AUTOID_MANAGEMENT
/*
On MSW the range is always restricted no matter if id management
is used or not because the native window ids are limited to short
range. On other platforms the range is only restricted if id
management is used so the reference count buffer won't be so big.
*/
wxID_AUTO_LOWEST = -32000,
wxID_AUTO_HIGHEST = -2000,
#else
wxID_AUTO_LOWEST = -1000000,
wxID_AUTO_HIGHEST = -2000,
#endif
/* no id matches this one when compared to it */
wxID_NONE = -3,
@@ -1919,6 +1924,19 @@ enum
wxID_HIGHEST = 5999
};
/* ---------------------------------------------------------------------------- */
/* wxWindowID type (after wxID_XYZ enum, platform detection, and dlimpexp.h) */
/* ---------------------------------------------------------------------------- */
/* special care should be taken with this type under Windows where the real */
/* window id is unsigned, so we must always do the cast before comparing them */
/* (or else they would be always different!). Using wxGetWindowId() which does */
/* the cast itself is recommended. Note that this type can't be unsigned */
/* because wxID_ANY == -1 is a valid (and largely used) value for window id. */
#ifdef __cplusplus
#include "wx/windowid.h"
#endif
/* ---------------------------------------------------------------------------- */
/* other constants */
/* ---------------------------------------------------------------------------- */

View File

@@ -887,6 +887,16 @@
// wxValidator class and related methods
#define wxUSE_VALIDATORS 1
// Use reference counted ID management: this means that wxWidgets will track
// the automatically allocated ids (those used when you use wxID_ANY when
// creating a window, menu or toolbar item &c) instead of just supposing that
// the program never runs out of them. This is mostly useful only under wxMSW
// where the total ids range is limited to SHRT_MIN..SHRT_MAX and where
// long-running programs can run into problems with ids reuse without this. On
// the other platforms, where the ids have the full int range, this shouldn't
// be necessary.
#define wxUSE_AUTOID_MANAGEMENT defined(__WXMSW__)
// ----------------------------------------------------------------------------
// common dialogs
// ----------------------------------------------------------------------------

View File

@@ -145,7 +145,7 @@ public:
}
protected:
int m_id; // numeric id of the item >= 0 or wxID_ANY or wxID_SEPARATOR
wxWindowIDRef m_id; // numeric id of the item >= 0 or wxID_ANY or wxID_SEPARATOR
wxMenu *m_parentMenu, // the menu we belong to
*m_subMenu; // our sub menu or NULL
wxString m_text, // label of the item

View File

@@ -886,6 +886,16 @@
// wxValidator class and related methods
#define wxUSE_VALIDATORS 1
// Use reference counted ID management: this means that wxWidgets will track
// the automatically allocated ids (those used when you use wxID_ANY when
// creating a window, menu or toolbar item &c) instead of just supposing that
// the program never runs out of them. This is mostly useful only under wxMSW
// where the total ids range is limited to SHRT_MIN..SHRT_MAX and where
// long-running programs can run into problems with ids reuse without this. On
// the other platforms, where the ids have the full int range, this shouldn't
// be necessary.
#define wxUSE_AUTOID_MANAGEMENT defined(__WXMSW__)
// ----------------------------------------------------------------------------
// common dialogs
// ----------------------------------------------------------------------------

View File

@@ -158,6 +158,7 @@ protected:
// the buttons we contain
wxSubwindows *m_radioButtons;
wxWindowIDRef *m_radioButtonIds;
// array of widths and heights of the buttons, may be wxDefaultCoord if the
// corresponding quantity should be computed

View File

@@ -886,6 +886,16 @@
// wxValidator class and related methods
#define wxUSE_VALIDATORS 1
// Use reference counted ID management: this means that wxWidgets will track
// the automatically allocated ids (those used when you use wxID_ANY when
// creating a window, menu or toolbar item &c) instead of just supposing that
// the program never runs out of them. This is mostly useful only under wxMSW
// where the total ids range is limited to SHRT_MIN..SHRT_MAX and where
// long-running programs can run into problems with ids reuse without this. On
// the other platforms, where the ids have the full int range, this shouldn't
// be necessary.
#define wxUSE_AUTOID_MANAGEMENT defined(__WXMSW__)
// ----------------------------------------------------------------------------
// common dialogs
// ----------------------------------------------------------------------------

View File

@@ -117,7 +117,8 @@ protected:
virtual wxSize DoGetBestSize() const;
// the labels windows, if any
wxSubwindows *m_labels;
wxSubwindows *m_labels;
wxWindowIDRef *m_labelIds;
int m_rangeMin;
int m_rangeMax;

View File

@@ -886,6 +886,16 @@
// wxValidator class and related methods
#define wxUSE_VALIDATORS 1
// Use reference counted ID management: this means that wxWidgets will track
// the automatically allocated ids (those used when you use wxID_ANY when
// creating a window, menu or toolbar item &c) instead of just supposing that
// the program never runs out of them. This is mostly useful only under wxMSW
// where the total ids range is limited to SHRT_MIN..SHRT_MAX and where
// long-running programs can run into problems with ids reuse without this. On
// the other platforms, where the ids have the full int range, this shouldn't
// be necessary.
#define wxUSE_AUTOID_MANAGEMENT defined(__WXMSW__)
// ----------------------------------------------------------------------------
// common dialogs
// ----------------------------------------------------------------------------

View File

@@ -886,6 +886,16 @@
// wxValidator class and related methods
#define wxUSE_VALIDATORS 1
// Use reference counted ID management: this means that wxWidgets will track
// the automatically allocated ids (those used when you use wxID_ANY when
// creating a window, menu or toolbar item &c) instead of just supposing that
// the program never runs out of them. This is mostly useful only under wxMSW
// where the total ids range is limited to SHRT_MIN..SHRT_MAX and where
// long-running programs can run into problems with ids reuse without this. On
// the other platforms, where the ids have the full int range, this shouldn't
// be necessary.
#define wxUSE_AUTOID_MANAGEMENT defined(__WXMSW__)
// ----------------------------------------------------------------------------
// common dialogs
// ----------------------------------------------------------------------------

View File

@@ -886,6 +886,16 @@
// wxValidator class and related methods
#define wxUSE_VALIDATORS 1
// Use reference counted ID management: this means that wxWidgets will track
// the automatically allocated ids (those used when you use wxID_ANY when
// creating a window, menu or toolbar item &c) instead of just supposing that
// the program never runs out of them. This is mostly useful only under wxMSW
// where the total ids range is limited to SHRT_MIN..SHRT_MAX and where
// long-running programs can run into problems with ids reuse without this. On
// the other platforms, where the ids have the full int range, this shouldn't
// be necessary.
#define wxUSE_AUTOID_MANAGEMENT defined(__WXMSW__)
// ----------------------------------------------------------------------------
// common dialogs
// ----------------------------------------------------------------------------

View File

@@ -882,6 +882,16 @@
// wxValidator class and related methods
#define wxUSE_VALIDATORS 1
// Use reference counted ID management: this means that wxWidgets will track
// the automatically allocated ids (those used when you use wxID_ANY when
// creating a window, menu or toolbar item &c) instead of just supposing that
// the program never runs out of them. This is mostly useful only under wxMSW
// where the total ids range is limited to SHRT_MIN..SHRT_MAX and where
// long-running programs can run into problems with ids reuse without this. On
// the other platforms, where the ids have the full int range, this shouldn't
// be necessary.
#define wxUSE_AUTOID_MANAGEMENT defined(__WXMSW__)
// ----------------------------------------------------------------------------
// common dialogs
// ----------------------------------------------------------------------------

View File

@@ -210,7 +210,7 @@ protected:
// tool parameters
int m_toolStyle; // see enum wxToolBarToolStyle
int m_id; // the tool id, wxID_SEPARATOR for separator
wxWindowIDRef m_id; // the tool id, wxID_SEPARATOR for separator
wxItemKind m_kind; // for normal buttons may be wxITEM_NORMAL/CHECK/RADIO
// as controls have their own client data, no need to waste memory

View File

@@ -228,17 +228,21 @@ public:
void SetId( wxWindowID winid ) { m_windowId = winid; }
wxWindowID GetId() const { return m_windowId; }
// returns true if this id value belong to the range reserved for the
// auto-generated (by NewControlId()) ids (they're always negative)
static bool IsAutoGeneratedId(wxWindowID id);
// generate a unique id (or count of them consecutively), returns a
// valid id in IsAutoGeneratedId() range or wxID_NONE if failed
static wxWindowID NewControlId(int count = 1);
// valid id in the auto-id range or wxID_NONE if failed. If using
// autoid management, it will mark the id as reserved until it is
// used (by assigning it to a wxWindowIDRef) or unreserved.
static wxWindowID NewControlId(int count = 1)
{
return wxIdManager::ReserveId(count);
}
// mark an id previously returned by NewControlId() as being unused any
// more so that it can be reused again for another control later
static void ReleaseControlId(wxWindowID id);
// If an ID generated from NewControlId is not assigned to a wxWindowIDRef,
// it must be unreserved
static void UnreserveControlId(wxWindowID id, int count = 1)
{
wxIdManager::UnreserveId(id, count);
}
// moving/resizing
@@ -1356,7 +1360,7 @@ protected:
// the window id - a number which uniquely identifies a window among
// its siblings unless it is wxID_ANY
wxWindowID m_windowId;
wxWindowIDRef m_windowId;
// the parent window of this window (or NULL) and the list of the children
// of this window
@@ -1425,10 +1429,6 @@ protected:
// Layout() window automatically when its size changes?
bool m_autoLayout:1;
// true if we had automatically allocated the id value for this window
// (i.e. wxID_ANY had been passed to the ctor)
bool m_freeId:1;
// window state
bool m_isShown:1;
bool m_isEnabled:1;
@@ -1747,8 +1747,8 @@ WXDLLEXPORT wxWindow* wxGetTopLevelParent(wxWindow *win);
#if WXWIN_COMPATIBILITY_2_6
// deprecated (doesn't start with 'wx' prefix), use wxWindow::NewControlId()
wxDEPRECATED( int NewControlId() );
inline int NewControlId() { return wxWindowBase::NewControlId(); }
wxDEPRECATED( wxWindowID NewControlId() );
inline wxWindowID NewControlId() { return wxWindowBase::NewControlId(); }
#endif // WXWIN_COMPATIBILITY_2_6
#if wxUSE_ACCESSIBILITY

189
include/wx/windowid.h Normal file
View File

@@ -0,0 +1,189 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/windowid.h
// Purpose: wxWindowID class - a class for managing window ids
// Author: Brian Vanderburg II
// Created: 2007-09-21
// RCS-ID: $Id$
// Copyright: (c) 2007 Brian Vanderburg II
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_WINDOWID_H_
#define _WX_WINDOWID_H_
// NB: do not include defs.h as we are included from it
typedef int wxWindowID;
// ----------------------------------------------------------------------------
// wxWindowIDRef: reference counted id value
// ----------------------------------------------------------------------------
// A wxWindowIDRef object wraps an id value and marks it as (un)used as
// necessary. All ids returned from wxWindow::NewControlId() should be assigned
// to an instance of this class to ensure that the id is marked as being in
// use.
//
// This class is always defined but it is trivial if wxUSE_AUTOID_MANAGEMENT is
// off.
class WXDLLIMPEXP_CORE wxWindowIDRef
{
public:
// default ctor
wxWindowIDRef()
{
m_id = wxID_NONE;
}
// ctor taking id values
wxWindowIDRef(int id)
{
Init(id);
}
wxWindowIDRef(long id)
{
Init(id);
}
wxWindowIDRef(const wxWindowIDRef& id)
{
Init(id.m_id);
}
// dtor
~wxWindowIDRef()
{
Assign(wxID_NONE);
}
// assignment
wxWindowIDRef& operator=(int id)
{
Assign(id);
return *this;
}
wxWindowIDRef& operator=(long id)
{
Assign(id);
return *this;
}
wxWindowIDRef& operator=(const wxWindowIDRef& id)
{
Assign(id.m_id);
return *this;
}
// access to the stored id value
wxWindowID GetValue() const
{
return m_id;
}
operator wxWindowID() const
{
return m_id;
}
private:
#if wxUSE_AUTOID_MANAGEMENT
// common part of all ctors: call Assign() for our new id
void Init(wxWindowID id)
{
// m_id must be initialized before calling Assign()
m_id = wxID_NONE;
Assign(id);
}
// increase reference count of id, decrease the one of m_id
void Assign(wxWindowID id);
#else // !wxUSE_AUTOID_MANAGEMENT
// trivial stubs for the functions above
void Init(wxWindowID id)
{
m_id = id;
}
void Assign(wxWindowID id)
{
m_id = id;
}
#endif // wxUSE_AUTOID_MANAGEMENT/!wxUSE_AUTOID_MANAGEMENT
wxWindowID m_id;
};
// comparison operators
inline bool operator==(const wxWindowIDRef& lhs, const wxWindowIDRef& rhs)
{
return lhs.GetValue() == rhs.GetValue();
}
inline bool operator==(const wxWindowIDRef& lhs, int rhs)
{
return lhs.GetValue() == rhs;
}
inline bool operator==(const wxWindowIDRef& lhs, long rhs)
{
return lhs.GetValue() == rhs;
}
inline bool operator==(int lhs, const wxWindowIDRef& rhs)
{
return rhs == lhs;
}
inline bool operator==(long lhs, const wxWindowIDRef& rhs)
{
return rhs == lhs;
}
inline bool operator!=(const wxWindowIDRef& lhs, const wxWindowIDRef& rhs)
{
return !(lhs == rhs);
}
inline bool operator!=(const wxWindowIDRef& lhs, int rhs)
{
return !(lhs == rhs);
}
inline bool operator!=(const wxWindowIDRef& lhs, long rhs)
{
return !(lhs == rhs);
}
inline bool operator!=(int lhs, const wxWindowIDRef& rhs)
{
return !(lhs == rhs);
}
inline bool operator!=(long lhs, const wxWindowIDRef& rhs)
{
return !(lhs == rhs);
}
// ----------------------------------------------------------------------------
// wxIdManager
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_CORE wxIdManager
{
public:
// This returns an id value and not an wxWindowIDRef. The returned value
// should be assigned a.s.a.p to a wxWindowIDRef. The IDs are marked as
// reserved so that another call to ReserveId before assigning the id to a
// wxWindowIDRef will not use the same ID
static wxWindowID ReserveId(int count = 1);
// This will release an unused reserved ID. This should only be called
// if the ID returned by ReserveId was NOT assigned to a wxWindowIDRef
// for some purpose, maybe an early return from a function
static void UnreserveId(wxWindowID id, int count = 1);
};
#endif // _WX_WINDOWID_H_