mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
assert when subclassing rules are not followed
This commit is contained in:
parent
5e3a807168
commit
386bf49c0d
@ -3,13 +3,14 @@ class ResourceCounter(object):
|
||||
"""
|
||||
This class is an attempt to combine the RAIA idiom with reference
|
||||
counting semantics in order to model shared resources. RAIA stands
|
||||
for "Resource Allocation Is Acquisiton" (see 'Effective C++' for a
|
||||
more detailed explanation)
|
||||
for "Resource Allocation Is Acquisition" (see 'Effective C++' for a
|
||||
more in-depth explanation)
|
||||
|
||||
When a resource is needed, create an appropriate ResourceCounter
|
||||
object. If the resource is already available (meaning another
|
||||
ResourceCounter object of the same type already exists), no action
|
||||
is taken. The resource will remain valid until all matching
|
||||
is taken. Otherwise, acquire() is invoked, and the resource is
|
||||
allocated. The resource will remain valid until all matching
|
||||
ResourceCounter objects have been deleted. When no objects of
|
||||
a particular ResourceCounter type exist, the release() function for
|
||||
that type is invoked and the managed resource is cleaned up.
|
||||
@ -27,10 +28,11 @@ class ResourceCounter(object):
|
||||
Until we figure out a way to wrangle a bit more functionality out
|
||||
of Python, you MUST NOT define acquire() and release() again in
|
||||
any subclasses of your ResourceCounter subclass in an attempt
|
||||
to manage another resource. If you have more than one resource,
|
||||
to manage another resource. In debug mode, this will raise a
|
||||
runtime assertion. If you have more than one resource, you should
|
||||
subclass ResourceCounter again. See the example code at the
|
||||
bottom of this file to see how to manage more than one resource with
|
||||
a single instance of an object (Useful for dependent resources).
|
||||
bottom of this file to see how to manage more than one resource
|
||||
with a single instance of an object (Useful for dependent resources).
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
@ -46,18 +48,22 @@ class ResourceCounter(object):
|
||||
@classmethod
|
||||
def decrementCounter(cls):
|
||||
cls.RESOURCE_COUNTER -= 1
|
||||
|
||||
if cls.RESOURCE_COUNTER == 0:
|
||||
if cls.RESOURCE_COUNTER < 1:
|
||||
cls.release()
|
||||
|
||||
@classmethod
|
||||
def acquire(cls):
|
||||
pass
|
||||
cls.RESOURCE_COUNTER -= 1
|
||||
assert cls.__mro__[1] == ResourceCounter, \
|
||||
(lambda: \
|
||||
'acquire() should only be defined in ResourceCounter\'s immediate subclass: %s' \
|
||||
% cls.__mro__[list(cls.__mro__).index(ResourceCounter) - 1].__name__)()
|
||||
|
||||
cls.RESOURCE_COUNTER += 1
|
||||
|
||||
@classmethod
|
||||
def release(cls, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.incrementCounter()
|
||||
@ -73,19 +79,20 @@ if __debug__ and __name__ == '__main__':
|
||||
"""
|
||||
@classmethod
|
||||
def acquire(cls):
|
||||
ResourceCounter.acquire()
|
||||
print '-- Acquiring Mouse'
|
||||
super(MouseResource, cls).acquire()
|
||||
print '-- Acquire Mouse'
|
||||
|
||||
@classmethod
|
||||
def release(cls):
|
||||
ResourceCounter.release()
|
||||
print '-- Releasing Mouse'
|
||||
print '-- Release Mouse'
|
||||
super(MouseResource, cls).release()
|
||||
|
||||
|
||||
def __init__(self):
|
||||
ResourceCounter.__init__(self)
|
||||
|
||||
super(MouseResource, self).__init__()
|
||||
|
||||
def __del__(self):
|
||||
ResourceCounter.__del__(self)
|
||||
super(MouseResource, self).__del__()
|
||||
|
||||
class CursorResource(ResourceCounter):
|
||||
"""
|
||||
@ -93,26 +100,38 @@ if __debug__ and __name__ == '__main__':
|
||||
resource. Notice how this class also inherits from
|
||||
ResourceCounter. Instead of subclassing MouseCounter,
|
||||
we will just acquire it in our __init__() and release
|
||||
it in our
|
||||
it in our __del__().
|
||||
"""
|
||||
@classmethod
|
||||
def acquire(cls):
|
||||
print '-- Acquiring Cursor'
|
||||
ResourceCounter.acquire()
|
||||
super(CursorResource, cls).acquire()
|
||||
print '-- Acquire Cursor'
|
||||
|
||||
@classmethod
|
||||
def release(cls):
|
||||
print '-- Releasing Cursor'
|
||||
ResourceCounter.release()
|
||||
print '-- Release Cursor'
|
||||
super(CursorResource, cls).release()
|
||||
|
||||
def __init__(self):
|
||||
self.__mouseResource = MouseResource()
|
||||
ResourceCounter.__init__(self)
|
||||
super(CursorResource, self).__init__()
|
||||
|
||||
def __del__(self):
|
||||
ResourceCounter.__del__(self)
|
||||
super(CursorResource, self).__del__()
|
||||
del self.__mouseResource
|
||||
|
||||
class InvalidResource(MouseResource):
|
||||
@classmethod
|
||||
def acquire(cls):
|
||||
super(InvalidResource, cls).acquire()
|
||||
print '-- Acquire Invalid'
|
||||
|
||||
@classmethod
|
||||
def release(cls):
|
||||
print '-- Release Invalid'
|
||||
super(InvalidResource, cls).release()
|
||||
|
||||
|
||||
print '\nAllocate Mouse'
|
||||
m = MouseResource()
|
||||
print 'Free up Mouse'
|
||||
@ -154,13 +173,21 @@ if __debug__ and __name__ == '__main__':
|
||||
del m
|
||||
print 'Free up Cursor'
|
||||
del c
|
||||
|
||||
|
||||
# example of an invalid subclass
|
||||
try:
|
||||
print '\nAllocate Invalid'
|
||||
i = InvalidResource()
|
||||
print 'Free up Invalid'
|
||||
except AssertionError,e:
|
||||
print e
|
||||
|
||||
def demoFunc():
|
||||
print '\nAllocate Cursor within function'
|
||||
c = CursorResource()
|
||||
|
||||
|
||||
print 'Cursor will be freed on function exit'
|
||||
|
||||
|
||||
demoFunc()
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user