Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Michael Migliore
VTK
Commits
6270dbe5
Commit
6270dbe5
authored
Aug 18, 2010
by
David Gobbi
Browse files
ENH: New WeakPointer implementation for vtkObjectBase.
parent
39bc66a6
Changes
6
Hide whitespace changes
Inline
Side-by-side
Common/Testing/Cxx/CMakeLists.txt
View file @
6270dbe5
...
...
@@ -24,6 +24,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CxxTests.cxx
TestUnicodeStringAPI.cxx
TestUnicodeStringArrayAPI.cxx
TestVariantComparison.cxx
TestWeakPointer.cxx
SystemInformation.cxx
EXTRA_INCLUDE vtkTestDriver.h
)
...
...
Common/Testing/Cxx/TestWeakPointer.cxx
0 → 100644
View file @
6270dbe5
/*=========================================================================
Program: Visualization Toolkit
Module: TestWeakPointer.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME Test of vtkWeakPointer.
// .SECTION Description
// Tests instantiations of the vtkWeakPointer class template.
#include
"vtkDebugLeaks.h"
#include
"vtkFloatArray.h"
#include
"vtkIntArray.h"
#include
"vtkWeakPointer.h"
int
TestWeakPointer
(
int
,
char
*
[])
{
vtkIntArray
*
ia
=
vtkIntArray
::
New
();
// Coverage:
vtkWeakPointer
<
vtkIntArray
>
da2
(
ia
);
vtkWeakPointer
<
vtkFloatArray
>
da3
;
vtkWeakPointer
<
vtkDataArray
>
da1
(
da2
);
da1
=
ia
;
da1
=
da2
;
da2
==
da3
;
da2
!=
da3
;
da2
<
da3
;
da2
<=
da3
;
da2
>
da3
;
da2
>=
da3
;
ia
==
da3
;
ia
!=
da3
;
ia
<
da3
;
ia
<=
da3
;
ia
>
da3
;
ia
>=
da3
;
da2
==
ia
;
da2
!=
ia
;
da2
<
ia
;
da2
<=
ia
;
da2
>
ia
;
da2
>=
ia
;
da1
==
0
;
da1
!=
0
;
da1
<
0
;
da1
<=
0
;
da1
>
0
;
da1
>=
0
;
(
*
da1
).
SetNumberOfComponents
(
1
);
if
(
da2
)
{
da2
->
SetNumberOfComponents
(
1
);
}
if
(
!
da2
)
{
cerr
<<
"da2 is NULL!"
<<
"
\n
"
;
return
1
;
}
cout
<<
"IntArray: "
<<
da2
<<
"
\n
"
;
if
(
da1
.
GetPointer
()
==
0
)
{
cerr
<<
"da1.GetPointer() is NULL
\n
"
;
}
if
(
da2
.
GetPointer
()
==
0
)
{
cerr
<<
"da2.GetPointer() is NULL
\n
"
;
}
if
(
da3
.
GetPointer
()
!=
0
)
{
cerr
<<
"da3.GetPointer() is not NULL
\n
"
;
}
da2
=
0
;
ia
->
Delete
();
if
(
da1
.
GetPointer
()
!=
NULL
)
{
cerr
<<
"da1.GetPointer() is not NULL
\n
"
;
}
return
0
;
}
Common/vtkObjectBase.cxx
View file @
6270dbe5
...
...
@@ -16,6 +16,7 @@
#include
"vtkObjectBase.h"
#include
"vtkDebugLeaks.h"
#include
"vtkGarbageCollector.h"
#include
"vtkWeakPointerBase.h"
#include
<vtksys/ios/sstream>
...
...
@@ -34,6 +35,15 @@ public:
}
};
class
vtkObjectBaseToWeakPointerBaseFriendship
{
public:
static
void
ClearPointer
(
vtkWeakPointerBase
*
p
,
vtkObjectBase
*
obj
)
{
p
->
Object
=
NULL
;
}
};
// avoid dll boundary problems
#ifdef _WIN32
void
*
vtkObjectBase
::
operator
new
(
size_t
nSize
)
...
...
@@ -64,7 +74,7 @@ ostream& operator<<(ostream& os, vtkObjectBase& o)
vtkObjectBase
::
vtkObjectBase
()
{
this
->
ReferenceCount
=
1
;
// initial reference count = 1 and reference counting on.
this
->
WeakPointers
=
0
;
}
vtkObjectBase
::~
vtkObjectBase
()
...
...
@@ -75,6 +85,16 @@ vtkObjectBase::~vtkObjectBase()
{
vtkGenericWarningMacro
(
<<
"Trying to delete object with non-zero reference count."
);
}
// clear all weak pointers to this object
if
(
this
->
WeakPointers
)
{
vtkWeakPointerBase
**
p
=
this
->
WeakPointers
;
while
(
*
p
)
{
vtkObjectBaseToWeakPointerBaseFriendship
::
ClearPointer
(
*
p
++
,
this
);
}
delete
[]
this
->
WeakPointers
;
}
}
//----------------------------------------------------------------------------
...
...
Common/vtkObjectBase.h
View file @
6270dbe5
...
...
@@ -45,6 +45,8 @@
class
vtkGarbageCollector
;
class
vtkGarbageCollectorToObjectBaseFriendship
;
class
vtkWeakPointerBase
;
class
vtkWeakPointerBaseToObjectBaseFriendship
;
class
VTK_COMMON_EXPORT
vtkObjectBase
{
...
...
@@ -159,7 +161,8 @@ protected:
virtual
void
CollectRevisions
(
ostream
&
os
);
int
ReferenceCount
;
// Number of uses of this object by other objects
int
ReferenceCount
;
vtkWeakPointerBase
**
WeakPointers
;
// Internal Register/UnRegister implementation that accounts for
// possible garbage collection participation. The second argument
...
...
@@ -169,10 +172,12 @@ protected:
// See vtkGarbageCollector.h:
virtual
void
ReportReferences
(
vtkGarbageCollector
*
);
private:
//BTX
friend
VTK_COMMON_EXPORT
ostream
&
operator
<<
(
ostream
&
os
,
vtkObjectBase
&
o
);
friend
class
vtkGarbageCollectorToObjectBaseFriendship
;
friend
class
vtkWeakPointerBaseToObjectBaseFriendship
;
//ETX
protected:
//BTX
...
...
Common/vtkWeakPointerBase.cxx
View file @
6270dbe5
...
...
@@ -14,80 +14,118 @@
=========================================================================*/
#include
"vtkWeakPointerBase.h"
#include
"vtkCommand.h"
//----------------------------------------------------------------------------
class
vtkWeakPointerBase
::
vtkObserver
:
public
vtkCommand
class
vtkWeakPointerBase
ToObjectBaseFriendship
{
public:
static
vtkObserver
*
New
()
{
return
new
vtkObserver
;
}
virtual
void
Execute
(
vtkObject
*
caller
,
unsigned
long
,
void
*
)
static
void
AddWeakPointer
(
vtkObjectBase
*
r
,
vtkWeakPointerBase
*
p
);
static
void
RemoveWeakPointer
(
vtkObjectBase
*
r
,
vtkWeakPointerBase
*
p
);
};
//----------------------------------------------------------------------------
void
vtkWeakPointerBaseToObjectBaseFriendship
::
AddWeakPointer
(
vtkObjectBase
*
r
,
vtkWeakPointerBase
*
p
)
{
if
(
r
)
{
if
(
this
->
WeakReference
&&
this
->
WeakReference
->
Object
==
caller
)
vtkWeakPointerBase
**
l
=
r
->
WeakPointers
;
if
(
l
==
0
)
{
this
->
WeakReference
->
Object
=
NULL
;
// create a new list if none exists
l
=
new
vtkWeakPointerBase
*
[
2
];
l
[
0
]
=
p
;
l
[
1
]
=
0
;
r
->
WeakPointers
=
l
;
}
else
{
size_t
n
=
0
;
while
(
l
[
n
]
!=
0
)
{
n
++
;
}
// if n+1 is a power of two, double the list size
if
((
n
&
(
n
+
1
))
==
0
)
{
vtkWeakPointerBase
**
t
=
l
;
l
=
new
vtkWeakPointerBase
*
[(
n
+
1
)
*
2
];
for
(
size_t
i
=
0
;
i
<
n
;
i
++
)
{
l
[
i
]
=
t
[
i
];
}
delete
[]
t
;
r
->
WeakPointers
=
l
;
}
// make sure list is null-terminated
l
[
n
++
]
=
p
;
l
[
n
]
=
0
;
}
}
void
SetTarget
(
vtkWeakPointerBase
*
ref
)
{
this
->
WeakReference
=
ref
;
}
private:
vtkObserver
()
{
this
->
WeakReference
=
0
;
}
vtkWeakPointerBase
*
WeakReference
;
};
}
//----------------------------------------------------------------------------
vtkWeakPointerBase
::
vtk
WeakPointer
Base
()
:
Object
(
0
)
void
vtkWeakPointerBase
ToObjectBaseFriendship
::
Remove
WeakPointer
(
vtk
Object
Base
*
r
,
vtkWeakPointerBase
*
p
)
{
this
->
Observer
=
vtkWeakPointerBase
::
vtkObserver
::
New
();
this
->
Observer
->
SetTarget
(
this
);
this
->
AddObserver
();
if
(
r
)
{
vtkWeakPointerBase
**
l
=
r
->
WeakPointers
;
if
(
l
!=
0
)
{
size_t
i
=
0
;
while
(
l
[
i
]
!=
0
&&
l
[
i
]
!=
p
)
{
i
++
;
}
while
(
l
[
i
]
!=
0
)
{
l
[
i
]
=
l
[
i
+
1
];
i
++
;
}
if
(
l
[
0
]
==
0
)
{
delete
[]
l
;
r
->
WeakPointers
=
0
;
}
}
}
}
//----------------------------------------------------------------------------
vtkWeakPointerBase
::
vtkWeakPointerBase
(
vtkObject
*
r
)
:
vtkWeakPointerBase
::
vtkWeakPointerBase
(
vtkObject
Base
*
r
)
:
Object
(
r
)
{
this
->
Observer
=
vtkWeakPointerBase
::
vtkObserver
::
New
();
this
->
Observer
->
SetTarget
(
this
);
this
->
AddObserver
();
vtkWeakPointerBaseToObjectBaseFriendship
::
AddWeakPointer
(
r
,
this
);
}
//----------------------------------------------------------------------------
vtkWeakPointerBase
::
vtkWeakPointerBase
(
const
vtkWeakPointerBase
&
r
)
:
vtkWeakPointerBase
::
vtkWeakPointerBase
(
const
vtkWeakPointerBase
&
r
)
:
Object
(
r
.
Object
)
{
this
->
Observer
=
vtkWeakPointerBase
::
vtkObserver
::
New
();
this
->
Observer
->
SetTarget
(
this
);
this
->
AddObserver
();
vtkWeakPointerBaseToObjectBaseFriendship
::
AddWeakPointer
(
r
.
Object
,
this
);
}
//----------------------------------------------------------------------------
vtkWeakPointerBase
::~
vtkWeakPointerBase
()
{
this
->
RemoveObserver
();
this
->
Ob
server
->
SetTarget
(
0
);
this
->
Observer
->
Delete
();
vtkWeakPointerBaseToObjectBaseFriendship
::
RemoveWeakPointer
(
this
->
Ob
ject
,
this
);
this
->
Object
=
0
;
}
//----------------------------------------------------------------------------
vtkWeakPointerBase
&
vtkWeakPointerBase
::
operator
=
(
vtkObject
*
r
)
vtkWeakPointerBase
::
operator
=
(
vtkObject
Base
*
r
)
{
if
(
this
->
Object
!=
r
)
if
(
this
->
Object
!=
r
)
{
this
->
RemoveObserver
();
vtkWeakPointerBaseToObjectBaseFriendship
::
RemoveWeakPointer
(
this
->
Object
,
this
);
this
->
Object
=
r
;
this
->
AddObserver
();
vtkWeakPointerBaseToObjectBaseFriendship
::
AddWeakPointer
(
this
->
Object
,
this
);
}
return
*
this
;
}
...
...
@@ -95,34 +133,21 @@ vtkWeakPointerBase::operator=(vtkObject* r)
vtkWeakPointerBase
&
vtkWeakPointerBase
::
operator
=
(
const
vtkWeakPointerBase
&
r
)
{
if
(
this
!=&
r
)
if
(
this
!=
&
r
)
{
if
(
this
->
Object
!=
r
.
Object
)
if
(
this
->
Object
!=
r
.
Object
)
{
this
->
RemoveObserver
();
vtkWeakPointerBaseToObjectBaseFriendship
::
RemoveWeakPointer
(
this
->
Object
,
this
);
this
->
Object
=
r
.
Object
;
this
->
AddObserver
();
}
}
return
*
this
;
}
//----------------------------------------------------------------------------
void
vtkWeakPointerBase
::
AddObserver
()
{
if
(
this
->
Object
&&
this
->
Observer
)
{
this
->
Object
->
AddObserver
(
vtkCommand
::
DeleteEvent
,
this
->
Observer
);
vtkWeakPointerBaseToObjectBaseFriendship
::
AddWeakPointer
(
this
->
Object
,
this
);
}
}
}
//----------------------------------------------------------------------------
void
vtkWeakPointerBase
::
RemoveObserver
()
{
if
(
this
->
Object
&&
this
->
Observer
)
{
this
->
Object
->
RemoveObservers
(
vtkCommand
::
DeleteEvent
,
this
->
Observer
);
}
return
*
this
;
}
//----------------------------------------------------------------------------
...
...
Common/vtkWeakPointerBase.h
View file @
6270dbe5
...
...
@@ -14,26 +14,28 @@
=========================================================================*/
// .NAME vtkWeakPointerBase - Non-templated superclass for vtkWeakPointer.
// .SECTION Description
// vtkWeakPointerBase holds a pointer to a vtkObject or subclass
// instance, but it never affects the reference count of the vtkObject. However,
// when the vtkObject referred to is destroyed, the pointer gets initialized to
// vtkWeakPointerBase holds a pointer to a vtkObject
Base
or subclass
// instance, but it never affects the reference count of the vtkObject
Base
. However,
// when the vtkObject
Base
referred to is destroyed, the pointer gets initialized to
// NULL, thus avoid dangling references.
#ifndef __vtkWeakPointerBase_h
#define __vtkWeakPointerBase_h
#include
"vtkObject.h"
#include
"vtkObjectBase.h"
class
vtkObjectBaseToWeakPointerBaseFriendship
;
class
VTK_COMMON_EXPORT
vtkWeakPointerBase
{
public:
// Description:
// Initialize smart pointer to NULL.
vtkWeakPointerBase
();
vtkWeakPointerBase
()
:
Object
(
0
)
{}
;
// Description:
// Initialize smart pointer to given object.
vtkWeakPointerBase
(
vtkObject
*
r
);
vtkWeakPointerBase
(
vtkObject
Base
*
r
);
// Description:
// Initialize weak pointer .
...
...
@@ -46,37 +48,29 @@ public:
// Description:
// Assign object to reference. This removes any reference to an old
// object.
vtkWeakPointerBase
&
operator
=
(
vtkObject
*
r
);
vtkWeakPointerBase
&
operator
=
(
vtkObject
Base
*
r
);
vtkWeakPointerBase
&
operator
=
(
const
vtkWeakPointerBase
&
r
);
// Description:
// Get the contained pointer.
vtkObject
*
GetPointer
()
const
vtkObject
Base
*
GetPointer
()
const
{
// Inline implementation so smart pointer comparisons can be fully
// inlined.
return
this
->
Object
;
}
private:
friend
class
vtkObjectBaseToWeakPointerBaseFriendship
;
protected:
// Initialize smart pointer to given object, but do not increment
// reference count. The destructor will still decrement the count.
// This effectively makes it an auto-ptr.
// Initialize weak pointer to given object.
class
NoReference
{};
vtkWeakPointerBase
(
vtkObject
*
r
,
const
NoReference
&
);
vtkWeakPointerBase
(
vtkObject
Base
*
r
,
const
NoReference
&
);
// Pointer to the actual object.
vtkObject
*
Object
;
private:
// Internal utility methods.
void
RemoveObserver
();
void
AddObserver
();
class
vtkObserver
;
friend
class
vtkObserver
;
vtkObserver
*
Observer
;
vtkObjectBase
*
Object
;
};
//----------------------------------------------------------------------------
...
...
@@ -92,12 +86,12 @@ private:
static_cast<void*>(r.GetPointer())); \
} \
inline vtkstd_bool \
operator op (vtkObject* l, const vtkWeakPointerBase& r) \
operator op (vtkObject
Base
* l, const vtkWeakPointerBase& r) \
{ \
return (static_cast<void*>(l) op static_cast<void*>(r.GetPointer())); \
} \
inline vtkstd_bool \
operator op (const vtkWeakPointerBase& l, vtkObject* r) \
operator op (const vtkWeakPointerBase& l, vtkObject
Base
* r) \
{ \
return (static_cast<void*>(l.GetPointer()) op static_cast<void*>(r)); \
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment