use weak references for the internal metaclass typemap,

this should help with blender leaking memory with python classes though the bug is still not fixed.
This commit is contained in:
Campbell Barton
2011-02-11 00:39:07 +00:00
parent fb8c135584
commit b1cdf5c344
2 changed files with 32 additions and 26 deletions

View File

@@ -579,35 +579,40 @@ def user_resource(type, path="", create=False):
return target_path
def _bpy_module_classes(module, is_registered=False):
typemap_list = _bpy_types.TypeMap.get(module, ())
i = 0
while i < len(typemap_list):
cls_weakref, path, line = typemap_list[i]
cls = cls_weakref()
if cls is None:
del typemap_list[i]
elif is_registered == ("bl_rna" in cls.__dict__):
yield (cls, path, line)
i += 1
def register_module(module):
import traceback
total = 0
for cls, path, line in _bpy_types.TypeMap.get(module, ()):
if not "bl_rna" in cls.__dict__:
total += 1
try:
register_class(cls)
except:
print("bpy.utils.register_module(): failed to registering class '%s.%s'" % (cls.__module__, cls.__name__))
print("\t", path, "line", line)
traceback.print_exc()
for cls, path, line in _bpy_module_classes(module, is_registered=False):
try:
register_class(cls)
except:
print("bpy.utils.register_module(): failed to registering class '%s.%s'" % (cls.__module__, cls.__name__))
print("\t", path, "line", line)
traceback.print_exc()
if total == 0:
if "cls" not in locals():
raise Exception("register_module(%r): defines no classes" % module)
def unregister_module(module):
import traceback
total = 0
for cls, path, line in _bpy_types.TypeMap.get(module, ()):
if "bl_rna" in cls.__dict__:
total += 1
try:
unregister_class(cls)
except:
print("bpy.utils.unregister_module(): failed to unregistering class '%s.%s'" % (cls.__module__, cls.__name__))
print("\t", path, "line", line)
traceback.print_exc()
if total == 0:
raise Exception("unregister_module(%r): defines no classes" % module)
for cls, path, line in _bpy_module_classes(module, is_registered=True):
try:
unregister_class(cls)
except:
print("bpy.utils.unregister_module(): failed to unregistering class '%s.%s'" % (cls.__module__, cls.__name__))
print("\t", path, "line", line)
traceback.print_exc()

View File

@@ -556,9 +556,10 @@ TypeMap = {}
class RNAMeta(type):
def __new__(cls, name, bases, classdict, **args):
import traceback
result = type.__new__(cls, name, bases, classdict)
if bases and bases[0] != StructRNA:
import traceback
import weakref
module = result.__module__
# first part of packages only
@@ -567,7 +568,7 @@ class RNAMeta(type):
sf = traceback.extract_stack(limit=2)[0]
TypeMap.setdefault(module, []).append((result, sf[0], sf[1]))
TypeMap.setdefault(module, []).append((weakref.ref(result), sf[0], sf[1]))
return result