Skip to content

Commit 094c66b

Browse files
committed
Improve TypeManager.function/TypeManager.virtual_function fetch speed by using cache and setattr.
1 parent 12a24f4 commit 094c66b

File tree

1 file changed

+54
-27
lines changed
  • addons/source-python/packages/source-python/memory

1 file changed

+54
-27
lines changed

Diff for: addons/source-python/packages/source-python/memory/manager.py

+54-27
Original file line numberDiff line numberDiff line change
@@ -619,21 +619,34 @@ def virtual_function(
619619
if return_type not in DataType.values:
620620
return_type = self.create_converter(return_type)
621621

622-
def fget(ptr):
623-
"""Return the virtual function."""
624-
# Create the virtual function
625-
func = ptr.make_virtual_function(
626-
index,
627-
convention,
628-
args,
629-
return_type
630-
)
622+
class fget(object):
623+
def __set_name__(fget_self, owner, name):
624+
fget_self.name = name
625+
626+
def __get__(fget_self, obj, cls=None):
627+
"""Return the virtual function."""
628+
if obj is None:
629+
return fget_self
630+
631+
# Create the virtual function
632+
func = obj.make_virtual_function(
633+
index,
634+
convention,
635+
args,
636+
return_type
637+
)
638+
639+
# Wrap it using MemberFunction, so we don't have to pass the this
640+
# pointer anymore
641+
func = MemberFunction(self, return_type, func, obj)
642+
func.__doc__ = doc
631643

632-
# Wrap it using MemberFunction, so we don't have to pass the this
633-
# pointer anymore
634-
return MemberFunction(self, return_type, func, ptr)
644+
# Set the MemberFunction as an attribute to the instance.
645+
setattr(obj, fget_self.name, func)
635646

636-
return property(fget, None, None, doc)
647+
return func
648+
649+
return fget()
637650

638651
def function(
639652
self, identifier, args=(), return_type=DataType.VOID,
@@ -646,34 +659,48 @@ def function(
646659
if return_type not in DataType.values:
647660
return_type = self.create_converter(return_type)
648661

662+
# Store the function cache
663+
func = None
664+
649665
class fget(object):
666+
def __set_name__(fget_self, owner, name):
667+
fget_self.name = name
668+
650669
def __get__(fget_self, obj, cls=None):
670+
nonlocal func
651671
if cls is None:
652672
if obj is None:
653673
return fget_self
654674
else:
655675
cls = obj.__class__
656676

657-
if cls._binary is None:
658-
raise ValueError('_binary was not specified.')
677+
if func is None:
678+
if cls._binary is None:
679+
raise ValueError('_binary was not specified.')
659680

660-
# Create a binary object
661-
binary = find_binary(cls._binary, cls._srv_check)
681+
# Create a binary object
682+
binary = find_binary(cls._binary, cls._srv_check)
662683

663-
# Create the function object
664-
func = binary[identifier].make_function(
665-
convention,
666-
args,
667-
return_type
668-
)
684+
# Create the function object and cache it
685+
func = binary[identifier].make_function(
686+
convention,
687+
args,
688+
return_type
689+
)
690+
func.__doc__ = doc
669691

670692
# Called with a this pointer?
671693
if obj is not None:
672-
# Wrap the function using MemberFunction, so we don't have
673-
# to pass the this pointer anymore
674-
func = MemberFunction(self, return_type, func, obj)
694+
# Wrap the function using MemberFunction,
695+
# so we don't have to pass the this pointer anymore
696+
m_func = MemberFunction(self, return_type, func, obj)
697+
m_func.__doc__ = doc
698+
699+
# Set the MemberFunction as an attribute to the instance.
700+
setattr(obj, fget_self.name, m_func)
701+
702+
return m_func
675703

676-
func.__doc__ = doc
677704
return func
678705

679706
return fget()

0 commit comments

Comments
 (0)