mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Experimental undo and redo Python prototype (#1539)
* Experimental undo and redo Python prototype * Simplify history, use transaction jargon, use walk for more robust serialisation * Black file, set history size, add file reference to entity_instance constructor * Ensure that files are always passed when entities are wrapped * Add support for undo/redo of all project module operations * Minor fix * Blender to IFC mappings are now managed by Blender RNA, so they don't break on undo operations. See #1475. * Implement undo for all attribute operations. See #1475. * Update documentation for installation of add-on * Revert Blender RNA approach for Blender-IFC mappings, because it didn't scale, but still fix the undo/redo object memory corruption with new "reload_linked_elements" method.
This commit is contained in:
@@ -48,20 +48,21 @@ class entity_instance(object):
|
||||
>>> #423=IfcProductDefinitionShape($,$,(#409,#421))
|
||||
"""
|
||||
|
||||
def __init__(self, e):
|
||||
def __init__(self, e, file):
|
||||
if isinstance(e, tuple):
|
||||
e = ifcopenshell_wrapper.new_IfcBaseClass(*e)
|
||||
super(entity_instance, self).__setattr__("wrapped_data", e)
|
||||
self.wrapped_data.file = file
|
||||
|
||||
def __getattr__(self, name):
|
||||
INVALID, FORWARD, INVERSE = range(3)
|
||||
attr_cat = self.wrapped_data.get_attribute_category(name)
|
||||
if attr_cat == FORWARD:
|
||||
return entity_instance.wrap_value(
|
||||
self.wrapped_data.get_argument(self.wrapped_data.get_argument_index(name))
|
||||
self.wrapped_data.get_argument(self.wrapped_data.get_argument_index(name)), self.wrapped_data.file
|
||||
)
|
||||
elif attr_cat == INVERSE:
|
||||
return entity_instance.wrap_value(self.wrapped_data.get_inverse(name))
|
||||
return entity_instance.wrap_value(self.wrapped_data.get_inverse(name), self.wrapped_data.file)
|
||||
else:
|
||||
raise AttributeError(
|
||||
"entity instance of type '%s' has no attribute '%s'" % (self.wrapped_data.is_a(), name)
|
||||
@@ -77,9 +78,9 @@ class entity_instance(object):
|
||||
return value
|
||||
|
||||
@staticmethod
|
||||
def wrap_value(v):
|
||||
def wrap_value(v, file):
|
||||
def wrap(e):
|
||||
return entity_instance(e)
|
||||
return entity_instance(e, file)
|
||||
|
||||
def is_instance(e):
|
||||
return isinstance(e, ifcopenshell_wrapper.entity_instance)
|
||||
@@ -116,12 +117,15 @@ class entity_instance(object):
|
||||
return self.wrapped_data.get_argument_name(attr_idx)
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
self[self.wrapped_data.get_argument_index(key)] = value
|
||||
index = self.wrapped_data.get_argument_index(key)
|
||||
if self.wrapped_data.file.transaction:
|
||||
self.wrapped_data.file.transaction.store_edit(self, index, value)
|
||||
self[index] = value
|
||||
|
||||
def __getitem__(self, key):
|
||||
if key < 0 or key >= len(self):
|
||||
raise IndexError("Attribute index {} out of range for instance of type {}".format(key, self.is_a()))
|
||||
return entity_instance.wrap_value(self.wrapped_data.get_argument(key))
|
||||
return entity_instance.wrap_value(self.wrapped_data.get_argument(key), self.wrapped_data.file)
|
||||
|
||||
def __setitem__(self, idx, value):
|
||||
attr_type = real_attr_type = self.attribute_type(idx).title().replace(" ", "")
|
||||
@@ -271,7 +275,7 @@ class entity_instance(object):
|
||||
return return_type(_())
|
||||
|
||||
__dict__ = property(get_info)
|
||||
|
||||
|
||||
def get_info_2(self, include_identifier=True, recursive=False, return_type=dict, ignore=()):
|
||||
assert include_identifier
|
||||
assert recursive
|
||||
|
||||
Reference in New Issue
Block a user